]> git.mxchange.org Git - simgear.git/commitdiff
Harald JOHNSEN:
authorehofman <ehofman>
Sun, 31 Jul 2005 07:59:08 +0000 (07:59 +0000)
committerehofman <ehofman>
Sun, 31 Jul 2005 07:59:08 +0000 (07:59 +0000)
This is the low level shader class for Simgear.
It's the code from Roman Grigoriev with a few adaptations.

simgear/screen/Makefile.am
simgear/screen/extensions.hxx
simgear/screen/shader.cpp [new file with mode: 0644]
simgear/screen/shader.h [new file with mode: 0644]

index aaa007a3f2b402b39c93226d7b970639e516185b..155d1fe495a226284a9f9f6316d331d46fde18d2 100644 (file)
@@ -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
index 1c3afd60337fbfa7f3b1f3d5fe75a3364f4d1bd8..cf633c1144421b7a8ac43236467990fff2dcb94a 100644 (file)
@@ -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 (file)
index 0000000..6276051
--- /dev/null
@@ -0,0 +1,704 @@
+/* Shader
+ *
+ * Copyright (C) 2003-2005, Alexander Zaprjagaev <frustum@frustum.org>
+ *                          Roman Grigoriev <grigoriev@gosniias.ru>
+ *
+ * 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 <simgear/debug/logstream.hxx>
+#include "shader.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+
+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,&parameter);
+       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,&parameter);
+               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,&parameter);
+       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 (file)
index 0000000..55d804c
--- /dev/null
@@ -0,0 +1,90 @@
+/* Shader
+ *
+ * Copyright (C) 2003-2005, Alexander Zaprjagaev <frustum@frustum.org>
+ *                          Roman Grigoriev <grigoriev@gosniias.ru>
+ *
+ * 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 <simgear/compiler.h>
+#include <simgear/screen/extensions.hxx>
+
+#include <vector>
+
+#include <map>
+#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<Parameter> parameters;
+       typedef map<string, struct Parameter> 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__ */