30f0ad28 |
1 | // Created on: 2013-09-20 |
2 | // Created by: Denis BOGOLEPOV |
3 | // Copyright (c) 2013 OPEN CASCADE SAS |
4 | // |
5 | // The content of this file is subject to the Open CASCADE Technology Public |
6 | // License Version 6.5 (the "License"). You may not use the content of this file |
7 | // except in compliance with the License. Please obtain a copy of the License |
8 | // at http://www.opencascade.org and read it completely before using this file. |
9 | // |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
12 | // |
13 | // The Original Code and all software distributed under the License is |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
15 | // Initial Developer hereby disclaims all such warranties, including without |
16 | // limitation, any warranties of merchantability, fitness for a particular |
17 | // purpose or non-infringement. Please see the License for the specific terms |
18 | // and conditions governing the rights and limitations under the License. |
19 | |
20 | #include <Standard_Atomic.hxx> |
21 | #include <Standard_Assert.hxx> |
22 | |
23 | #include <Graphic3d_GraphicDriver.hxx> |
24 | #include <Graphic3d_ShaderObject.hxx> |
25 | #include <Graphic3d_ShaderProgram.hxx> |
392ac980 |
26 | #include <OSD_Directory.hxx> |
27 | #include <OSD_Environment.hxx> |
28 | #include <OSD_File.hxx> |
29 | #include <OSD_Path.hxx> |
30f0ad28 |
30 | |
31 | namespace |
32 | { |
33 | static volatile Standard_Integer THE_PROGRAM_OBJECT_COUNTER = 0; |
34 | }; |
35 | |
36 | IMPLEMENT_STANDARD_HANDLE (Graphic3d_ShaderProgram, Standard_Transient) |
37 | IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ShaderProgram, Standard_Transient) |
38 | |
392ac980 |
39 | // ======================================================================= |
40 | // function : ShadersFolder |
41 | // purpose : |
42 | // ======================================================================= |
43 | const TCollection_AsciiString& Graphic3d_ShaderProgram::ShadersFolder() |
44 | { |
45 | static Standard_Boolean THE_IS_DEFINED = Standard_False; |
46 | static TCollection_AsciiString THE_SHADERS_FOLDER; |
47 | if (!THE_IS_DEFINED) |
48 | { |
49 | THE_IS_DEFINED = Standard_True; |
50 | OSD_Environment aDirEnv ("CSF_ShadersDirectory"); |
51 | THE_SHADERS_FOLDER = aDirEnv.Value(); |
52 | if (THE_SHADERS_FOLDER.IsEmpty()) |
53 | { |
54 | OSD_Environment aCasRootEnv ("CASROOT"); |
55 | THE_SHADERS_FOLDER = aCasRootEnv.Value(); |
56 | if (!THE_SHADERS_FOLDER.IsEmpty()) |
57 | { |
58 | THE_SHADERS_FOLDER += "/src/Shaders"; |
59 | } |
60 | } |
61 | |
62 | if (THE_SHADERS_FOLDER.IsEmpty()) |
63 | { |
64 | std::cerr << "Both environment variables CSF_ShadersDirectory and CASROOT are undefined!\n" |
65 | << "At least one should be defined to use standard GLSL programs.\n"; |
66 | Standard_Failure::Raise ("CSF_ShadersDirectory and CASROOT are undefined"); |
67 | return THE_SHADERS_FOLDER; |
68 | } |
69 | |
70 | const OSD_Path aDirPath (THE_SHADERS_FOLDER); |
71 | OSD_Directory aDir (aDirPath); |
72 | const TCollection_AsciiString aProgram = THE_SHADERS_FOLDER + "/Declarations.glsl"; |
73 | OSD_File aProgramFile (aProgram); |
74 | if (!aDir.Exists() |
75 | || !aProgramFile.Exists()) |
76 | { |
77 | std::cerr << "Standard GLSL programs are not found in: " << THE_SHADERS_FOLDER.ToCString() << std::endl; |
78 | Standard_Failure::Raise ("CSF_ShadersDirectory or CASROOT is set incorrectly"); |
79 | return THE_SHADERS_FOLDER; |
80 | } |
81 | } |
82 | return THE_SHADERS_FOLDER; |
83 | } |
84 | |
30f0ad28 |
85 | // ======================================================================= |
86 | // function : Graphic3d_ShaderProgram |
87 | // purpose : Creates new empty program object |
88 | // ======================================================================= |
89 | Graphic3d_ShaderProgram::Graphic3d_ShaderProgram() |
90 | { |
91 | myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_") |
92 | + TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER)); |
93 | } |
94 | |
392ac980 |
95 | // ======================================================================= |
96 | // function : Graphic3d_ShaderProgram |
97 | // purpose : |
98 | // ======================================================================= |
99 | Graphic3d_ShaderProgram::Graphic3d_ShaderProgram (const Graphic3d_ShaderProgram::ShaderName theName) |
100 | { |
101 | const TCollection_AsciiString& aShadersRoot = Graphic3d_ShaderProgram::ShadersFolder(); |
102 | switch (theName) |
103 | { |
104 | case ShaderName_Phong: |
105 | { |
106 | myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_Phong"); |
107 | const TCollection_AsciiString aSrcVert = aShadersRoot + "/PhongShading.vs"; |
108 | const TCollection_AsciiString aSrcFrag = aShadersRoot + "/PhongShading.fs"; |
109 | |
110 | if (!aSrcVert.IsEmpty() |
111 | && !OSD_File (aSrcVert).Exists()) |
112 | { |
113 | Standard_Failure::Raise ("Graphic3d_ShaderProgram, PhongShading.vs is not found"); |
114 | return; |
115 | } |
116 | if (!aSrcFrag.IsEmpty() |
117 | && !OSD_File (aSrcFrag).Exists()) |
118 | { |
119 | Standard_Failure::Raise ("Graphic3d_ShaderProgram, PhongShading.fs is not found"); |
120 | return; |
121 | } |
122 | |
123 | AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert)); |
124 | AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag)); |
125 | break; |
126 | } |
127 | case ShaderName_UNKNOWN: |
128 | default: |
129 | { |
130 | Standard_Failure::Raise ("Graphic3d_ShaderProgram, unknown program name"); |
131 | break; |
132 | } |
133 | } |
134 | } |
135 | |
30f0ad28 |
136 | // ======================================================================= |
137 | // function : ~Graphic3d_ShaderProgram |
138 | // purpose : Releases resources of program object |
139 | // ======================================================================= |
140 | Graphic3d_ShaderProgram::~Graphic3d_ShaderProgram() |
141 | { |
142 | Destroy(); |
143 | } |
144 | |
145 | // ======================================================================= |
146 | // function : Destroy |
147 | // purpose : Releases resources of program object |
148 | // ======================================================================= |
149 | void Graphic3d_ShaderProgram::Destroy() const |
150 | { } |
151 | |
152 | // ======================================================================= |
153 | // function : IsDone |
154 | // purpose : Checks if the program object is valid or not |
155 | // ======================================================================= |
156 | Standard_Boolean Graphic3d_ShaderProgram::IsDone() const |
157 | { |
158 | if (myShaderObjects.IsEmpty()) |
159 | { |
160 | return Standard_False; |
161 | } |
162 | |
163 | for (Graphic3d_ShaderObjectList::Iterator anIt (myShaderObjects); anIt.More(); anIt.Next()) |
164 | { |
165 | if (!anIt.Value()->IsDone()) |
166 | return Standard_False; |
167 | } |
168 | |
169 | return Standard_True; |
170 | } |
171 | |
172 | // ======================================================================= |
173 | // function : AttachShader |
174 | // purpose : Attaches shader object to the program object |
175 | // ======================================================================= |
176 | Standard_Boolean Graphic3d_ShaderProgram::AttachShader (const Handle(Graphic3d_ShaderObject)& theShader) |
177 | { |
178 | if (theShader.IsNull()) |
179 | { |
180 | return Standard_False; |
181 | } |
182 | |
183 | for (Graphic3d_ShaderObjectList::Iterator anIt (myShaderObjects); anIt.More(); anIt.Next()) |
184 | { |
185 | if (anIt.Value() == theShader) |
186 | return Standard_False; |
187 | } |
188 | |
189 | myShaderObjects.Append (theShader); |
190 | return Standard_True; |
191 | } |
192 | |
193 | // ======================================================================= |
194 | // function : DetachShader |
195 | // purpose : Detaches shader object from the program object |
196 | // ======================================================================= |
197 | Standard_Boolean Graphic3d_ShaderProgram::DetachShader (const Handle(Graphic3d_ShaderObject)& theShader) |
198 | { |
199 | if (theShader.IsNull()) |
200 | { |
201 | return Standard_False; |
202 | } |
203 | |
204 | for (Graphic3d_ShaderObjectList::Iterator anIt (myShaderObjects); anIt.More(); anIt.Next()) |
205 | { |
206 | if (anIt.Value() == theShader) |
207 | { |
208 | myShaderObjects.Remove (anIt); |
209 | return Standard_True; |
210 | } |
211 | } |
212 | |
213 | return Standard_False; |
214 | } |
215 | |
216 | // ======================================================================= |
217 | // function : ClearVariables |
218 | // purpose : Removes all custom uniform variables from the program |
219 | // ======================================================================= |
220 | void Graphic3d_ShaderProgram::ClearVariables() |
221 | { |
222 | myVariables.Clear(); |
223 | } |