8aec5ad43190b26a100a86d18a69a5daf4c58f71
[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 IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderObject, OpenGl_Resource)
24 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderObject, OpenGl_Resource)
25
26 // =======================================================================
27 // function : OpenGl_ShaderObject
28 // purpose  : Creates uninitialized shader object
29 // =======================================================================
30 OpenGl_ShaderObject::OpenGl_ShaderObject (GLenum theType)
31 : myType     (theType),
32   myShaderID (NO_SHADER)
33 {
34   //
35 }
36
37 // =======================================================================
38 // function : ~OpenGl_ShaderObject
39 // purpose  : Releases resources of shader object
40 // =======================================================================
41 OpenGl_ShaderObject::~OpenGl_ShaderObject()
42 {
43   Release (NULL);
44 }
45
46 // =======================================================================
47 // function : LoadSource
48 // purpose  : Loads shader source code
49 // =======================================================================
50 Standard_Boolean OpenGl_ShaderObject::LoadSource (const Handle(OpenGl_Context)&  theCtx,
51                                                   const TCollection_AsciiString& theSource)
52 {
53   if (myShaderID == NO_SHADER)
54   {
55     return Standard_False;
56   }
57
58   const GLchar* aLines = theSource.ToCString();
59   theCtx->core20->glShaderSource (myShaderID, 1, &aLines, NULL);
60   return Standard_True;
61 }
62
63 // =======================================================================
64 // function : Compile
65 // purpose  : Compiles the shader object
66 // =======================================================================
67 Standard_Boolean OpenGl_ShaderObject::Compile (const Handle(OpenGl_Context)& theCtx)
68 {
69   if (myShaderID == NO_SHADER)
70   {
71     return Standard_False;
72   }
73
74   // Try to compile shader
75   theCtx->core20->glCompileShader (myShaderID);
76
77   // Check compile status
78   GLint aStatus = GL_FALSE;
79   theCtx->core20->glGetShaderiv (myShaderID, GL_COMPILE_STATUS, &aStatus);
80   return aStatus != GL_FALSE;
81 }
82
83 // =======================================================================
84 // function : FetchInfoLog
85 // purpose  : Fetches information log of the last compile operation
86 // =======================================================================
87 Standard_Boolean OpenGl_ShaderObject::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
88                                                     TCollection_AsciiString&      theLog)
89 {
90   if (myShaderID == NO_SHADER)
91   {
92     return Standard_False;
93   }
94
95   // Load information log of the compiler
96   GLint aLength = 0;
97   theCtx->core20->glGetShaderiv (myShaderID, GL_INFO_LOG_LENGTH, &aLength);
98   if (aLength > 0)
99   {
100     GLchar* aLog = (GLchar*) alloca (aLength);
101     memset (aLog, 0, aLength);
102     theCtx->core20->glGetShaderInfoLog (myShaderID, aLength, NULL, aLog);
103     theLog = aLog;
104   }
105
106   return Standard_True;
107 }
108
109 // =======================================================================
110 // function : Create
111 // purpose  : Creates new empty shader object of specified type
112 // =======================================================================
113 Standard_Boolean OpenGl_ShaderObject::Create (const Handle(OpenGl_Context)& theCtx)
114 {
115   if (myShaderID == NO_SHADER
116    && theCtx->core20 != NULL)
117   {
118     myShaderID = theCtx->core20->glCreateShader (myType);
119   }
120
121   return myShaderID != NO_SHADER;
122 }
123
124 // =======================================================================
125 // function : Release
126 // purpose  : Destroys shader object
127 // =======================================================================
128 void OpenGl_ShaderObject::Release (OpenGl_Context* theCtx)
129 {
130   if (myShaderID == NO_SHADER)
131   {
132     return;
133   }
134
135   Standard_ASSERT_RETURN (theCtx != NULL,
136     "OpenGl_ShaderObject destroyed without GL context! Possible GPU memory leakage...",);
137
138   if (theCtx->core20 != NULL
139    && theCtx->IsValid())
140   {
141     theCtx->core20->glDeleteShader (myShaderID);
142   }
143   myShaderID = NO_SHADER;
144 }