1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include <osl/diagnose.hxx>
25 
26 #include "OGLTrans_Shaders.hxx"
27 
28 namespace unx
29 {
30 #include <GL/glx.h>
31 #include <GL/glxext.h>
32 }
33 
34 bool OGLShaders::cbInitialized = false;
35 
36 #ifdef GL_VERSION_2_0
37 
38 PFNGLCREATESHADERPROC OGLShaders::glCreateShader = NULL;
39 PFNGLSHADERSOURCEPROC OGLShaders::glShaderSource = NULL;
40 PFNGLCOMPILESHADERPROC OGLShaders::glCompileShader = NULL;
41 PFNGLGETSHADERIVPROC OGLShaders::glGetShaderiv = NULL;
42 PFNGLGETSHADERINFOLOGPROC OGLShaders::glGetShaderInfoLog = NULL;
43 PFNGLDELETESHADERPROC OGLShaders::glDeleteShader = NULL;
44 PFNGLCREATEPROGRAMPROC OGLShaders::glCreateProgram = NULL;
45 PFNGLATTACHSHADERPROC OGLShaders::glAttachShader = NULL;
46 PFNGLLINKPROGRAMPROC OGLShaders::glLinkProgram = NULL;
47 PFNGLGETPROGRAMIVPROC OGLShaders::glGetProgramiv = NULL;
48 PFNGLGETPROGRAMINFOLOGPROC OGLShaders::glGetProgramInfoLog = NULL;
49 PFNGLUSEPROGRAMPROC OGLShaders::glUseProgram = NULL;
50 PFNGLDELETEPROGRAMPROC OGLShaders::glDeleteProgram = NULL;
51 PFNGLGETUNIFORMLOCATIONPROC OGLShaders::glGetUniformLocation = NULL;
52 PFNGLUNIFORM1IPROC OGLShaders::glUniform1i = NULL;
53 PFNGLUNIFORM1FPROC OGLShaders::glUniform1f = NULL;
54 #endif
55 
Initialize()56 bool OGLShaders::Initialize()
57 {
58 #ifdef GL_VERSION_2_0
59     if( !cbInitialized ) {
60         glCreateShader = (PFNGLCREATESHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glCreateShader" );
61         glShaderSource = (PFNGLSHADERSOURCEPROC) unx::glXGetProcAddress( (unsigned char *) "glShaderSource" );
62         glCompileShader = (PFNGLCOMPILESHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glCompileShader" );
63         glGetShaderiv = (PFNGLGETSHADERIVPROC) unx::glXGetProcAddress( (unsigned char *) "glGetShaderiv" );
64         glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) unx::glXGetProcAddress( (unsigned char *) "glGetShaderInfoLog" );
65         glDeleteShader = (PFNGLDELETESHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glDeleteShader" );
66         glCreateProgram = (PFNGLCREATEPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glCreateProgram" );
67         glAttachShader = (PFNGLATTACHSHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glAttachShader" );
68         glLinkProgram = (PFNGLLINKPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glLinkProgram" );
69         glGetProgramiv = (PFNGLGETPROGRAMIVPROC) unx::glXGetProcAddress( (unsigned char *) "glGetProgramiv" );
70         glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) unx::glXGetProcAddress( (unsigned char *) "glGetProgramInfoLog" );
71         glUseProgram = (PFNGLUSEPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glUseProgram" );
72         glDeleteProgram = (PFNGLDELETEPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glDeleteProgram" );
73         glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) unx::glXGetProcAddress( (unsigned char *) "glGetUniformLocation" );
74         glUniform1i = (PFNGLUNIFORM1IPROC) unx::glXGetProcAddress( (unsigned char *) "glUniform1i" );
75         glUniform1f = (PFNGLUNIFORM1FPROC) unx::glXGetProcAddress( (unsigned char *) "glUniform1f" );
76         cbInitialized = true;
77     }
78 
79     return glCreateShader != NULL;
80 #else
81     return false;
82 #endif
83 }
84 
LinkProgram(const char * vertexShader,const char * fragmentShader)85 GLuint OGLShaders::LinkProgram( const char *vertexShader, const char *fragmentShader )
86 {
87 #ifdef GL_VERSION_2_0
88     if( !Initialize() )
89         return 0;
90 
91     GLhandleARB vertexObject, fragmentObject, programObject;
92     GLint vertexCompiled, fragmentCompiled, programLinked;
93     char log[1024];
94 
95     vertexObject = glCreateShader( GL_VERTEX_SHADER );
96     fragmentObject = glCreateShader( GL_FRAGMENT_SHADER );
97     OSL_TRACE("checkpoint 1: shaders created (%d) vertex: %d fragment: %d", glGetError() == GL_NO_ERROR, vertexObject, fragmentObject );
98 
99 
100     glShaderSource( vertexObject, 1, &vertexShader, NULL );
101     glShaderSource( fragmentObject, 1, &fragmentShader, NULL );
102 
103     glCompileShader( vertexObject );
104     glGetShaderInfoLog( vertexObject, sizeof( log ), NULL, log );
105     OSL_TRACE("vertex compile log: %s", log);
106     glGetShaderiv( vertexObject, GL_COMPILE_STATUS, &vertexCompiled );
107     glCompileShader( fragmentObject );
108     glGetShaderInfoLog( fragmentObject, sizeof( log ), NULL, log );
109     OSL_TRACE("fragment compile log: %s", log);
110     glGetShaderiv( fragmentObject, GL_COMPILE_STATUS, &fragmentCompiled );
111 
112     if( !vertexCompiled || !fragmentCompiled )
113         return 0;
114 
115     OSL_TRACE("checkpoint 2: shaders compiled (%d)", glGetError() == GL_NO_ERROR);
116 
117     programObject = glCreateProgram();
118     glAttachShader( programObject, vertexObject );
119     glAttachShader( programObject, fragmentObject );
120 
121     glLinkProgram( programObject );
122     glGetProgramInfoLog( programObject, sizeof( log ), NULL, log );
123     OSL_TRACE("program link log: %s", log);
124     glGetProgramiv( programObject, GL_LINK_STATUS, &programLinked );
125 
126     if( !programLinked )
127         return 0;
128 
129     OSL_TRACE("checkpoint 3: program linked (%d)", glGetError() == GL_NO_ERROR);
130 
131     return programObject;
132 #else
133     return 0;
134 #endif
135 }
136 
137