0028824: Possibility to build OCCT 7.1.0 and above using Visual Studio 2008
[occt.git] / src / OpenGl / OpenGl_ShaderObject.cxx
1 // Created on: 2013-09-19
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <Graphic3d_ShaderObject.hxx>
17 #include <OpenGl_Context.hxx>
18 #include <OpenGl_ShaderObject.hxx>
19 #include <OSD_Path.hxx>
20 #include <Standard_Assert.hxx>
21 #include <TCollection_AsciiString.hxx>
22
23 #ifdef _WIN32
24   #include <malloc.h> // for alloca()
25 #endif
26
27 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderObject,OpenGl_Resource)
28
29 // =======================================================================
30 // function : OpenGl_ShaderObject
31 // purpose  : Creates uninitialized shader object
32 // =======================================================================
33 OpenGl_ShaderObject::OpenGl_ShaderObject (GLenum theType)
34 : myType     (theType),
35   myShaderID (NO_SHADER)
36 {
37   //
38 }
39
40 // =======================================================================
41 // function : ~OpenGl_ShaderObject
42 // purpose  : Releases resources of shader object
43 // =======================================================================
44 OpenGl_ShaderObject::~OpenGl_ShaderObject()
45 {
46   Release (NULL);
47 }
48
49 // =======================================================================
50 // function : LoadSource
51 // purpose  : Loads shader source code
52 // =======================================================================
53 Standard_Boolean OpenGl_ShaderObject::LoadSource (const Handle(OpenGl_Context)&  theCtx,
54                                                   const TCollection_AsciiString& theSource)
55 {
56   if (myShaderID == NO_SHADER)
57   {
58     return Standard_False;
59   }
60
61   const GLchar* aLines = theSource.ToCString();
62   theCtx->core20fwd->glShaderSource (myShaderID, 1, &aLines, NULL);
63   return Standard_True;
64 }
65
66 // =======================================================================
67 // function : Compile
68 // purpose  : Compiles the shader object
69 // =======================================================================
70 Standard_Boolean OpenGl_ShaderObject::Compile (const Handle(OpenGl_Context)& theCtx)
71 {
72   if (myShaderID == NO_SHADER)
73   {
74     return Standard_False;
75   }
76
77   // Try to compile shader
78   theCtx->core20fwd->glCompileShader (myShaderID);
79
80   // Check compile status
81   GLint aStatus = GL_FALSE;
82   theCtx->core20fwd->glGetShaderiv (myShaderID, GL_COMPILE_STATUS, &aStatus);
83   return aStatus != GL_FALSE;
84 }
85
86 // =======================================================================
87 // function : FetchInfoLog
88 // purpose  : Fetches information log of the last compile operation
89 // =======================================================================
90 Standard_Boolean OpenGl_ShaderObject::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
91                                                     TCollection_AsciiString&      theLog)
92 {
93   if (myShaderID == NO_SHADER)
94   {
95     return Standard_False;
96   }
97
98   // Load information log of the compiler
99   GLint aLength = 0;
100   theCtx->core20fwd->glGetShaderiv (myShaderID, GL_INFO_LOG_LENGTH, &aLength);
101   if (aLength > 0)
102   {
103     GLchar* aLog = (GLchar*) alloca (aLength);
104     memset (aLog, 0, aLength);
105     theCtx->core20fwd->glGetShaderInfoLog (myShaderID, aLength, NULL, aLog);
106     theLog = aLog;
107   }
108
109   return Standard_True;
110 }
111
112 // =======================================================================
113 // function : Create
114 // purpose  : Creates new empty shader object of specified type
115 // =======================================================================
116 Standard_Boolean OpenGl_ShaderObject::Create (const Handle(OpenGl_Context)& theCtx)
117 {
118   if (myShaderID == NO_SHADER
119    && theCtx->core20fwd != NULL)
120   {
121     myShaderID = theCtx->core20fwd->glCreateShader (myType);
122   }
123
124   return myShaderID != NO_SHADER;
125 }
126
127 // =======================================================================
128 // function : Release
129 // purpose  : Destroys shader object
130 // =======================================================================
131 void OpenGl_ShaderObject::Release (OpenGl_Context* theCtx)
132 {
133   if (myShaderID == NO_SHADER)
134   {
135     return;
136   }
137
138   Standard_ASSERT_RETURN (theCtx != NULL,
139     "OpenGl_ShaderObject destroyed without GL context! Possible GPU memory leakage...",);
140
141   if (theCtx->core20fwd != NULL
142    && theCtx->IsValid())
143   {
144     theCtx->core20fwd->glDeleteShader (myShaderID);
145   }
146   myShaderID = NO_SHADER;
147 }