nux-1.16.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "GLResource.h" 00024 #include "GraphicsDisplay.h" 00025 #include "GpuDevice.h" 00026 #include "GLDeviceObjects.h" 00027 #include "IOpenGLAsmShader.h" 00028 00029 namespace nux 00030 { 00031 00032 NUX_IMPLEMENT_OBJECT_TYPE (IOpenGLAsmShader); 00033 NUX_IMPLEMENT_OBJECT_TYPE (IOpenGLAsmVertexShader); 00034 NUX_IMPLEMENT_OBJECT_TYPE (IOpenGLAsmPixelShader); 00035 NUX_IMPLEMENT_OBJECT_TYPE (IOpenGLAsmShaderProgram); 00036 00037 bool ExtractShaderString3 (const NString &ShaderToken, const NString &ShaderSource, NString &RetSource, NString ShaderPreprocessorDefines); 00038 00039 IOpenGLAsmShader::IOpenGLAsmShader (NString ShaderName, OpenGLResourceType ResourceType) 00040 : IOpenGLResource (ResourceType) 00041 , _ShaderName (ShaderName) 00042 { 00043 00044 } 00045 00046 IOpenGLAsmShader::~IOpenGLAsmShader() 00047 { 00048 00049 } 00050 00051 IOpenGLAsmVertexShader::IOpenGLAsmVertexShader (NString ShaderName) 00052 : IOpenGLAsmShader (ShaderName, RT_GLSL_VERTEXSHADER) 00053 , m_CompiledAndReady (false) 00054 { 00055 CHECKGL ( glGenProgramsARB (1, &_OpenGLID) ); 00056 } 00057 00058 IOpenGLAsmVertexShader::~IOpenGLAsmVertexShader() 00059 { 00060 CHECKGL ( glDeleteProgramsARB (1, &_OpenGLID) ); 00061 _OpenGLID = 0; 00062 m_CompiledAndReady = false; 00063 } 00064 00065 void IOpenGLAsmVertexShader::SetShaderCode (const TCHAR *ShaderCode) 00066 { 00067 nuxAssertMsg (ShaderCode, TEXT ("[IOpenGLAsmVertexShader::SetShaderCode] Invalid shader code.") ); 00068 NUX_RETURN_IF_NULL (ShaderCode); 00069 m_CompiledAndReady = false; 00070 _ShaderCode = ShaderCode; 00071 } 00072 00073 bool IOpenGLAsmVertexShader::Compile() 00074 { 00075 m_CompiledAndReady = false; 00076 t_size CodeSize = _ShaderCode.Size(); 00077 00078 if (CodeSize == 0) 00079 { 00080 nuxDebugMsg (TEXT ("[IOpenGLAsmVertexShader::Compile] Vertex shader source code is empty.") ); 00081 } 00082 00083 char *ShaderSource = new char[CodeSize+1]; 00084 Memset (ShaderSource, 0, CodeSize + 1); 00085 Memcpy (ShaderSource, TCHAR_TO_ANSI (_ShaderCode.GetTCharPtr() ), CodeSize); 00086 00087 CHECKGL ( glBindProgramARB (GL_VERTEX_PROGRAM_ARB, _OpenGLID) ); 00088 glProgramStringARB (GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, CodeSize, ShaderSource); 00089 00090 if ( GL_INVALID_OPERATION == glGetError() ) 00091 { 00092 // Find the error position 00093 GLint errPos; 00094 glGetIntegerv ( GL_PROGRAM_ERROR_POSITION_ARB, &errPos ); 00095 // Print implementation-dependent program 00096 // errors and warnings string. 00097 const unsigned char *ErrorString; 00098 ErrorString = NUX_STATIC_CAST (const unsigned char *, glGetString (GL_PROGRAM_ERROR_STRING_ARB) ); 00099 nuxError (TEXT ("[IOpenGLAsmVertexShader::Compile] Error in vertex shader at position: %d\n%s\n"), errPos, ErrorString ); 00100 return m_CompiledAndReady; 00101 } 00102 00103 delete[] ShaderSource; 00104 00105 m_CompiledAndReady = true; 00106 return m_CompiledAndReady; 00107 } 00108 00109 bool IOpenGLAsmVertexShader::IsValid() 00110 { 00111 return m_CompiledAndReady; 00112 } 00113 00114 IOpenGLAsmPixelShader::IOpenGLAsmPixelShader (NString ShaderName) 00115 : IOpenGLAsmShader (ShaderName, RT_GLSL_PIXELSHADER) 00116 , m_CompiledAndReady (false) 00117 { 00118 CHECKGL ( glGenProgramsARB (1, &_OpenGLID) ); 00119 } 00120 00121 IOpenGLAsmPixelShader::~IOpenGLAsmPixelShader() 00122 { 00123 CHECKGL ( glDeleteProgramsARB (1, &_OpenGLID) ); 00124 _OpenGLID = 0; 00125 m_CompiledAndReady = false; 00126 } 00127 00128 void IOpenGLAsmPixelShader::SetShaderCode (const TCHAR *ShaderCode) 00129 { 00130 nuxAssertMsg (ShaderCode, TEXT ("[IOpenGLAsmPixelShader::SetShaderCode] Invalid shader code.") ); 00131 NUX_RETURN_IF_NULL (ShaderCode); 00132 m_CompiledAndReady = false; 00133 _ShaderCode = ShaderCode; 00134 } 00135 00136 bool IOpenGLAsmPixelShader::Compile() 00137 { 00138 m_CompiledAndReady = false; 00139 t_size CodeSize = _ShaderCode.Size(); 00140 00141 if (CodeSize == 0) 00142 { 00143 nuxDebugMsg (TEXT ("[IOpenGLAsmPixelShader::Compile] Vertex shader source code is empty.") ); 00144 } 00145 00146 char *ShaderSource = new char[CodeSize+1]; 00147 Memset (ShaderSource, 0, CodeSize + 1); 00148 Memcpy (ShaderSource, TCHAR_TO_ANSI (_ShaderCode.GetTCharPtr() ), CodeSize); 00149 00150 CHECKGL ( glBindProgramARB (GL_FRAGMENT_PROGRAM_ARB, _OpenGLID) ); 00151 glProgramStringARB (GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, CodeSize, ShaderSource); 00152 00153 if ( GL_INVALID_OPERATION == glGetError() ) 00154 { 00155 // Find the error position 00156 GLint errPos; 00157 glGetIntegerv ( GL_PROGRAM_ERROR_POSITION_ARB, &errPos ); 00158 // Print implementation-dependent program 00159 // errors and warnings string. 00160 const unsigned char *ErrorString; 00161 ErrorString = NUX_STATIC_CAST (const unsigned char *, glGetString (GL_PROGRAM_ERROR_STRING_ARB) ); 00162 nuxError (TEXT ("[IOpenGLAsmPixelShader::Compile] Error in fragment shader at position: %d\n%s\n"), errPos, ErrorString ); 00163 } 00164 00165 delete[] ShaderSource; 00166 00167 m_CompiledAndReady = true; 00168 return m_CompiledAndReady; 00169 } 00170 00171 bool IOpenGLAsmPixelShader::IsValid() 00172 { 00173 return m_CompiledAndReady; 00174 } 00175 00176 IOpenGLAsmShaderProgram::IOpenGLAsmShaderProgram (NString ShaderProgramName) 00177 : IOpenGLResource (RT_GLSL_SHADERPROGRAM) 00178 , _ShaderProgramName (ShaderProgramName) 00179 { 00180 _OpenGLID = 0; 00181 m_AsmVertexProgram = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmVertexShader(); 00182 m_AsmFragmentProgram = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmPixelShader(); 00183 } 00184 00185 IOpenGLAsmShaderProgram::~IOpenGLAsmShaderProgram() 00186 { 00187 _OpenGLID = 0; 00188 } 00189 00190 void IOpenGLAsmShaderProgram::LoadIShaderFile (const TCHAR *ShaderFileName) 00191 { 00192 nuxAssertMsg (ShaderFileName, TEXT ("[IOpenGLAsmShaderProgram::LoadIShaderFile] Invalid shader file name.") ); 00193 NUX_RETURN_IF_NULL (ShaderFileName); 00194 NString SourceCode; 00195 LoadFileToString (SourceCode, ShaderFileName); 00196 LoadIShader (&SourceCode[0]); 00197 } 00198 00199 void IOpenGLAsmShaderProgram::LoadIShader (const TCHAR *ShaderCode) 00200 { 00201 nuxAssertMsg (ShaderCode, TEXT ("[IOpenGLAsmShaderProgram::LoadIShader] Invalid shader code.") ); 00202 NUX_RETURN_IF_NULL (ShaderCode); 00203 NString VertexShaderSource; 00204 ExtractShaderString3 (TEXT ("[Vertex Shader]"), ShaderCode, VertexShaderSource, NString ("") ); 00205 NString PixelShaderSource; 00206 ExtractShaderString3 (TEXT ("[Fragment Shader]"), ShaderCode, PixelShaderSource, NString ("") ); 00207 00208 m_AsmVertexProgram->SetShaderCode (&VertexShaderSource[0]); 00209 m_AsmFragmentProgram->SetShaderCode (&PixelShaderSource[0]); 00210 00211 m_AsmVertexProgram->Compile(); 00212 m_AsmFragmentProgram->Compile(); 00213 } 00214 00215 void IOpenGLAsmShaderProgram::LoadVertexShader (const TCHAR *glslshader) 00216 { 00217 nuxAssertMsg (glslshader, TEXT ("[IOpenGLAsmShaderProgram::LoadVertexShader] Invalid shader code.") ); 00218 NUX_RETURN_IF_NULL (glslshader); 00219 m_AsmVertexProgram->SetShaderCode (glslshader); 00220 m_AsmVertexProgram->Compile(); 00221 } 00222 00223 void IOpenGLAsmShaderProgram::LoadPixelShader (const TCHAR *glslshader) 00224 { 00225 nuxAssertMsg (glslshader, TEXT ("[IOpenGLAsmShaderProgram::LoadPixelShader] Invalid shader code.") ); 00226 NUX_RETURN_IF_NULL (glslshader); 00227 m_AsmFragmentProgram->SetShaderCode (glslshader); 00228 m_AsmFragmentProgram->Compile(); 00229 } 00230 00231 void IOpenGLAsmShaderProgram::Link() 00232 { 00233 m_AsmVertexProgram->Compile(); 00234 m_AsmFragmentProgram->Compile(); 00235 } 00236 00237 bool IOpenGLAsmShaderProgram::IsValid() 00238 { 00239 if (m_AsmVertexProgram->IsValid() && m_AsmFragmentProgram->IsValid() ) 00240 return true; 00241 00242 return false; 00243 } 00244 00245 void IOpenGLAsmShaderProgram::Begin (void) 00246 { 00247 CHECKGL ( glEnable (GL_VERTEX_PROGRAM_ARB) ); 00248 CHECKGL ( glBindProgramARB (GL_VERTEX_PROGRAM_ARB, m_AsmVertexProgram->GetOpenGLID() ) ); 00249 CHECKGL ( glEnable (GL_FRAGMENT_PROGRAM_ARB) ); 00250 CHECKGL ( glBindProgramARB (GL_FRAGMENT_PROGRAM_ARB, m_AsmFragmentProgram->GetOpenGLID() ) ); 00251 } 00252 00253 void IOpenGLAsmShaderProgram::End (void) 00254 { 00255 CHECKGL ( glDisable (GL_VERTEX_PROGRAM_ARB) ); 00256 CHECKGL ( glBindProgramARB (GL_VERTEX_PROGRAM_ARB, 0) ); 00257 CHECKGL ( glDisable (GL_FRAGMENT_PROGRAM_ARB) ); 00258 CHECKGL ( glBindProgramARB (GL_FRAGMENT_PROGRAM_ARB, 0) ); 00259 } 00260 00261 void IOpenGLAsmShaderProgram::SetVertexEnvParameter4dARB (t_uint32 index, double x, double y, double z, double w) 00262 { 00263 CHECKGL ( glProgramEnvParameter4dARB (GL_VERTEX_PROGRAM_ARB, index, x, y, z, w) ); 00264 } 00265 00266 void IOpenGLAsmShaderProgram::SetVertexEnvParameter4dvARB (t_uint32 index, const double *params) 00267 { 00268 CHECKGL ( glProgramEnvParameter4dvARB (GL_VERTEX_PROGRAM_ARB, index, params) ); 00269 } 00270 00271 void IOpenGLAsmShaderProgram::SetVertexEnvParameter4fARB (t_uint32 index, float x, float y, float z, float w) 00272 { 00273 CHECKGL ( glProgramEnvParameter4fARB (GL_VERTEX_PROGRAM_ARB, index, x, y, z, w) ); 00274 } 00275 00276 void IOpenGLAsmShaderProgram::SetVertexEnvParameter4fvARB (t_uint32 index, const float *params) 00277 { 00278 CHECKGL ( glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, index, params) ); 00279 } 00280 00281 void IOpenGLAsmShaderProgram::SetVertexLocalParameter4dARB (t_uint32 index, double x, double y, double z, double w) 00282 { 00283 CHECKGL ( glProgramEnvParameter4dARB (GL_VERTEX_PROGRAM_ARB, index, x, y, z, w) ); 00284 } 00285 00286 void IOpenGLAsmShaderProgram::SetVertexLocalParameter4dvARB (t_uint32 index, const double *params) 00287 { 00288 CHECKGL ( glProgramEnvParameter4dvARB (GL_VERTEX_PROGRAM_ARB, index, params) ); 00289 } 00290 00291 void IOpenGLAsmShaderProgram::SetVertexLocalParameter4fARB (t_uint32 index, float x, float y, float z, float w) 00292 { 00293 CHECKGL ( glProgramEnvParameter4fARB (GL_VERTEX_PROGRAM_ARB, index, x, y, z, w) ); 00294 } 00295 00296 void IOpenGLAsmShaderProgram::SetVertexLocalParameter4fvARB (t_uint32 index, const float *params) 00297 { 00298 CHECKGL ( glProgramEnvParameter4fvARB (GL_VERTEX_PROGRAM_ARB, index, params) ); 00299 } 00300 00301 void IOpenGLAsmShaderProgram::SetFragmentEnvParameter4dARB (t_uint32 index, double x, double y, double z, double w) 00302 { 00303 CHECKGL ( glProgramEnvParameter4dARB (GL_FRAGMENT_PROGRAM_ARB, index, x, y, z, w) ); 00304 } 00305 00306 void IOpenGLAsmShaderProgram::SetFragmentEnvParameter4dvARB (t_uint32 index, const double *params) 00307 { 00308 CHECKGL ( glProgramEnvParameter4dvARB (GL_FRAGMENT_PROGRAM_ARB, index, params) ); 00309 } 00310 00311 void IOpenGLAsmShaderProgram::SetFragmentEnvParameter4fARB (t_uint32 index, float x, float y, float z, float w) 00312 { 00313 CHECKGL ( glProgramEnvParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, index, x, y, z, w) ); 00314 } 00315 00316 void IOpenGLAsmShaderProgram::SetFragmentEnvParameter4fvARB (t_uint32 index, const float *params) 00317 { 00318 CHECKGL ( glProgramEnvParameter4fvARB (GL_FRAGMENT_PROGRAM_ARB, index, params) ); 00319 } 00320 00321 void IOpenGLAsmShaderProgram::SetFragmentLocalParameter4dARB (t_uint32 index, double x, double y, double z, double w) 00322 { 00323 CHECKGL ( glProgramEnvParameter4dARB (GL_FRAGMENT_PROGRAM_ARB, index, x, y, z, w) ); 00324 } 00325 00326 void IOpenGLAsmShaderProgram::SetFragmentLocalParameter4dvARB (t_uint32 index, const double *params) 00327 { 00328 CHECKGL ( glProgramEnvParameter4dvARB (GL_FRAGMENT_PROGRAM_ARB, index, params) ); 00329 } 00330 00331 void IOpenGLAsmShaderProgram::SetFragmentLocalParameter4fARB (t_uint32 index, float x, float y, float z, float w) 00332 { 00333 CHECKGL ( glProgramEnvParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, index, x, y, z, w) ); 00334 } 00335 00336 void IOpenGLAsmShaderProgram::SetFragmentLocalParameter4fvARB (t_uint32 index, const float *params) 00337 { 00338 CHECKGL ( glProgramEnvParameter4fvARB (GL_FRAGMENT_PROGRAM_ARB, index, params) ); 00339 } 00340 00341 }