nux-1.14.0
IOpenGLAsmShader.cpp
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 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends