]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/COpenGLSLMaterialRenderer.cpp
Remove more unused code (#87)
[irrlicht.git] / source / Irrlicht / COpenGLSLMaterialRenderer.cpp
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt\r
2 // This file is part of the "Irrlicht Engine".\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
4 \r
5 // This file was originally written by William Finlayson.  I (Nikolaus\r
6 // Gebhardt) did some minor modifications and changes to it and integrated it\r
7 // into Irrlicht. Thanks a lot to William for his work on this and that he gave\r
8 // me his permission to add it into Irrlicht using the zlib license.\r
9 \r
10 // After Irrlicht 0.12, Michael Zoech did some improvements to this renderer, I\r
11 // merged this into Irrlicht 0.14, thanks to him for his work.\r
12 \r
13 #include "COpenGLSLMaterialRenderer.h"\r
14 \r
15 #ifdef _IRR_COMPILE_WITH_OPENGL_\r
16 \r
17 #include "IGPUProgrammingServices.h"\r
18 #include "IShaderConstantSetCallBack.h"\r
19 #include "IMaterialRendererServices.h"\r
20 #include "IVideoDriver.h"\r
21 #include "os.h"\r
22 \r
23 #include "COpenGLDriver.h"\r
24 #include "COpenGLCacheHandler.h"\r
25 #include "COpenGLMaterialRenderer.h"\r
26 \r
27 #include "COpenGLCoreFeature.h"\r
28 \r
29 namespace irr\r
30 {\r
31 namespace video\r
32 {\r
33 \r
34 \r
35 //! Constructor\r
36 COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* driver,\r
37                 s32& outMaterialTypeNr, const c8* vertexShaderProgram,\r
38                 const c8* vertexShaderEntryPointName,\r
39                 E_VERTEX_SHADER_TYPE vsCompileTarget,\r
40                 const c8* pixelShaderProgram,\r
41                 const c8* pixelShaderEntryPointName,\r
42                 E_PIXEL_SHADER_TYPE psCompileTarget,\r
43                 const c8* geometryShaderProgram,\r
44                 const c8* geometryShaderEntryPointName,\r
45                 E_GEOMETRY_SHADER_TYPE gsCompileTarget,\r
46                 scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType,\r
47                 u32 verticesOut,\r
48                 IShaderConstantSetCallBack* callback,\r
49                 E_MATERIAL_TYPE baseMaterial,\r
50                 s32 userData)\r
51         : Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false), AlphaTest(false), Program(0), Program2(0), UserData(userData)\r
52 {\r
53         #ifdef _DEBUG\r
54         setDebugName("COpenGLSLMaterialRenderer");\r
55         #endif\r
56 \r
57         switch (baseMaterial)\r
58         {\r
59         case EMT_TRANSPARENT_VERTEX_ALPHA:\r
60         case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
61                 Alpha = true;\r
62                 break;\r
63         case EMT_TRANSPARENT_ADD_COLOR:\r
64                 FixedBlending = true;\r
65                 break;\r
66         case EMT_ONETEXTURE_BLEND:\r
67                 Blending = true;\r
68                 break;\r
69         case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:\r
70                 AlphaTest = true;\r
71                 break;\r
72         default:\r
73                 break;\r
74         }\r
75 \r
76         if (CallBack)\r
77                 CallBack->grab();\r
78 \r
79         if (!Driver->queryFeature(EVDF_ARB_GLSL))\r
80                 return;\r
81 \r
82         init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram, geometryShaderProgram);\r
83 }\r
84 \r
85 \r
86 //! constructor only for use by derived classes who want to\r
87 //! create a fall back material for example.\r
88 COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver* driver,\r
89                                         IShaderConstantSetCallBack* callback,\r
90                                         E_MATERIAL_TYPE baseMaterial, s32 userData)\r
91 : Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false), AlphaTest(false), Program(0), Program2(0), UserData(userData)\r
92 {\r
93         switch (baseMaterial)\r
94         {\r
95         case EMT_TRANSPARENT_VERTEX_ALPHA:\r
96         case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
97                 Alpha = true;\r
98                 break;\r
99         case EMT_TRANSPARENT_ADD_COLOR:\r
100                 FixedBlending = true;\r
101                 break;\r
102         case EMT_ONETEXTURE_BLEND:\r
103                 Blending = true;\r
104                 break;\r
105         case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:\r
106                 AlphaTest = true;\r
107                 break;\r
108         default:\r
109                 break;\r
110         }\r
111 \r
112         if (CallBack)\r
113                 CallBack->grab();\r
114 }\r
115 \r
116 \r
117 //! Destructor\r
118 COpenGLSLMaterialRenderer::~COpenGLSLMaterialRenderer()\r
119 {\r
120         if (CallBack)\r
121                 CallBack->drop();\r
122 \r
123         if (Program)\r
124         {\r
125                 GLhandleARB shaders[8];\r
126                 GLint count;\r
127                 Driver->extGlGetAttachedObjects(Program, 8, &count, shaders);\r
128                 // avoid bugs in some drivers, which return larger numbers\r
129                 // use int variable to avoid compiler problems with template\r
130                 int mincount=core::min_((int)count,8);\r
131                 for (int i=0; i<mincount; ++i)\r
132                         Driver->extGlDeleteObject(shaders[i]);\r
133                 Driver->extGlDeleteObject(Program);\r
134                 Program = 0;\r
135         }\r
136 \r
137         if (Program2)\r
138         {\r
139                 GLuint shaders[8];\r
140                 GLint count;\r
141                 Driver->extGlGetAttachedShaders(Program2, 8, &count, shaders);\r
142                 // avoid bugs in some drivers, which return larger numbers\r
143                 // use int variable to avoid compiler problems with template\r
144                 int mincount=core::min_((int)count,8);\r
145                 for (int i=0; i<mincount; ++i)\r
146                         Driver->extGlDeleteShader(shaders[i]);\r
147                 Driver->extGlDeleteProgram(Program2);\r
148                 Program2 = 0;\r
149         }\r
150 \r
151         UniformInfo.clear();\r
152 }\r
153 \r
154 \r
155 void COpenGLSLMaterialRenderer::init(s32& outMaterialTypeNr,\r
156                 const c8* vertexShaderProgram,\r
157                 const c8* pixelShaderProgram,\r
158                 const c8* geometryShaderProgram,\r
159                 scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType,\r
160                 u32 verticesOut)\r
161 {\r
162         outMaterialTypeNr = -1;\r
163 \r
164         if (!createProgram())\r
165                 return;\r
166 \r
167 #if defined(GL_ARB_vertex_shader) && defined (GL_ARB_fragment_shader)\r
168         if (vertexShaderProgram)\r
169                 if (!createShader(GL_VERTEX_SHADER_ARB, vertexShaderProgram))\r
170                         return;\r
171 \r
172         if (pixelShaderProgram)\r
173                 if (!createShader(GL_FRAGMENT_SHADER_ARB, pixelShaderProgram))\r
174                         return;\r
175 #endif\r
176 \r
177 #if defined(GL_ARB_geometry_shader4) || defined(GL_EXT_geometry_shader4) || defined(GL_NV_geometry_program4) || defined(GL_NV_geometry_shader4)\r
178         if (geometryShaderProgram && Driver->queryFeature(EVDF_GEOMETRY_SHADER))\r
179         {\r
180                 if (!createShader(GL_GEOMETRY_SHADER_EXT, geometryShaderProgram))\r
181                         return;\r
182 #if defined(GL_ARB_geometry_shader4) || defined(GL_EXT_geometry_shader4) || defined(GL_NV_geometry_shader4)\r
183                 if (Program2) // Geometry shaders are supported only in OGL2.x+ drivers.\r
184                 {\r
185                         Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_INPUT_TYPE_EXT, Driver->primitiveTypeToGL(inType));\r
186                         Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_OUTPUT_TYPE_EXT, Driver->primitiveTypeToGL(outType));\r
187                         if (verticesOut==0)\r
188                                 Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_VERTICES_OUT_EXT, Driver->MaxGeometryVerticesOut);\r
189                         else\r
190                                 Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_VERTICES_OUT_EXT, core::min_(verticesOut, Driver->MaxGeometryVerticesOut));\r
191                 }\r
192 #elif defined(GL_NV_geometry_program4)\r
193                 if (verticesOut==0)\r
194                         Driver->extGlProgramVertexLimit(GL_GEOMETRY_PROGRAM_NV, Driver->MaxGeometryVerticesOut);\r
195                 else\r
196                         Driver->extGlProgramVertexLimit(GL_GEOMETRY_PROGRAM_NV, core::min_(verticesOut, Driver->MaxGeometryVerticesOut));\r
197 #endif\r
198         }\r
199 #endif\r
200 \r
201         if (!linkProgram())\r
202                 return;\r
203 \r
204         // register myself as new material\r
205         outMaterialTypeNr = Driver->addMaterialRenderer(this);\r
206 }\r
207 \r
208 \r
209 bool COpenGLSLMaterialRenderer::OnRender(IMaterialRendererServices* service,\r
210                                         E_VERTEX_TYPE vtxtype)\r
211 {\r
212         // call callback to set shader constants\r
213         if (CallBack && (Program||Program2))\r
214                 CallBack->OnSetConstants(this, UserData);\r
215 \r
216         return true;\r
217 }\r
218 \r
219 \r
220 void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,\r
221                                 const video::SMaterial& lastMaterial,\r
222                                 bool resetAllRenderstates,\r
223                                 video::IMaterialRendererServices* services)\r
224 {\r
225         if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_ENABLE)\r
226                 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE_TO_DISABLE);\r
227         else\r
228                 Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE);\r
229 \r
230         COpenGLCacheHandler* cacheHandler = Driver->getCacheHandler();\r
231 \r
232         if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)\r
233         {\r
234                 if (Program2)\r
235                         Driver->irrGlUseProgram(Program2);\r
236                 else if (Program)\r
237                         Driver->extGlUseProgramObject(Program);\r
238         }\r
239 \r
240         Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);\r
241 \r
242         if (Alpha)\r
243         {\r
244                 cacheHandler->setBlend(true);\r
245                 cacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r
246         }\r
247         else if (FixedBlending)\r
248         {\r
249                 cacheHandler->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);\r
250                 cacheHandler->setBlend(true);\r
251         }\r
252         else if (Blending)\r
253         {\r
254                 E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;\r
255                 E_MODULATE_FUNC modulate;\r
256                 u32 alphaSource;\r
257                 unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);\r
258 \r
259                 if (Driver->queryFeature(EVDF_BLEND_SEPARATE))\r
260         {\r
261                         cacheHandler->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),\r
262                 Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));\r
263         }\r
264         else\r
265         {\r
266                         cacheHandler->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));\r
267         }\r
268 \r
269                 cacheHandler->setBlend(true);\r
270         }\r
271         else if (AlphaTest)\r
272         {\r
273                 cacheHandler->setAlphaTest(true);\r
274                 cacheHandler->setAlphaFunc(GL_GREATER, 0.5f);\r
275         }\r
276 \r
277         if (CallBack)\r
278                 CallBack->OnSetMaterial(material);\r
279 }\r
280 \r
281 \r
282 void COpenGLSLMaterialRenderer::OnUnsetMaterial()\r
283 {\r
284         if (Program)\r
285                 Driver->extGlUseProgramObject(0);\r
286         if (Program2)\r
287                 Driver->irrGlUseProgram(0);\r
288 \r
289         COpenGLCacheHandler* cacheHandler = Driver->getCacheHandler();\r
290         if (Alpha || FixedBlending || Blending)\r
291         {\r
292                 cacheHandler->setBlend(false);\r
293         }\r
294         else if (AlphaTest)\r
295         {\r
296                 cacheHandler->setAlphaTest(false);\r
297         }\r
298 }\r
299 \r
300 \r
301 //! Returns if the material is transparent.\r
302 bool COpenGLSLMaterialRenderer::isTransparent() const\r
303 {\r
304         return (Alpha || Blending || FixedBlending);\r
305 }\r
306 \r
307 \r
308 bool COpenGLSLMaterialRenderer::createProgram()\r
309 {\r
310         if (Driver->Version>=200)\r
311                 Program2 = Driver->extGlCreateProgram();\r
312         else\r
313                 Program = Driver->extGlCreateProgramObject();\r
314         return true;\r
315 }\r
316 \r
317 \r
318 bool COpenGLSLMaterialRenderer::createShader(GLenum shaderType, const char* shader)\r
319 {\r
320         if (Program2)\r
321         {\r
322                 GLuint shaderHandle = Driver->extGlCreateShader(shaderType);\r
323                 Driver->extGlShaderSource(shaderHandle, 1, &shader, NULL);\r
324                 Driver->extGlCompileShader(shaderHandle);\r
325 \r
326                 GLint status = 0;\r
327 \r
328 #ifdef GL_VERSION_2_0\r
329                 Driver->extGlGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &status);\r
330 #endif\r
331 \r
332                 if (status != GL_TRUE)\r
333                 {\r
334                         core::stringc typeInfo("shaderType: ");\r
335                         typeInfo += core::stringc((unsigned long)shaderType);\r
336                         os::Printer::log("GLSL (> 2.x) shader failed to compile", typeInfo.c_str(), ELL_ERROR);\r
337                         // check error message and log it\r
338                         GLint maxLength=0;\r
339                         GLint length;\r
340 #ifdef GL_VERSION_2_0\r
341                         Driver->extGlGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH,\r
342                                         &maxLength);\r
343 #endif\r
344                         if (maxLength)\r
345                         {\r
346                                 GLchar *infoLog = new GLchar[maxLength];\r
347                                 Driver->extGlGetShaderInfoLog(shaderHandle, maxLength, &length, infoLog);\r
348                                 os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);\r
349                                 delete [] infoLog;\r
350                         }\r
351 \r
352                         return false;\r
353                 }\r
354 \r
355                 Driver->extGlAttachShader(Program2, shaderHandle);\r
356         }\r
357         else\r
358         {\r
359                 GLhandleARB shaderHandle = Driver->extGlCreateShaderObject(shaderType);\r
360 \r
361                 Driver->extGlShaderSourceARB(shaderHandle, 1, &shader, NULL);\r
362                 Driver->extGlCompileShaderARB(shaderHandle);\r
363 \r
364                 GLint status = 0;\r
365 \r
366 #ifdef GL_ARB_shader_objects\r
367                 Driver->extGlGetObjectParameteriv(shaderHandle, GL_OBJECT_COMPILE_STATUS_ARB, &status);\r
368 #endif\r
369 \r
370                 if (!status)\r
371                 {\r
372                         core::stringc typeInfo("shaderType: ");\r
373                         typeInfo += core::stringc((unsigned long)shaderType);\r
374                         os::Printer::log("GLSL shader failed to compile", typeInfo.c_str(), ELL_ERROR);\r
375                         // check error message and log it\r
376                         GLint maxLength=0;\r
377                         GLsizei length;\r
378 #ifdef GL_ARB_shader_objects\r
379                         Driver->extGlGetObjectParameteriv(shaderHandle,\r
380                                         GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength);\r
381 #endif\r
382                         if (maxLength)\r
383                         {\r
384                                 GLcharARB *infoLog = new GLcharARB[maxLength];\r
385                                 Driver->extGlGetInfoLog(shaderHandle, maxLength, &length, infoLog);\r
386                                 os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);\r
387                                 delete [] infoLog;\r
388                         }\r
389 \r
390                         return false;\r
391                 }\r
392 \r
393                 Driver->extGlAttachObject(Program, shaderHandle);\r
394         }\r
395         return true;\r
396 }\r
397 \r
398 \r
399 bool COpenGLSLMaterialRenderer::linkProgram()\r
400 {\r
401         if (Program2)\r
402         {\r
403                 Driver->extGlLinkProgram(Program2);\r
404 \r
405                 GLint status = 0;\r
406 \r
407 #ifdef GL_VERSION_2_0\r
408                 Driver->extGlGetProgramiv(Program2, GL_LINK_STATUS, &status);\r
409 #endif\r
410 \r
411                 if (!status)\r
412                 {\r
413                         os::Printer::log("GLSL (> 2.x) shader program failed to link", ELL_ERROR);\r
414                         // check error message and log it\r
415                         GLint maxLength=0;\r
416                         GLsizei length;\r
417 #ifdef GL_VERSION_2_0\r
418                         Driver->extGlGetProgramiv(Program2, GL_INFO_LOG_LENGTH, &maxLength);\r
419 #endif\r
420                         if (maxLength)\r
421                         {\r
422                                 GLchar *infoLog = new GLchar[maxLength];\r
423                                 Driver->extGlGetProgramInfoLog(Program2, maxLength, &length, infoLog);\r
424                                 os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);\r
425                                 delete [] infoLog;\r
426                         }\r
427 \r
428                         return false;\r
429                 }\r
430 \r
431                 // get uniforms information\r
432 \r
433                 GLint num = 0;\r
434 #ifdef GL_VERSION_2_0\r
435                 Driver->extGlGetProgramiv(Program2, GL_ACTIVE_UNIFORMS, &num);\r
436 #endif\r
437 \r
438                 if (num == 0)\r
439                 {\r
440                         // no uniforms\r
441                         return true;\r
442                 }\r
443 \r
444                 GLint maxlen = 0;\r
445 #ifdef GL_VERSION_2_0\r
446                 Driver->extGlGetProgramiv(Program2, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxlen);\r
447 #endif\r
448 \r
449                 if (maxlen == 0)\r
450                 {\r
451                         os::Printer::log("GLSL (> 2.x): failed to retrieve uniform information", ELL_ERROR);\r
452                         return false;\r
453                 }\r
454 \r
455                 // seems that some implementations use an extra null terminator\r
456                 ++maxlen;\r
457                 c8 *buf = new c8[maxlen];\r
458 \r
459                 UniformInfo.clear();\r
460                 UniformInfo.reallocate(num);\r
461 \r
462                 for (GLint i=0; i < num; ++i)\r
463                 {\r
464                         SUniformInfo ui;\r
465                         memset(buf, 0, maxlen);\r
466 \r
467                         GLint size;\r
468                         Driver->extGlGetActiveUniform(Program2, i, maxlen, 0, &size, &ui.type, reinterpret_cast<GLchar*>(buf));\r
469                         ui.name = buf;\r
470                         ui.location = Driver->extGlGetUniformLocation(Program2, buf);\r
471 \r
472                         UniformInfo.push_back(ui);\r
473                 }\r
474 \r
475                 delete [] buf;\r
476         }\r
477         else\r
478         {\r
479                 Driver->extGlLinkProgramARB(Program);\r
480 \r
481                 GLint status = 0;\r
482 \r
483 #ifdef GL_ARB_shader_objects\r
484                 Driver->extGlGetObjectParameteriv(Program, GL_OBJECT_LINK_STATUS_ARB, &status);\r
485 #endif\r
486 \r
487                 if (!status)\r
488                 {\r
489                         os::Printer::log("GLSL shader program failed to link", ELL_ERROR);\r
490                         // check error message and log it\r
491                         GLint maxLength=0;\r
492                         GLsizei length;\r
493 #ifdef GL_ARB_shader_objects\r
494                         Driver->extGlGetObjectParameteriv(Program,\r
495                                         GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength);\r
496 #endif\r
497                         if (maxLength)\r
498                         {\r
499                                 GLcharARB *infoLog = new GLcharARB[maxLength];\r
500                                 Driver->extGlGetInfoLog(Program, maxLength, &length, infoLog);\r
501                                 os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);\r
502                                 delete [] infoLog;\r
503                         }\r
504 \r
505                         return false;\r
506                 }\r
507 \r
508                 // get uniforms information\r
509 \r
510                 GLint num = 0;\r
511         #ifdef GL_ARB_shader_objects\r
512                 Driver->extGlGetObjectParameteriv(Program, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &num);\r
513         #endif\r
514 \r
515                 if (num == 0)\r
516                 {\r
517                         // no uniforms\r
518                         return true;\r
519                 }\r
520 \r
521                 GLint maxlen = 0;\r
522         #ifdef GL_ARB_shader_objects\r
523                 Driver->extGlGetObjectParameteriv(Program, GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, &maxlen);\r
524         #endif\r
525 \r
526                 if (maxlen == 0)\r
527                 {\r
528                         os::Printer::log("GLSL: failed to retrieve uniform information", ELL_ERROR);\r
529                         return false;\r
530                 }\r
531 \r
532                 // seems that some implementations use an extra null terminator\r
533                 ++maxlen;\r
534                 c8 *buf = new c8[maxlen];\r
535 \r
536                 UniformInfo.clear();\r
537                 UniformInfo.reallocate(num);\r
538 \r
539                 for (int i=0; i < num; ++i)\r
540                 {\r
541                         SUniformInfo ui;\r
542                         memset(buf, 0, maxlen);\r
543 \r
544                         GLint size;\r
545                         Driver->extGlGetActiveUniformARB(Program, i, maxlen, 0, &size, &ui.type, reinterpret_cast<GLcharARB*>(buf));\r
546                         ui.name = buf;\r
547                         ui.location = Driver->extGlGetUniformLocationARB(Program, buf);\r
548 \r
549                         UniformInfo.push_back(ui);\r
550                 }\r
551 \r
552                 delete [] buf;\r
553         }\r
554 \r
555         return true;\r
556 }\r
557 \r
558 \r
559 void COpenGLSLMaterialRenderer::setBasicRenderStates(const SMaterial& material,\r
560                                                 const SMaterial& lastMaterial,\r
561                                                 bool resetAllRenderstates)\r
562 {\r
563         // forward\r
564         Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);\r
565 }\r
566 \r
567 s32 COpenGLSLMaterialRenderer::getVertexShaderConstantID(const c8* name)\r
568 {\r
569         return getPixelShaderConstantID(name);\r
570 }\r
571 \r
572 s32 COpenGLSLMaterialRenderer::getPixelShaderConstantID(const c8* name)\r
573 {\r
574         for (u32 i = 0; i < UniformInfo.size(); ++i)\r
575         {\r
576                 if (UniformInfo[i].name == name)\r
577                         return i;\r
578         }\r
579 \r
580         return -1;\r
581 }\r
582 \r
583 void COpenGLSLMaterialRenderer::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)\r
584 {\r
585         os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING);\r
586 }\r
587 \r
588 void COpenGLSLMaterialRenderer::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)\r
589 {\r
590         os::Printer::log("Cannot set constant, use high level shader call.", ELL_WARNING);\r
591 }\r
592 \r
593 bool COpenGLSLMaterialRenderer::setVertexShaderConstant(s32 index, const f32* floats, int count)\r
594 {\r
595         return setPixelShaderConstant(index, floats, count);\r
596 }\r
597 \r
598 bool COpenGLSLMaterialRenderer::setVertexShaderConstant(s32 index, const s32* ints, int count)\r
599 {\r
600         return setPixelShaderConstant(index, ints, count);\r
601 }\r
602 \r
603 bool COpenGLSLMaterialRenderer::setVertexShaderConstant(s32 index, const u32* ints, int count)\r
604 {\r
605         return setPixelShaderConstant(index, ints, count);\r
606 }\r
607 \r
608 bool COpenGLSLMaterialRenderer::setPixelShaderConstant(s32 index, const f32* floats, int count)\r
609 {\r
610         if(index < 0 || UniformInfo[index].location < 0)\r
611                 return false;\r
612 \r
613         bool status = true;\r
614 \r
615         switch (UniformInfo[index].type)\r
616         {\r
617                 case GL_FLOAT:\r
618                         Driver->extGlUniform1fv(UniformInfo[index].location, count, floats);\r
619                         break;\r
620                 case GL_FLOAT_VEC2:\r
621                         Driver->extGlUniform2fv(UniformInfo[index].location, count/2, floats);\r
622                         break;\r
623                 case GL_FLOAT_VEC3:\r
624                         Driver->extGlUniform3fv(UniformInfo[index].location, count/3, floats);\r
625                         break;\r
626                 case GL_FLOAT_VEC4:\r
627                         Driver->extGlUniform4fv(UniformInfo[index].location, count/4, floats);\r
628                         break;\r
629                 case GL_FLOAT_MAT2:\r
630                         Driver->extGlUniformMatrix2fv(UniformInfo[index].location, count/4, false, floats);\r
631                         break;\r
632                 case GL_FLOAT_MAT2x3:\r
633                         Driver->extGlUniformMatrix2x3fv(UniformInfo[index].location, count/6, false, floats);\r
634                         break;\r
635                 case GL_FLOAT_MAT2x4:\r
636                         Driver->extGlUniformMatrix2x4fv(UniformInfo[index].location, count/8, false, floats);\r
637                         break;\r
638                 case GL_FLOAT_MAT3x2:\r
639                         Driver->extGlUniformMatrix3x2fv(UniformInfo[index].location, count/6, false, floats);\r
640                         break;\r
641                 case GL_FLOAT_MAT3:\r
642                         Driver->extGlUniformMatrix3fv(UniformInfo[index].location, count/9, false, floats);\r
643                         break;\r
644                 case GL_FLOAT_MAT3x4:\r
645                         Driver->extGlUniformMatrix3x4fv(UniformInfo[index].location, count/12, false, floats);\r
646                         break;\r
647                 case GL_FLOAT_MAT4x2:\r
648                         Driver->extGlUniformMatrix4x2fv(UniformInfo[index].location, count/8, false, floats);\r
649                         break;\r
650                 case GL_FLOAT_MAT4x3:\r
651                         Driver->extGlUniformMatrix4x3fv(UniformInfo[index].location, count/12, false, floats);\r
652                         break;\r
653                 case GL_FLOAT_MAT4:\r
654                         Driver->extGlUniformMatrix4fv(UniformInfo[index].location, count/16, false, floats);\r
655                         break;\r
656                 case GL_SAMPLER_1D:\r
657                 case GL_SAMPLER_2D:\r
658                 case GL_SAMPLER_3D:\r
659                 case GL_SAMPLER_CUBE:\r
660                 case GL_SAMPLER_1D_SHADOW:\r
661                 case GL_SAMPLER_2D_SHADOW:\r
662                         {\r
663                                 if(floats)\r
664                                 {\r
665                                         const GLint id = static_cast<GLint>(*floats);\r
666                                         Driver->extGlUniform1iv(UniformInfo[index].location, 1, &id);\r
667                                 }\r
668                                 else\r
669                                         status = false;\r
670                         }\r
671                         break;\r
672                 default:\r
673                         status = false;\r
674                         break;\r
675         }\r
676         return status;\r
677 }\r
678 \r
679 bool COpenGLSLMaterialRenderer::setPixelShaderConstant(s32 index, const s32* ints, int count)\r
680 {\r
681         if(index < 0 || UniformInfo[index].location < 0)\r
682                 return false;\r
683 \r
684         bool status = true;\r
685 \r
686         switch (UniformInfo[index].type)\r
687         {\r
688                 case GL_INT:\r
689                 case GL_BOOL:\r
690                         Driver->extGlUniform1iv(UniformInfo[index].location, count, reinterpret_cast<const GLint*>(ints));\r
691                         break;\r
692                 case GL_INT_VEC2:\r
693                 case GL_BOOL_VEC2:\r
694                         Driver->extGlUniform2iv(UniformInfo[index].location, count/2, reinterpret_cast<const GLint*>(ints));\r
695                         break;\r
696                 case GL_INT_VEC3:\r
697                 case GL_BOOL_VEC3:\r
698                         Driver->extGlUniform3iv(UniformInfo[index].location, count/3, reinterpret_cast<const GLint*>(ints));\r
699                         break;\r
700                 case GL_INT_VEC4:\r
701                 case GL_BOOL_VEC4:\r
702                         Driver->extGlUniform4iv(UniformInfo[index].location, count/4, reinterpret_cast<const GLint*>(ints));\r
703                         break;\r
704                 case GL_SAMPLER_1D:\r
705                 case GL_SAMPLER_2D:\r
706                 case GL_SAMPLER_3D:\r
707                 case GL_SAMPLER_CUBE:\r
708                 case GL_SAMPLER_1D_SHADOW:\r
709                 case GL_SAMPLER_2D_SHADOW:\r
710                         Driver->extGlUniform1iv(UniformInfo[index].location, 1, reinterpret_cast<const GLint*>(ints));\r
711                         break;\r
712                 default:\r
713                         status = false;\r
714                         break;\r
715         }\r
716         return status;\r
717 }\r
718 \r
719 bool COpenGLSLMaterialRenderer::setPixelShaderConstant(s32 index, const u32* ints, int count)\r
720 {\r
721         if(index < 0 || UniformInfo[index].location < 0)\r
722                 return false;\r
723 \r
724         bool status = true;\r
725 \r
726         switch (UniformInfo[index].type)\r
727         {\r
728                 case GL_UNSIGNED_INT:\r
729                         Driver->extGlUniform1uiv(UniformInfo[index].location, count, reinterpret_cast<const GLuint*>(ints));\r
730                         break;\r
731 #if defined(GL_VERSION_3_0)\r
732                 case GL_UNSIGNED_INT_VEC2:\r
733                         Driver->extGlUniform2uiv(UniformInfo[index].location, count/2, reinterpret_cast<const GLuint*>(ints));\r
734                         break;\r
735                 case GL_UNSIGNED_INT_VEC3:\r
736                         Driver->extGlUniform3uiv(UniformInfo[index].location, count/3, reinterpret_cast<const GLuint*>(ints));\r
737                         break;\r
738                 case GL_UNSIGNED_INT_VEC4:\r
739                         Driver->extGlUniform4uiv(UniformInfo[index].location, count/4, reinterpret_cast<const GLuint*>(ints));\r
740                         break;\r
741 #endif\r
742                 default:\r
743                         status = false;\r
744                         break;\r
745         }\r
746         return status;\r
747 }\r
748 \r
749 IVideoDriver* COpenGLSLMaterialRenderer::getVideoDriver()\r
750 {\r
751         return Driver;\r
752 }\r
753 \r
754 } // end namespace video\r
755 } // end namespace irr\r
756 \r
757 \r
758 #endif\r
759 \r