From: ehofman Date: Sun, 31 Jul 2005 07:59:08 +0000 (+0000) Subject: Harald JOHNSEN: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=32e2cd9f06d4b11eca868d3e26776dfba0092c10;p=simgear.git Harald JOHNSEN: This is the low level shader class for Simgear. It's the code from Roman Grigoriev with a few adaptations. --- diff --git a/simgear/screen/Makefile.am b/simgear/screen/Makefile.am index aaa007a3..155d1fe4 100644 --- a/simgear/screen/Makefile.am +++ b/simgear/screen/Makefile.am @@ -21,6 +21,7 @@ include_HEADERS = \ screen-dump.hxx \ extensions.hxx \ RenderTexture.h \ + shader.h \ tr.h libsgscreen_a_SOURCES = \ @@ -31,6 +32,7 @@ libsgscreen_a_SOURCES = \ tr.cxx \ extensions.cxx \ RenderTexture.cpp \ + shader.cpp \ win32-printer.h INCLUDES = -I$(top_srcdir) -DGLX_GLXEXT_PROTOTYPES diff --git a/simgear/screen/extensions.hxx b/simgear/screen/extensions.hxx index 1c3afd60..cf633c11 100644 --- a/simgear/screen/extensions.hxx +++ b/simgear/screen/extensions.hxx @@ -208,6 +208,7 @@ typedef void (APIENTRY * glClientActiveTextureProc)(GLenum texture); #define GL_RGB_SCALE_ARB 0x8573 #define GL_ADD_SIGNED_ARB 0x8574 #define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 #define GL_CONSTANT_ARB 0x8576 #define GL_PRIMARY_COLOR_ARB 0x8577 #define GL_PREVIOUS_ARB 0x8578 @@ -563,6 +564,313 @@ typedef void (*glXQueryDrawableProc) (Display *, GLXDrawable, int, unsigned int #define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F #endif +/* + * ARB_vertex_program + */ +#ifndef GL_ARB_vertex_program +#define GL_ARB_vertex_program 1 +#define GL_COLOR_SUM_ARB 0x8458 +#define GL_VERTEX_PROGRAM_ARB 0x8620 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 +#define GL_PROGRAM_LENGTH_ARB 0x8627 +#define GL_PROGRAM_STRING_ARB 0x8628 +#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E +#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F +#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 +#define GL_CURRENT_MATRIX_ARB 0x8641 +#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 +#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B +#define GL_PROGRAM_BINDING_ARB 0x8677 +#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A +#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +#define GL_PROGRAM_FORMAT_ARB 0x8876 +#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 +#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 +#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 +#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 +#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 +#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 +#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 +#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 +#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 +#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 +#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA +#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB +#define GL_PROGRAM_ATTRIBS_ARB 0x88AC +#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD +#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE +#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF +#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 +#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 +#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 +#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 +#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 +#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 +#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 +#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 +#define GL_MATRIX0_ARB 0x88C0 +#define GL_MATRIX1_ARB 0x88C1 +#define GL_MATRIX2_ARB 0x88C2 +#define GL_MATRIX3_ARB 0x88C3 +#define GL_MATRIX4_ARB 0x88C4 +#define GL_MATRIX5_ARB 0x88C5 +#define GL_MATRIX6_ARB 0x88C6 +#define GL_MATRIX7_ARB 0x88C7 +#define GL_MATRIX8_ARB 0x88C8 +#define GL_MATRIX9_ARB 0x88C9 +#define GL_MATRIX10_ARB 0x88CA +#define GL_MATRIX11_ARB 0x88CB +#define GL_MATRIX12_ARB 0x88CC +#define GL_MATRIX13_ARB 0x88CD +#define GL_MATRIX14_ARB 0x88CE +#define GL_MATRIX15_ARB 0x88CF +#define GL_MATRIX16_ARB 0x88D0 +#define GL_MATRIX17_ARB 0x88D1 +#define GL_MATRIX18_ARB 0x88D2 +#define GL_MATRIX19_ARB 0x88D3 +#define GL_MATRIX20_ARB 0x88D4 +#define GL_MATRIX21_ARB 0x88D5 +#define GL_MATRIX22_ARB 0x88D6 +#define GL_MATRIX23_ARB 0x88D7 +#define GL_MATRIX24_ARB 0x88D8 +#define GL_MATRIX25_ARB 0x88D9 +#define GL_MATRIX26_ARB 0x88DA +#define GL_MATRIX27_ARB 0x88DB +#define GL_MATRIX28_ARB 0x88DC +#define GL_MATRIX29_ARB 0x88DD +#define GL_MATRIX30_ARB 0x88DE +#define GL_MATRIX31_ARB 0x88DF +#endif + +/* + * ARB_fragment_program + */ +#ifndef GL_ARB_fragment_program +#define GL_ARB_fragment_program 1 +#define GL_FRAGMENT_PROGRAM_ARB 0x8804 +#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 +#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 +#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 +#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 +#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 +#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A +#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B +#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C +#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D +#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E +#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F +#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 +#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 +#endif + +typedef void (APIENTRY * glVertexAttrib1dProc) (GLuint index, GLdouble x); +typedef void (APIENTRY * glVertexAttrib1dvProc) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * glVertexAttrib1fProc) (GLuint index, GLfloat x); +typedef void (APIENTRY * glVertexAttrib1fvProc) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * glVertexAttrib1sProc) (GLuint index, GLshort x); +typedef void (APIENTRY * glVertexAttrib1svProc) (GLuint index, const GLshort *v); +typedef void (APIENTRY * glVertexAttrib2dProc) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRY * glVertexAttrib2dvProc) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * glVertexAttrib2fProc) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRY * glVertexAttrib2fvProc) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * glVertexAttrib2sProc) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRY * glVertexAttrib2svProc) (GLuint index, const GLshort *v); +typedef void (APIENTRY * glVertexAttrib3dProc) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY * glVertexAttrib3dvProc) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * glVertexAttrib3fProc) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * glVertexAttrib3fvProc) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * glVertexAttrib3sProc) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRY * glVertexAttrib3svProc) (GLuint index, const GLshort *v); +typedef void (APIENTRY * glVertexAttrib4NbvProc) (GLuint index, const GLbyte *v); +typedef void (APIENTRY * glVertexAttrib4NivProc) (GLuint index, const GLint *v); +typedef void (APIENTRY * glVertexAttrib4NsvProc) (GLuint index, const GLshort *v); +typedef void (APIENTRY * glVertexAttrib4NubProc) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRY * glVertexAttrib4NubvProc) (GLuint index, const GLubyte *v); +typedef void (APIENTRY * glVertexAttrib4NuivProc) (GLuint index, const GLuint *v); +typedef void (APIENTRY * glVertexAttrib4NusvProc) (GLuint index, const GLushort *v); +typedef void (APIENTRY * glVertexAttrib4bvProc) (GLuint index, const GLbyte *v); +typedef void (APIENTRY * glVertexAttrib4dProc) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * glVertexAttrib4dvProc) (GLuint index, const GLdouble *v); +typedef void (APIENTRY * glVertexAttrib4fProc) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * glVertexAttrib4fvProc) (GLuint index, const GLfloat *v); +typedef void (APIENTRY * glVertexAttrib4ivProc) (GLuint index, const GLint *v); +typedef void (APIENTRY * glVertexAttrib4sProc) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRY * glVertexAttrib4svProc) (GLuint index, const GLshort *v); +typedef void (APIENTRY * glVertexAttrib4ubvProc) (GLuint index, const GLubyte *v); +typedef void (APIENTRY * glVertexAttrib4uivProc) (GLuint index, const GLuint *v); +typedef void (APIENTRY * glVertexAttrib4usvProc) (GLuint index, const GLushort *v); +typedef void (APIENTRY * glVertexAttribPointerProc) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRY * glEnableVertexAttribArrayProc) (GLuint index); +typedef void (APIENTRY * glDisableVertexAttribArrayProc) (GLuint index); +typedef void (APIENTRY * glProgramStringProc) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); +typedef void (APIENTRY * glBindProgramProc) (GLenum target, GLuint program); +typedef void (APIENTRY * glDeleteProgramsProc) (GLsizei n, const GLuint *programs); +typedef void (APIENTRY * glGenProgramsProc) (GLsizei n, GLuint *programs); +typedef void (APIENTRY * glProgramEnvParameter4dProc) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * glProgramEnvParameter4dvProc) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRY * glProgramEnvParameter4fProc) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * glProgramEnvParameter4fvProc) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRY * glProgramLocalParameter4dProc) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * glProgramLocalParameter4dvProc) (GLenum target, GLuint index, const GLdouble *params); +typedef void (APIENTRY * glProgramLocalParameter4fProc) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * glProgramLocalParameter4fvProc) (GLenum target, GLuint index, const GLfloat *params); +typedef void (APIENTRY * glGetProgramEnvParameterdvProc) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRY * glGetProgramEnvParameterfvProc) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRY * glGetProgramLocalParameterdvProc) (GLenum target, GLuint index, GLdouble *params); +typedef void (APIENTRY * glGetProgramLocalParameterfvProc) (GLenum target, GLuint index, GLfloat *params); +typedef void (APIENTRY * glGetProgramivProc) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * glGetProgramStringProc) (GLenum target, GLenum pname, GLvoid *string); +typedef void (APIENTRY * glGetVertexAttribdvProc) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRY * glGetVertexAttribfvProc) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRY * glGetVertexAttribivProc) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRY * glGetVertexAttribPointervProc) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRY * glIsProgramProc) (GLuint program); + +/* + * ARB_shader_objects + */ +#ifndef GL_ARB_shader_objects +#define GL_ARB_shader_objects 1 +/* GL types for handling shader object handles and program/shader text */ +typedef char GLcharARB; /* native character */ +typedef unsigned int GLhandleARB; /* shader object handle */ + +#define GL_PROGRAM_OBJECT_ARB 0x8B40 +#define GL_SHADER_OBJECT_ARB 0x8B48 +#define GL_OBJECT_TYPE_ARB 0x8B4E +#define GL_OBJECT_SUBTYPE_ARB 0x8B4F +#define GL_FLOAT_VEC2_ARB 0x8B50 +#define GL_FLOAT_VEC3_ARB 0x8B51 +#define GL_FLOAT_VEC4_ARB 0x8B52 +#define GL_INT_VEC2_ARB 0x8B53 +#define GL_INT_VEC3_ARB 0x8B54 +#define GL_INT_VEC4_ARB 0x8B55 +#define GL_BOOL_ARB 0x8B56 +#define GL_BOOL_VEC2_ARB 0x8B57 +#define GL_BOOL_VEC3_ARB 0x8B58 +#define GL_BOOL_VEC4_ARB 0x8B59 +#define GL_FLOAT_MAT2_ARB 0x8B5A +#define GL_FLOAT_MAT3_ARB 0x8B5B +#define GL_FLOAT_MAT4_ARB 0x8B5C +#define GL_SAMPLER_1D_ARB 0x8B5D +#define GL_SAMPLER_2D_ARB 0x8B5E +#define GL_SAMPLER_3D_ARB 0x8B5F +#define GL_SAMPLER_CUBE_ARB 0x8B60 +#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 +#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 +#define GL_SAMPLER_2D_RECT_ARB 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 +#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 +#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 +#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 +#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 +#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 +#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 +#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 +#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 +#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 +#endif + +typedef void (APIENTRY * glDeleteObjectProc) (GLhandleARB obj); +typedef GLhandleARB (APIENTRY * glGetHandleProc) (GLenum pname); +typedef void (APIENTRY * glDetachObjectProc) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef GLhandleARB (APIENTRY * glCreateShaderObjectProc) (GLenum shaderType); +typedef void (APIENTRY * glShaderSourceProc) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); +typedef void (APIENTRY * glCompileShaderProc) (GLhandleARB shaderObj); +typedef GLhandleARB (APIENTRY * glCreateProgramObjectProc) (void); +typedef void (APIENTRY * glAttachObjectProc) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (APIENTRY * glLinkProgramProc) (GLhandleARB programObj); +typedef void (APIENTRY * glUseProgramObjectProc) (GLhandleARB programObj); +typedef void (APIENTRY * glValidateProgramProc) (GLhandleARB programObj); +typedef void (APIENTRY * glUniform1fProc) (GLint location, GLfloat v0); +typedef void (APIENTRY * glUniform2fProc) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRY * glUniform3fProc) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRY * glUniform4fProc) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRY * glUniform1iProc) (GLint location, GLint v0); +typedef void (APIENTRY * glUniform2iProc) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRY * glUniform3iProc) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRY * glUniform4iProc) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRY * glUniform1fvProc) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRY * glUniform2fvProc) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRY * glUniform3fvProc) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRY * glUniform4fvProc) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRY * glUniform1ivProc) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRY * glUniform2ivProc) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRY * glUniform3ivProc) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRY * glUniform4ivProc) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRY * glUniformMatrix2fvProc) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRY * glUniformMatrix3fvProc) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRY * glUniformMatrix4fvProc) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRY * glGetObjectParameterfvProc) (GLhandleARB obj, GLenum pname, GLfloat *params); +typedef void (APIENTRY * glGetObjectParameterivProc) (GLhandleARB obj, GLenum pname, GLint *params); +typedef void (APIENTRY * glGetInfoLogProc) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); +typedef void (APIENTRY * glGetAttachedObjectsProc) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); +typedef GLint (APIENTRY * glGetUniformLocationProc) (GLhandleARB programObj, const GLcharARB *name); +typedef void (APIENTRY * glGetActiveUniformProc) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef void (APIENTRY * glGetUniformfvProc) (GLhandleARB programObj, GLint location, GLfloat *params); +typedef void (APIENTRY * glGetUniformivProc) (GLhandleARB programObj, GLint location, GLint *params); +typedef void (APIENTRY * glGetShaderSourceProc) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); + +/* + * ARB_vertex_shader + */ +#ifndef GL_ARB_vertex_shader +#define GL_ARB_vertex_shader 1 +#define GL_VERTEX_SHADER_ARB 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A +#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D +#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 +#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A +#endif + +typedef void (APIENTRY * glBindAttribLocationProc) (GLhandleARB programObj, GLuint index, const GLcharARB *name); +typedef void (APIENTRY * glGetActiveAttribProc) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); +typedef GLint (APIENTRY * glGetAttribLocationProc) (GLhandleARB programObj, const GLcharARB *name); + +/* + * ARB_fragment_shader + */ +#ifndef GL_ARB_fragment_shader +#define GL_ARB_fragment_shader1 +#define GL_FRAGMENT_SHADER_ARB 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B +#endif + +/* + * NV_fragment_program + */ +#ifndef GL_NV_fragment_program +#define GL_NV_fragment_program 1 +#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 +#define GL_FRAGMENT_PROGRAM_NV 0x8870 +#define GL_MAX_TEXTURE_COORDS_NV 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 +#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 +#define GL_PROGRAM_ERROR_STRING_NV 0x8874 +#endif +#ifndef GL_NV_vertex_program +#define GL_NV_vertex_program 1 +#define GL_VERTEX_PROGRAM_NV 0x8620 +#define GL_PROGRAM_ERROR_POSITION_NV 0x864B +#endif + +typedef void (APIENTRY * glBindProgramNVProc) (GLenum target, GLuint id); +typedef void (APIENTRY * glDeleteProgramsNVProc) (GLsizei n, const GLuint *programs); +typedef void (APIENTRY * glGenProgramsNVProc) (GLsizei n, GLuint *programs); +typedef void (APIENTRY * glLoadProgramNVProc) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); +typedef void (APIENTRY * glProgramParameter4fvNVProc) (GLenum target, GLuint index, const GLfloat *v); #if defined(__cplusplus) } diff --git a/simgear/screen/shader.cpp b/simgear/screen/shader.cpp new file mode 100644 index 00000000..6276051a --- /dev/null +++ b/simgear/screen/shader.cpp @@ -0,0 +1,704 @@ +/* Shader + * + * Copyright (C) 2003-2005, Alexander Zaprjagaev + * Roman Grigoriev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include +#include "shader.h" +#include +#include + + +glVertexAttrib1dProc glVertexAttrib1dPtr = NULL; +glVertexAttrib1dvProc glVertexAttrib1dvPtr = NULL; +glVertexAttrib1fProc glVertexAttrib1fPtr = NULL; +glVertexAttrib1fvProc glVertexAttrib1fvPtr = NULL; +glVertexAttrib1sProc glVertexAttrib1sPtr = NULL; +glVertexAttrib1svProc glVertexAttrib1svPtr = NULL; +glVertexAttrib2dProc glVertexAttrib2dPtr = NULL; +glVertexAttrib2dvProc glVertexAttrib2dvPtr = NULL; +glVertexAttrib2fProc glVertexAttrib2fPtr = NULL; +glVertexAttrib2fvProc glVertexAttrib2fvPtr = NULL; +glVertexAttrib2sProc glVertexAttrib2sPtr = NULL; +glVertexAttrib2svProc glVertexAttrib2svPtr = NULL; +glVertexAttrib3dProc glVertexAttrib3dPtr = NULL; +glVertexAttrib3dvProc glVertexAttrib3dvPtr = NULL; +glVertexAttrib3fProc glVertexAttrib3fPtr = NULL; +glVertexAttrib3fvProc glVertexAttrib3fvPtr = NULL; +glVertexAttrib3sProc glVertexAttrib3sPtr = NULL; +glVertexAttrib3svProc glVertexAttrib3svPtr = NULL; +glVertexAttrib4NbvProc glVertexAttrib4NbvPtr = NULL; +glVertexAttrib4NivProc glVertexAttrib4NivPtr = NULL; +glVertexAttrib4NsvProc glVertexAttrib4NsvPtr = NULL; +glVertexAttrib4NubProc glVertexAttrib4NubPtr = NULL; +glVertexAttrib4NubvProc glVertexAttrib4NubvPtr = NULL; +glVertexAttrib4NuivProc glVertexAttrib4NuivPtr = NULL; +glVertexAttrib4NusvProc glVertexAttrib4NusvPtr = NULL; +glVertexAttrib4bvProc glVertexAttrib4bvPtr = NULL; +glVertexAttrib4dProc glVertexAttrib4dPtr = NULL; +glVertexAttrib4dvProc glVertexAttrib4dvPtr = NULL; +glVertexAttrib4fProc glVertexAttrib4fPtr = NULL; +glVertexAttrib4fvProc glVertexAttrib4fvPtr = NULL; +glVertexAttrib4ivProc glVertexAttrib4ivPtr = NULL; +glVertexAttrib4sProc glVertexAttrib4sPtr = NULL; +glVertexAttrib4svProc glVertexAttrib4svPtr = NULL; +glVertexAttrib4ubvProc glVertexAttrib4ubvPtr = NULL; +glVertexAttrib4uivProc glVertexAttrib4uivPtr = NULL; +glVertexAttrib4usvProc glVertexAttrib4usvPtr = NULL; +glVertexAttribPointerProc glVertexAttribPointerPtr = NULL; +glEnableVertexAttribArrayProc glEnableVertexAttribArrayPtr = NULL; +glDisableVertexAttribArrayProc glDisableVertexAttribArrayPtr = NULL; +glProgramStringProc glProgramStringPtr = NULL; +glBindProgramProc glBindProgramPtr = NULL; +glDeleteProgramsProc glDeleteProgramsPtr = NULL; +glGenProgramsProc glGenProgramsPtr = NULL; +glProgramEnvParameter4dProc glProgramEnvParameter4dPtr = NULL; +glProgramEnvParameter4dvProc glProgramEnvParameter4dvPtr = NULL; +glProgramEnvParameter4fProc glProgramEnvParameter4fPtr = NULL; +glProgramEnvParameter4fvProc glProgramEnvParameter4fvPtr = NULL; +glProgramLocalParameter4dProc glProgramLocalParameter4dPtr = NULL; +glProgramLocalParameter4dvProc glProgramLocalParameter4dvPtr = NULL; +glProgramLocalParameter4fProc glProgramLocalParameter4fPtr = NULL; +glProgramLocalParameter4fvProc glProgramLocalParameter4fvPtr = NULL; +glGetProgramEnvParameterdvProc glGetProgramEnvParameterdvPtr = NULL; +glGetProgramEnvParameterfvProc glGetProgramEnvParameterfvPtr = NULL; +glGetProgramLocalParameterdvProc glGetProgramLocalParameterdvPtr = NULL; +glGetProgramLocalParameterfvProc glGetProgramLocalParameterfvPtr = NULL; +glGetProgramivProc glGetProgramivPtr = NULL; +glGetProgramStringProc glGetProgramStringPtr = NULL; +glGetVertexAttribdvProc glGetVertexAttribdvPtr = NULL; +glGetVertexAttribfvProc glGetVertexAttribfvPtr = NULL; +glGetVertexAttribivProc glGetVertexAttribivPtr = NULL; +glGetVertexAttribPointervProc glGetVertexAttribPointervPtr = NULL; +glIsProgramProc glIsProgramPtr = NULL; + +glDeleteObjectProc glDeleteObjectPtr = NULL; +glGetHandleProc glGetHandlePtr = NULL; +glDetachObjectProc glDetachObjectPtr = NULL; +glCreateShaderObjectProc glCreateShaderObjectPtr = NULL; +glShaderSourceProc glShaderSourcePtr = NULL; +glCompileShaderProc glCompileShaderPtr = NULL; +glCreateProgramObjectProc glCreateProgramObjectPtr = NULL; +glAttachObjectProc glAttachObjectPtr = NULL; +glLinkProgramProc glLinkProgramPtr = NULL; +glUseProgramObjectProc glUseProgramObjectPtr = NULL; +glValidateProgramProc glValidateProgramPtr = NULL; +glUniform1fProc glUniform1fPtr = NULL; +glUniform2fProc glUniform2fPtr = NULL; +glUniform3fProc glUniform3fPtr = NULL; +glUniform4fProc glUniform4fPtr = NULL; +glUniform1iProc glUniform1iPtr = NULL; +glUniform2iProc glUniform2iPtr = NULL; +glUniform3iProc glUniform3iPtr = NULL; +glUniform4iProc glUniform4iPtr = NULL; +glUniform1fvProc glUniform1fvPtr = NULL; +glUniform2fvProc glUniform2fvPtr = NULL; +glUniform3fvProc glUniform3fvPtr = NULL; +glUniform4fvProc glUniform4fvPtr = NULL; +glUniform1ivProc glUniform1ivPtr = NULL; +glUniform2ivProc glUniform2ivPtr = NULL; +glUniform3ivProc glUniform3ivPtr = NULL; +glUniform4ivProc glUniform4ivPtr = NULL; +glUniformMatrix2fvProc glUniformMatrix2fvPtr = NULL; +glUniformMatrix3fvProc glUniformMatrix3fvPtr = NULL; +glUniformMatrix4fvProc glUniformMatrix4fvPtr = NULL; +glGetObjectParameterfvProc glGetObjectParameterfvPtr = NULL; +glGetObjectParameterivProc glGetObjectParameterivPtr = NULL; +glGetInfoLogProc glGetInfoLogPtr = NULL; +glGetAttachedObjectsProc glGetAttachedObjectsPtr = NULL; +glGetUniformLocationProc glGetUniformLocationPtr = NULL; +glGetActiveUniformProc glGetActiveUniformPtr = NULL; +glGetUniformfvProc glGetUniformfvPtr = NULL; +glGetUniformivProc glGetUniformivPtr = NULL; +glGetShaderSourceProc glGetShaderSourcePtr = NULL; + +glBindAttribLocationProc glBindAttribLocationPtr = NULL; +glGetActiveAttribProc glGetActiveAttribPtr = NULL; +glGetAttribLocationProc glGetAttribLocationPtr = NULL; + +glBindProgramNVProc glBindProgramNVPtr = NULL; +glDeleteProgramsNVProc glDeleteProgramsNVPtr = NULL; +glGenProgramsNVProc glGenProgramsNVPtr = NULL; +glLoadProgramNVProc glLoadProgramNVPtr = NULL; +glProgramParameter4fvNVProc glProgramParameter4fvNVPtr = NULL; + +bool Shader::VP_supported = false; +bool Shader::FP_supported = false; +bool Shader::GLSL_supported = false; +bool Shader::NVFP_supported = false; +GLint Shader::nb_texture_unit = 0; + +Shader::Shader(const char *name,const char *vertex,const char *fragment) { + + program = 0; + vertex_target = 0; + vertex_id = 0; + fragment_target = 0; + fragment_id = 0; + + char *data; + FILE *file = fopen(name,"rb"); + if(!file) { + SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): can't open '" << name << "' file\n"); + return; + } + + fseek(file,0,SEEK_END); + int size = ftell(file); + data = new char[size + 1]; + data[size] = '\0'; + fseek(file,0,SEEK_SET); + fread(data,1,size,file); + fclose(file); + + // skip comments + char *s = data; + char *d = data; + while(*s) { + if(*s == '/' && *(s + 1) == '/') { + while(*s && *s != '\n') s++; + while(*s && *s == '\n') s++; + *d++ = '\n'; + } + else if(*s == '/' && *(s + 1) == '*') { + while(*s && (*s != '*' || *(s + 1) != '/')) s++; + s += 2; + while(*s && *s == '\n') s++; + *d++ = '\n'; + } + else *d++ = *s++; + } + *d = '\0'; + + // find shaders + char *vertex_src = NULL; + char *fragment_src = NULL; + s = data; + while(*s) { + if(*s == '<') { + char *name = s; + while(*s) { + if(strchr("> \t\n\r",*s)) break; + s++; + } + if(*s == '>') { // it`s shader + *name++ = '\0'; + *s++ = '\0'; + while(*s && strchr(" \t\n\r",*s)) s++; + if(vertex == NULL && !strcmp(name,"vertex")) vertex_src = s; + if(vertex && !strcmp(name,vertex)) vertex_src = s; + if(fragment == NULL && !strcmp(name,"fragment")) fragment_src = s; + if(fragment && !strcmp(name,fragment)) fragment_src = s; + } + } + s++; + } + + if(vertex_src) { + + // ARB vertex program + if(VP_supported && !strncmp(vertex_src,"!!ARBvp1.0",10)) { + vertex_target = GL_VERTEX_PROGRAM_ARB; + glGenProgramsPtr(1,&vertex_id); + glBindProgramPtr(GL_VERTEX_PROGRAM_ARB,vertex_id); + glProgramStringPtr(GL_VERTEX_PROGRAM_ARB,GL_PROGRAM_FORMAT_ASCII_ARB,(GLsizei)strlen(vertex_src),vertex_src); + int pos = -1; + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB,&pos); + if(pos != -1) { + SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): vertex program error in " << name << " file\n" << get_error(vertex_src,pos)); + return; + } + char *var = strstr(vertex_src, "#var "); + while( var ) { + char *eol = strchr( var + 1, '#'); + char *c2, *c3, *c4; + c2 = strchr( var + 6, ' '); + if( c2 ) { + c3 = strchr( c2 + 1, ':'); + if( c3 ) { + c4 = strchr( c3 + 1, ':'); + if( c4 ) + c4 = strchr( c4 + 1, '['); + if( c4 && c4 < eol) { + char type[10], name[30]; + strncpy( type, var + 5, c2-var-5 ); + type[c2-var-5] = 0; + strncpy( name, c2 + 1, c3-c2-2 ); + name[c3-c2-2] = 0; + struct Parameter p; + p.location = atoi( c4 + 1); + p.length = 4; + if( ! strcmp(type, "float3") ) + p.length = 3; + else if( ! strcmp(type, "float") ) + p.length = 1; + arb_parameters[ name ] = p; + } + } + } + var = strstr(var + 1, "#var "); + } + } + // ARB vertex shader + else { + + program = glCreateProgramObjectPtr(); + + GLint length = (GLint)strlen(vertex_src); + GLhandleARB vertex = glCreateShaderObjectPtr(GL_VERTEX_SHADER_ARB); + glShaderSourcePtr(vertex,1,(const GLcharARB**)&vertex_src,&length); + glCompileShaderPtr(vertex); + glAttachObjectPtr(program,vertex); + glDeleteObjectPtr(vertex); + + glBindAttribLocationPtr(program,0,"s_attribute_0"); + glBindAttribLocationPtr(program,1,"s_attribute_1"); + glBindAttribLocationPtr(program,2,"s_attribute_2"); + glBindAttribLocationPtr(program,3,"s_attribute_3"); + glBindAttribLocationPtr(program,4,"s_attribute_4"); + glBindAttribLocationPtr(program,5,"s_attribute_5"); + glBindAttribLocationPtr(program,6,"s_attribute_6"); + + glBindAttribLocationPtr(program,0,"s_xyz"); + glBindAttribLocationPtr(program,1,"s_normal"); + glBindAttribLocationPtr(program,2,"s_tangent"); + glBindAttribLocationPtr(program,3,"s_binormal"); + glBindAttribLocationPtr(program,4,"s_texcoord"); + } + } + + if(fragment_src) { + + // ARB fragment program + if(FP_supported && !strncmp(fragment_src,"!!ARBfp1.0",10)) { + fragment_target = GL_FRAGMENT_PROGRAM_ARB; + glGenProgramsPtr(1,&fragment_id); + glBindProgramPtr(GL_FRAGMENT_PROGRAM_ARB,fragment_id); + glProgramStringPtr(GL_FRAGMENT_PROGRAM_ARB,GL_PROGRAM_FORMAT_ASCII_ARB,(GLsizei)strlen(fragment_src),fragment_src); + int pos = -1; + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB,&pos); + if(pos != -1) { + SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): fragment program error in " << name << " file\n" << get_error(fragment_src,pos)); + return; + } + } + + // NV fragment program + else if(!strncmp(fragment_src,"!!FP1.0",7)) { + fragment_target = GL_FRAGMENT_PROGRAM_NV; + glGenProgramsNVPtr(1,&fragment_id); + glBindProgramNVPtr(GL_FRAGMENT_PROGRAM_NV,fragment_id); + glLoadProgramNVPtr(GL_FRAGMENT_PROGRAM_NV,fragment_id,(GLsizei)strlen(fragment_src),(GLubyte*)fragment_src); + int pos = -1; + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_NV,&pos); + if(pos != -1) { + SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): fragment program error in " << name << " file\n" << get_error(fragment_src,pos)); + return; + } + } + + // ARB fragment shader + else { + + if(!program) program = glCreateProgramObjectPtr(); + + GLint length = (GLint)strlen(fragment_src); + GLhandleARB fragment = glCreateShaderObjectPtr(GL_FRAGMENT_SHADER_ARB); + glShaderSourcePtr(fragment,1,(const GLcharARB**)&fragment_src,&length); + glCompileShaderPtr(fragment); + glAttachObjectPtr(program,fragment); + glDeleteObjectPtr(fragment); + } + } + + if(program) { + + glLinkProgramPtr(program); + GLint linked; + glGetObjectParameterivPtr(program,GL_OBJECT_LINK_STATUS_ARB,&linked); + if(!linked) { + SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): GLSL error in " << name << " file\n" << get_glsl_error()); + return; + } + + glUseProgramObjectPtr(program); + + for(int i = 0; i < 8; i++) { + char texture[32]; + sprintf(texture,"s_texture_%d",i); + GLint location = glGetUniformLocationPtr(program,texture); + if(location >= 0) glUniform1iPtr(location,i); + } + + glUseProgramObjectPtr(0); + + glValidateProgramPtr(program); + GLint validated; + glGetObjectParameterivPtr(program,GL_OBJECT_VALIDATE_STATUS_ARB,&validated); + if(!validated) { + SG_LOG(SG_GL, SG_ALERT, "Shader::Shader(): GLSL error in " << name << " file\n" << get_glsl_error()); + return; + } + } + + delete [] data; +} + +Shader::~Shader() { + if(program) glDeleteObjectPtr(program); + if(vertex_target == GL_VERTEX_PROGRAM_ARB) glDeleteProgramsPtr(1,&vertex_id); + if(fragment_target == GL_FRAGMENT_PROGRAM_ARB) glDeleteProgramsPtr(1,&fragment_id); + else if(fragment_target == GL_FRAGMENT_PROGRAM_NV) glDeleteProgramsNVPtr(1,&fragment_id); + parameters.clear(); +} + +/* + */ +const char *Shader::get_error(char *data,int pos) { + char *s = data; + while(*s && pos--) s++; + while(s >= data && *s != '\n') s--; + char *e = ++s; + while(*e != '\0' && *e != '\n') e++; + *e = '\0'; + return s; +} + +/* + */ + +const char *Shader::get_glsl_error() { + int length; + static char error[4096]; + glGetInfoLogPtr(program,sizeof(error),&length,error); + return error; +} + +/* + */ +void Shader::getParameter(const char *name,Parameter *parameter) { + if( program ) { + char buf[1024]; + strcpy(buf,name); + char *s = strchr(buf,':'); + if(s) { + *s++ = '\0'; + parameter->length = atoi(s); + } else { + parameter->length = 4; + } + parameter->location = glGetUniformLocationPtr(program,buf); + } else if( vertex_id ) { + arb_parameter_list::iterator iParam = arb_parameters.find(name); + if( iParam != arb_parameters.end() ) + parameter->location = iParam->second.location; + else + parameter->location = 90; + parameter->length = 4; + } +} + +/* + */ +void Shader::bindNames(const char *name,...) { + Parameter parameter; + getParameter(name,¶meter); + parameters.push_back(parameter); + va_list args; + va_start(args,name); + while(1) { + const char *name = va_arg(args,const char*); + if(name == NULL) break; + getParameter(name,¶meter); + parameters.push_back(parameter); + } + va_end(args); +} + +/*****************************************************************************/ +/* */ +/* enable/disable/bind */ +/* */ +/*****************************************************************************/ + +/* + */ +void Shader::enable() { + if(vertex_id) glEnable(vertex_target); + if(fragment_id) glEnable(fragment_target); +} + +/* + */ +void Shader::disable() { + if(program) glUseProgramObjectPtr(0); + if(vertex_id) glDisable(vertex_target); + if(fragment_id) glDisable(fragment_target); +} + +/* + */ +void Shader::bind() { + if(program) glUseProgramObjectPtr(program); + if(vertex_id) { + if(vertex_target == GL_VERTEX_PROGRAM_ARB) glBindProgramPtr(vertex_target,vertex_id); + } + if(fragment_id) { + if(fragment_target == GL_FRAGMENT_PROGRAM_ARB) glBindProgramPtr(fragment_target,fragment_id); + else if(fragment_target == GL_FRAGMENT_PROGRAM_NV) glBindProgramNVPtr(fragment_target,fragment_id); + } +} + +/* + */ +void Shader::bind(const float *v,...) { + if(fragment_id) { + if(fragment_target == GL_FRAGMENT_PROGRAM_ARB) glBindProgramPtr(fragment_target,fragment_id); + else if(fragment_target == GL_FRAGMENT_PROGRAM_NV) glBindProgramNVPtr(fragment_target,fragment_id); + } else { + if(program == 0) { + SG_LOG(SG_GL, SG_ALERT, "Shader::bind(): error GLSL shader isn't loaded\n"); + return; + } + glUseProgramObjectPtr(program); + } + const float *value = v; + va_list args; + va_start(args,value); + for(int i = 0; i < (int)parameters.size(); i++) { + if( vertex_target ) { + glProgramLocalParameter4fvPtr( vertex_target, parameters[i].location, value); + } else if( program ) { + if(parameters[i].length == 1) glUniform1fvPtr(parameters[i].location,1,value); + else if(parameters[i].length == 2) glUniform2fvPtr(parameters[i].location,1,value); + else if(parameters[i].length == 3) glUniform3fvPtr(parameters[i].location,1,value); + else if(parameters[i].length == 4) glUniform4fvPtr(parameters[i].location,1,value); + else if(parameters[i].length == 9) glUniformMatrix3fvPtr(parameters[i].location,1,false,value); + else if(parameters[i].length == 16) glUniformMatrix4fvPtr(parameters[i].location,1,false,value); + } + value = va_arg(args,const float*); + if(!value) break; + } + va_end(args); +} + +/*****************************************************************************/ +/* */ +/* set parameters */ +/* */ +/*****************************************************************************/ + +void Shader::setLocalParameter(int location,const float *value) { + if(vertex_target == 0) { + SG_LOG(SG_GL, SG_ALERT, "Shader::setLocalParameter(): error vertex program isn't loaded\n"); + return; + } + glProgramLocalParameter4fvPtr(vertex_target,location,value); +} + +void Shader::setEnvParameter(int location,const float *value) { + if(vertex_target == 0) { + SG_LOG(SG_GL, SG_ALERT, "Shader::setEnvParameter(): error vertex program isn't loaded\n"); + return; + } + glProgramEnvParameter4fvPtr(vertex_target,location,value); +} + +/* + */ +void Shader::setParameter(const char *name,const float *value) { + Parameter parameter; + getParameter(name,¶meter); + if( vertex_target ) { + glProgramLocalParameter4fvPtr( vertex_target, parameter.location, value); + return; + } + if(program == 0) { + SG_LOG(SG_GL, SG_ALERT, "Shader::setLocalParameter(): error GLSL shader isn't loaded\n"); + return; + } + if(parameter.length == 1) glUniform1fvPtr(parameter.location,1,value); + else if(parameter.length == 2) glUniform2fvPtr(parameter.location,1,value); + else if(parameter.length == 3) glUniform3fvPtr(parameter.location,1,value); + else if(parameter.length == 4) glUniform4fvPtr(parameter.location,1,value); + else if(parameter.length == 9) glUniformMatrix3fvPtr(parameter.location,1,false,value); + else if(parameter.length == 16) glUniformMatrix4fvPtr(parameter.location,1,false,value); +} + +/* + */ +void Shader::setParameters(const float *v,...) { + const float *value = v; + va_list args; + va_start(args,value); + for(int i = 0; i < (int)parameters.size(); i++) { + if( vertex_target ) { + glProgramLocalParameter4fvPtr( vertex_target, parameters[i].location, value); + } else if( program ) { + if(parameters[i].length == 1) glUniform1fvPtr(parameters[i].location,1,value); + else if(parameters[i].length == 2) glUniform2fvPtr(parameters[i].location,1,value); + else if(parameters[i].length == 3) glUniform3fvPtr(parameters[i].location,1,value); + else if(parameters[i].length == 4) glUniform4fvPtr(parameters[i].location,1,value); + else if(parameters[i].length == 9) glUniformMatrix3fvPtr(parameters[i].location,1,false,value); + else if(parameters[i].length == 16) glUniformMatrix4fvPtr(parameters[i].location,1,false,value); + } + value = va_arg(args,const float*); + if(!value) break; + } + va_end(args); +} + +#ifndef CONCAT +#define CONCAT(a,b) a##b +#endif +#define mystringify(a) CONCAT(ST,R)(a) +#define STR(x) #x +#define LOAD_EXT(fn) CONCAT(fn,Ptr) = (CONCAT(fn,Proc)) SGLookupFunction( mystringify(CONCAT(fn,ARB)) ) + +void Shader::Init(void) { + if( SGIsOpenGLExtensionSupported("GL_ARB_multitexture") ) + glGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &nb_texture_unit ); + VP_supported = SGIsOpenGLExtensionSupported("GL_ARB_vertex_program"); + FP_supported = SGIsOpenGLExtensionSupported("GL_ARB_fragment_program"); + // check that + GLSL_supported = SGIsOpenGLExtensionSupported("GL_ARB_shading_language_100") && + SGIsOpenGLExtensionSupported("GL_ARB_fragment_shader") && + SGIsOpenGLExtensionSupported("GL_ARB_vertex_shader") && + SGIsOpenGLExtensionSupported("GL_ARB_shader_objects"); + NVFP_supported = SGIsOpenGLExtensionSupported("GL_NV_fragment_program"); + + if( VP_supported || FP_supported ) { + /* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ + LOAD_EXT(glVertexAttrib1d); + LOAD_EXT( glVertexAttrib1dv ); + LOAD_EXT( glVertexAttrib1f ); + LOAD_EXT( glVertexAttrib1fv ); + LOAD_EXT( glVertexAttrib1s ); + LOAD_EXT( glVertexAttrib1sv ); + LOAD_EXT( glVertexAttrib2d ); + LOAD_EXT( glVertexAttrib2dv ); + LOAD_EXT( glVertexAttrib2f ); + LOAD_EXT( glVertexAttrib2fv ); + LOAD_EXT( glVertexAttrib2s ); + LOAD_EXT( glVertexAttrib2sv ); + LOAD_EXT( glVertexAttrib3d ); + LOAD_EXT( glVertexAttrib3dv ); + LOAD_EXT( glVertexAttrib3f ); + LOAD_EXT( glVertexAttrib3fv ); + LOAD_EXT( glVertexAttrib3s ); + LOAD_EXT( glVertexAttrib3sv ); + LOAD_EXT( glVertexAttrib4Nbv ); + LOAD_EXT( glVertexAttrib4Niv ); + LOAD_EXT( glVertexAttrib4Nsv ); + LOAD_EXT( glVertexAttrib4Nub ); + LOAD_EXT( glVertexAttrib4Nubv ); + LOAD_EXT( glVertexAttrib4Nuiv ); + LOAD_EXT( glVertexAttrib4Nusv ); + LOAD_EXT( glVertexAttrib4bv ); + LOAD_EXT( glVertexAttrib4d ); + LOAD_EXT( glVertexAttrib4dv ); + LOAD_EXT( glVertexAttrib4f ); + LOAD_EXT( glVertexAttrib4fv ); + LOAD_EXT( glVertexAttrib4iv ); + LOAD_EXT( glVertexAttrib4s ); + LOAD_EXT( glVertexAttrib4sv ); + LOAD_EXT( glVertexAttrib4ubv ); + LOAD_EXT( glVertexAttrib4uiv ); + LOAD_EXT( glVertexAttrib4usv ); + LOAD_EXT( glVertexAttribPointer ); + LOAD_EXT( glEnableVertexAttribArray ); + LOAD_EXT( glDisableVertexAttribArray ); + LOAD_EXT( glProgramString ); + LOAD_EXT( glBindProgram ); + LOAD_EXT( glDeletePrograms ); + LOAD_EXT( glGenPrograms ); + LOAD_EXT( glProgramEnvParameter4d ); + LOAD_EXT( glProgramEnvParameter4dv ); + LOAD_EXT( glProgramEnvParameter4f ); + LOAD_EXT( glProgramEnvParameter4fv ); + LOAD_EXT( glProgramLocalParameter4d ); + LOAD_EXT( glProgramLocalParameter4dv ); + LOAD_EXT( glProgramLocalParameter4f ); + LOAD_EXT( glProgramLocalParameter4fv ); + LOAD_EXT( glGetProgramEnvParameterdv ); + LOAD_EXT( glGetProgramEnvParameterfv ); + LOAD_EXT( glGetProgramLocalParameterdv ); + LOAD_EXT( glGetProgramLocalParameterfv ); + LOAD_EXT( glGetProgramiv ); + LOAD_EXT( glGetProgramString ); + LOAD_EXT( glGetVertexAttribdv ); + LOAD_EXT( glGetVertexAttribfv ); + LOAD_EXT( glGetVertexAttribiv ); + LOAD_EXT( glGetVertexAttribPointerv ); + LOAD_EXT( glIsProgram ); + } + if( GLSL_supported ) { + LOAD_EXT( glDeleteObject ); + LOAD_EXT( glGetHandle ); + LOAD_EXT( glDetachObject ); + LOAD_EXT( glCreateShaderObject ); + LOAD_EXT( glShaderSource ); + LOAD_EXT( glCompileShader ); + LOAD_EXT( glCreateProgramObject ); + LOAD_EXT( glAttachObject ); + LOAD_EXT( glLinkProgram ); + LOAD_EXT( glUseProgramObject ); + LOAD_EXT( glValidateProgram ); + LOAD_EXT( glUniform1f ); + LOAD_EXT( glUniform2f ); + LOAD_EXT( glUniform3f ); + LOAD_EXT( glUniform4f ); + LOAD_EXT( glUniform1i ); + LOAD_EXT( glUniform2i ); + LOAD_EXT( glUniform3i ); + LOAD_EXT( glUniform4i ); + LOAD_EXT( glUniform1fv ); + LOAD_EXT( glUniform2fv ); + LOAD_EXT( glUniform3fv ); + LOAD_EXT( glUniform4fv ); + LOAD_EXT( glUniform1iv ); + LOAD_EXT( glUniform2iv ); + LOAD_EXT( glUniform3iv ); + LOAD_EXT( glUniform4iv ); + LOAD_EXT( glUniformMatrix2fv ); + LOAD_EXT( glUniformMatrix3fv ); + LOAD_EXT( glUniformMatrix4fv ); + LOAD_EXT( glGetObjectParameterfv ); + LOAD_EXT( glGetObjectParameteriv ); + LOAD_EXT( glGetInfoLog ); + LOAD_EXT( glGetAttachedObjects ); + LOAD_EXT( glGetUniformLocation ); + LOAD_EXT( glGetActiveUniform ); + LOAD_EXT( glGetUniformfv ); + LOAD_EXT( glGetUniformiv ); + LOAD_EXT( glGetShaderSource ); + + LOAD_EXT( glBindAttribLocation ); + LOAD_EXT( glGetActiveAttrib ); + LOAD_EXT( glGetAttribLocation ); + + } + if( NVFP_supported ) { + glBindProgramNVPtr = (glBindProgramNVProc) SGLookupFunction( "glBindProgramNV" ); + glDeleteProgramsNVPtr = (glDeleteProgramsNVProc) SGLookupFunction( "glDeleteProgramsNV" ); + glGenProgramsNVPtr = (glGenProgramsNVProc) SGLookupFunction( "glGenProgramsNV" ); + glLoadProgramNVPtr = (glLoadProgramNVProc) SGLookupFunction( "glLoadProgramNV" ); + glProgramParameter4fvNVPtr = (glProgramParameter4fvNVProc) SGLookupFunction( "glProgramParameter4fvNV" ); + } +} diff --git a/simgear/screen/shader.h b/simgear/screen/shader.h new file mode 100644 index 00000000..55d804c8 --- /dev/null +++ b/simgear/screen/shader.h @@ -0,0 +1,90 @@ +/* Shader + * + * Copyright (C) 2003-2005, Alexander Zaprjagaev + * Roman Grigoriev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __SHADER_H__ +#define __SHADER_H__ + +#include +#include + +#include + +#include +#include STL_STRING + +SG_USING_STD(map); +SG_USING_STD(vector); +SG_USING_STD(string); + +class Shader { +public: + + Shader(const char *name,const char *vertex = NULL,const char *fragment = NULL); + ~Shader(); + + void bindNames(const char *name,...); + + void enable(); + void disable(); + void bind(); + void bind(const float *value,...); + + void setLocalParameter(int location,const float *value); + void setEnvParameter(int location,const float *value); + + void setParameter(const char *name,const float *value); + void setParameters(const float *value,...); + + static void Init(void); + inline static bool is_VP_supported(void) {return VP_supported;} + inline static bool is_FP_supported(void) {return FP_supported;} + inline static bool is_GLSL_supported(void) {return GLSL_supported;} + inline static bool is_NVFP_supported(void) {return NVFP_supported;} + inline static int get_nb_texture_units(void) {return nb_texture_unit;} + +protected: + + struct Parameter { + GLuint location; + int length; + }; + + const char *get_error(char *data,int pos); + const char *get_glsl_error(); + + void getParameter(const char *name,Parameter *parameter); + + GLhandleARB program; + + GLuint vertex_target; + GLuint vertex_id; + + GLuint fragment_target; + GLuint fragment_id; + + std::vector parameters; + typedef map arb_parameter_list; + arb_parameter_list arb_parameters; + + static bool VP_supported, FP_supported, GLSL_supported, NVFP_supported; + static GLint nb_texture_unit; +}; + +#endif /* __SHADER_H__ */