1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include <osl/diagnose.hxx>
29 
30 #include "OGLTrans_Shaders.hxx"
31 
32 namespace unx
33 {
34 #include <GL/glx.h>
35 #include <GL/glxext.h>
36 }
37 
38 bool OGLShaders::cbInitialized = false;
39 
40 #ifdef GL_VERSION_2_0
41 
42 PFNGLCREATESHADERPROC OGLShaders::glCreateShader = NULL;
43 PFNGLSHADERSOURCEPROC OGLShaders::glShaderSource = NULL;
44 PFNGLCOMPILESHADERPROC OGLShaders::glCompileShader = NULL;
45 PFNGLGETSHADERIVPROC OGLShaders::glGetShaderiv = NULL;
46 PFNGLGETSHADERINFOLOGPROC OGLShaders::glGetShaderInfoLog = NULL;
47 PFNGLDELETESHADERPROC OGLShaders::glDeleteShader = NULL;
48 PFNGLCREATEPROGRAMPROC OGLShaders::glCreateProgram = NULL;
49 PFNGLATTACHSHADERPROC OGLShaders::glAttachShader = NULL;
50 PFNGLLINKPROGRAMPROC OGLShaders::glLinkProgram = NULL;
51 PFNGLGETPROGRAMIVPROC OGLShaders::glGetProgramiv = NULL;
52 PFNGLGETPROGRAMINFOLOGPROC OGLShaders::glGetProgramInfoLog = NULL;
53 PFNGLUSEPROGRAMPROC OGLShaders::glUseProgram = NULL;
54 PFNGLDELETEPROGRAMPROC OGLShaders::glDeleteProgram = NULL;
55 PFNGLGETUNIFORMLOCATIONPROC OGLShaders::glGetUniformLocation = NULL;
56 PFNGLUNIFORM1IPROC OGLShaders::glUniform1i = NULL;
57 PFNGLUNIFORM1FPROC OGLShaders::glUniform1f = NULL;
58 #endif
59 
60 bool OGLShaders::Initialize()
61 {
62 #ifdef GL_VERSION_2_0
63     if( !cbInitialized ) {
64         glCreateShader = (PFNGLCREATESHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glCreateShader" );
65         glShaderSource = (PFNGLSHADERSOURCEPROC) unx::glXGetProcAddress( (unsigned char *) "glShaderSource" );
66         glCompileShader = (PFNGLCOMPILESHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glCompileShader" );
67         glGetShaderiv = (PFNGLGETSHADERIVPROC) unx::glXGetProcAddress( (unsigned char *) "glGetShaderiv" );
68         glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) unx::glXGetProcAddress( (unsigned char *) "glGetShaderInfoLog" );
69         glDeleteShader = (PFNGLDELETESHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glDeleteShader" );
70         glCreateProgram = (PFNGLCREATEPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glCreateProgram" );
71         glAttachShader = (PFNGLATTACHSHADERPROC) unx::glXGetProcAddress( (unsigned char *) "glAttachShader" );
72         glLinkProgram = (PFNGLLINKPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glLinkProgram" );
73         glGetProgramiv = (PFNGLGETPROGRAMIVPROC) unx::glXGetProcAddress( (unsigned char *) "glGetProgramiv" );
74         glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) unx::glXGetProcAddress( (unsigned char *) "glGetProgramInfoLog" );
75         glUseProgram = (PFNGLUSEPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glUseProgram" );
76         glDeleteProgram = (PFNGLDELETEPROGRAMPROC) unx::glXGetProcAddress( (unsigned char *) "glDeleteProgram" );
77         glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) unx::glXGetProcAddress( (unsigned char *) "glGetUniformLocation" );
78         glUniform1i = (PFNGLUNIFORM1IPROC) unx::glXGetProcAddress( (unsigned char *) "glUniform1i" );
79         glUniform1f = (PFNGLUNIFORM1FPROC) unx::glXGetProcAddress( (unsigned char *) "glUniform1f" );
80         cbInitialized = true;
81     }
82 
83     return glCreateShader != NULL;
84 #else
85     return false;
86 #endif
87 }
88 
89 GLuint OGLShaders::LinkProgram( const char *vertexShader, const char *fragmentShader )
90 {
91 #ifdef GL_VERSION_2_0
92     if( !Initialize() )
93         return 0;
94 
95     GLhandleARB vertexObject, fragmentObject, programObject;
96     GLint vertexCompiled, fragmentCompiled, programLinked;
97     char log[1024];
98 
99     vertexObject = glCreateShader( GL_VERTEX_SHADER );
100     fragmentObject = glCreateShader( GL_FRAGMENT_SHADER );
101     OSL_TRACE("checkpoint 1: shaders created (%d) vertex: %d fragment: %d", glGetError() == GL_NO_ERROR, vertexObject, fragmentObject );
102 
103 
104     glShaderSource( vertexObject, 1, &vertexShader, NULL );
105     glShaderSource( fragmentObject, 1, &fragmentShader, NULL );
106 
107     glCompileShader( vertexObject );
108     glGetShaderInfoLog( vertexObject, sizeof( log ), NULL, log );
109     OSL_TRACE("vertex compile log: %s", log);
110     glGetShaderiv( vertexObject, GL_COMPILE_STATUS, &vertexCompiled );
111     glCompileShader( fragmentObject );
112     glGetShaderInfoLog( fragmentObject, sizeof( log ), NULL, log );
113     OSL_TRACE("fragment compile log: %s", log);
114     glGetShaderiv( fragmentObject, GL_COMPILE_STATUS, &fragmentCompiled );
115 
116     if( !vertexCompiled || !fragmentCompiled )
117         return 0;
118 
119     OSL_TRACE("checkpoint 2: shaders compiled (%d)", glGetError() == GL_NO_ERROR);
120 
121     programObject = glCreateProgram();
122     glAttachShader( programObject, vertexObject );
123     glAttachShader( programObject, fragmentObject );
124 
125     glLinkProgram( programObject );
126     glGetProgramInfoLog( programObject, sizeof( log ), NULL, log );
127     OSL_TRACE("program link log: %s", log);
128     glGetProgramiv( programObject, GL_LINK_STATUS, &programLinked );
129 
130     if( !programLinked )
131         return 0;
132 
133     OSL_TRACE("checkpoint 3: program linked (%d)", glGetError() == GL_NO_ERROR);
134 
135     return programObject;
136 #else
137     return 0;
138 #endif
139 }
140 
141