diff options
Diffstat (limited to 'libraries/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.cpp')
-rw-r--r-- | libraries/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.cpp | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.cpp b/libraries/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.cpp new file mode 100644 index 0000000..3550dba --- /dev/null +++ b/libraries/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.cpp | |||
@@ -0,0 +1,244 @@ | |||
1 | // Copyright (C) 2012-2012 Patryk Nadrowski | ||
2 | // This file is part of the "Irrlicht Engine". | ||
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | ||
4 | |||
5 | #include "IrrCompileConfig.h" | ||
6 | #if defined(_IRR_COMPILE_WITH_OPENGL_) && defined(_IRR_COMPILE_WITH_CG_) | ||
7 | |||
8 | #include "COpenGLCgMaterialRenderer.h" | ||
9 | #include "COpenGLDriver.h" | ||
10 | #include "COpenGLTexture.h" | ||
11 | |||
12 | namespace irr | ||
13 | { | ||
14 | namespace video | ||
15 | { | ||
16 | |||
17 | COpenGLCgUniformSampler2D::COpenGLCgUniformSampler2D(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) | ||
18 | { | ||
19 | Type = CG_SAMPLER2D; | ||
20 | } | ||
21 | |||
22 | void COpenGLCgUniformSampler2D::update(const void* data, const SMaterial& material) const | ||
23 | { | ||
24 | s32* Data = (s32*)data; | ||
25 | s32 LayerID = *Data; | ||
26 | |||
27 | if (material.TextureLayer[LayerID].Texture) | ||
28 | { | ||
29 | int TextureID = reinterpret_cast<COpenGLTexture*>(material.TextureLayer[LayerID].Texture)->getOpenGLTextureName(); | ||
30 | |||
31 | cgGLSetTextureParameter(Parameter, TextureID); | ||
32 | cgGLEnableTextureParameter(Parameter); | ||
33 | } | ||
34 | } | ||
35 | |||
36 | COpenGLCgMaterialRenderer::COpenGLCgMaterialRenderer(COpenGLDriver* driver, s32& materialType, | ||
37 | const c8* vertexProgram, const c8* vertexEntry, E_VERTEX_SHADER_TYPE vertexProfile, | ||
38 | const c8* fragmentProgram, const c8* fragmentEntry, E_PIXEL_SHADER_TYPE fragmentProfile, | ||
39 | const c8* geometryProgram, const c8* geometryEntry, E_GEOMETRY_SHADER_TYPE geometryProfile, | ||
40 | scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, u32 vertices, | ||
41 | IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) : | ||
42 | Driver(driver), CCgMaterialRenderer(callback, baseMaterial, userData) | ||
43 | { | ||
44 | #ifdef _DEBUG | ||
45 | setDebugName("COpenGLCgMaterialRenderer"); | ||
46 | #endif | ||
47 | |||
48 | init(materialType, vertexProgram, vertexEntry, vertexProfile, fragmentProgram, fragmentEntry, fragmentProfile, | ||
49 | geometryProgram, geometryEntry, geometryProfile, inType, outType, vertices); | ||
50 | } | ||
51 | |||
52 | COpenGLCgMaterialRenderer::~COpenGLCgMaterialRenderer() | ||
53 | { | ||
54 | if (VertexProgram) | ||
55 | { | ||
56 | cgGLUnloadProgram(VertexProgram); | ||
57 | cgDestroyProgram(VertexProgram); | ||
58 | } | ||
59 | if (FragmentProgram) | ||
60 | { | ||
61 | cgGLUnloadProgram(FragmentProgram); | ||
62 | cgDestroyProgram(FragmentProgram); | ||
63 | } | ||
64 | if (GeometryProgram) | ||
65 | { | ||
66 | cgGLUnloadProgram(GeometryProgram); | ||
67 | cgDestroyProgram(GeometryProgram); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | void COpenGLCgMaterialRenderer::OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates, IMaterialRendererServices* services) | ||
72 | { | ||
73 | Material = material; | ||
74 | |||
75 | if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) | ||
76 | { | ||
77 | if (VertexProgram) | ||
78 | { | ||
79 | cgGLEnableProfile(VertexProfile); | ||
80 | cgGLBindProgram(VertexProgram); | ||
81 | } | ||
82 | |||
83 | if (FragmentProgram) | ||
84 | { | ||
85 | cgGLEnableProfile(FragmentProfile); | ||
86 | cgGLBindProgram(FragmentProgram); | ||
87 | } | ||
88 | |||
89 | if (GeometryProgram) | ||
90 | { | ||
91 | cgGLEnableProfile(GeometryProfile); | ||
92 | cgGLBindProgram(GeometryProgram); | ||
93 | } | ||
94 | |||
95 | if (BaseMaterial) | ||
96 | BaseMaterial->OnSetMaterial(material, material, true, this); | ||
97 | } | ||
98 | |||
99 | if (CallBack) | ||
100 | CallBack->OnSetMaterial(material); | ||
101 | |||
102 | for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) | ||
103 | Driver->setActiveTexture(i, material.getTexture(i)); | ||
104 | |||
105 | Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); | ||
106 | } | ||
107 | |||
108 | bool COpenGLCgMaterialRenderer::OnRender(IMaterialRendererServices* services, E_VERTEX_TYPE vtxtype) | ||
109 | { | ||
110 | if (CallBack && (VertexProgram || FragmentProgram || GeometryProgram)) | ||
111 | CallBack->OnSetConstants(this, UserData); | ||
112 | |||
113 | return true; | ||
114 | } | ||
115 | |||
116 | void COpenGLCgMaterialRenderer::OnUnsetMaterial() | ||
117 | { | ||
118 | if (VertexProgram) | ||
119 | { | ||
120 | cgGLUnbindProgram(VertexProfile); | ||
121 | cgGLDisableProfile(VertexProfile); | ||
122 | } | ||
123 | if (FragmentProgram) | ||
124 | { | ||
125 | cgGLUnbindProgram(FragmentProfile); | ||
126 | cgGLDisableProfile(FragmentProfile); | ||
127 | } | ||
128 | if (GeometryProgram) | ||
129 | { | ||
130 | cgGLUnbindProgram(GeometryProfile); | ||
131 | cgGLDisableProfile(GeometryProfile); | ||
132 | } | ||
133 | |||
134 | if (BaseMaterial) | ||
135 | BaseMaterial->OnUnsetMaterial(); | ||
136 | |||
137 | Material = IdentityMaterial;; | ||
138 | } | ||
139 | |||
140 | void COpenGLCgMaterialRenderer::setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) | ||
141 | { | ||
142 | Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); | ||
143 | } | ||
144 | |||
145 | IVideoDriver* COpenGLCgMaterialRenderer::getVideoDriver() | ||
146 | { | ||
147 | return Driver; | ||
148 | } | ||
149 | |||
150 | void COpenGLCgMaterialRenderer::init(s32& materialType, | ||
151 | const c8* vertexProgram, const c8* vertexEntry, E_VERTEX_SHADER_TYPE vertexProfile, | ||
152 | const c8* fragmentProgram, const c8* fragmentEntry, E_PIXEL_SHADER_TYPE fragmentProfile, | ||
153 | const c8* geometryProgram, const c8* geometryEntry, E_GEOMETRY_SHADER_TYPE geometryProfile, | ||
154 | scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, u32 vertices) | ||
155 | { | ||
156 | bool Status = true; | ||
157 | CGerror Error = CG_NO_ERROR; | ||
158 | materialType = -1; | ||
159 | |||
160 | // TODO: add profile selection | ||
161 | |||
162 | if (vertexProgram) | ||
163 | { | ||
164 | VertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); | ||
165 | |||
166 | if (VertexProfile) | ||
167 | VertexProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, vertexProgram, VertexProfile, vertexEntry, 0); | ||
168 | |||
169 | if (!VertexProgram) | ||
170 | { | ||
171 | Error = cgGetError(); | ||
172 | os::Printer::log("Cg vertex program failed to compile:", ELL_ERROR); | ||
173 | os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); | ||
174 | |||
175 | Status = false; | ||
176 | } | ||
177 | else | ||
178 | cgGLLoadProgram(VertexProgram); | ||
179 | } | ||
180 | |||
181 | if (fragmentProgram) | ||
182 | { | ||
183 | FragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); | ||
184 | |||
185 | if (FragmentProfile) | ||
186 | FragmentProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, fragmentProgram, FragmentProfile, fragmentEntry, 0); | ||
187 | |||
188 | if (!FragmentProgram) | ||
189 | { | ||
190 | Error = cgGetError(); | ||
191 | os::Printer::log("Cg fragment program failed to compile:", ELL_ERROR); | ||
192 | os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); | ||
193 | |||
194 | Status = false; | ||
195 | } | ||
196 | else | ||
197 | cgGLLoadProgram(FragmentProgram); | ||
198 | } | ||
199 | |||
200 | if (geometryProgram) | ||
201 | { | ||
202 | GeometryProfile = cgGLGetLatestProfile(CG_GL_GEOMETRY); | ||
203 | |||
204 | if (GeometryProfile) | ||
205 | GeometryProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, geometryProgram, GeometryProfile, geometryEntry, 0); | ||
206 | |||
207 | if (!GeometryProgram) | ||
208 | { | ||
209 | Error = cgGetError(); | ||
210 | os::Printer::log("Cg geometry program failed to compile:", ELL_ERROR); | ||
211 | os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); | ||
212 | |||
213 | Status = false; | ||
214 | } | ||
215 | else | ||
216 | cgGLLoadProgram(GeometryProgram); | ||
217 | } | ||
218 | |||
219 | getUniformList(); | ||
220 | |||
221 | // create OpenGL specifics sampler uniforms. | ||
222 | for (unsigned int i = 0; i < UniformInfo.size(); ++i) | ||
223 | { | ||
224 | if (UniformInfo[i]->getType() == CG_SAMPLER2D) | ||
225 | { | ||
226 | bool IsGlobal = true; | ||
227 | |||
228 | if (UniformInfo[i]->getSpace() == CG_PROGRAM) | ||
229 | IsGlobal = false; | ||
230 | |||
231 | CCgUniform* Uniform = new COpenGLCgUniformSampler2D(UniformInfo[i]->getParameter(), IsGlobal); | ||
232 | delete UniformInfo[i]; | ||
233 | UniformInfo[i] = Uniform; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | if (Status) | ||
238 | materialType = Driver->addMaterialRenderer(this); | ||
239 | } | ||
240 | |||
241 | } | ||
242 | } | ||
243 | |||
244 | #endif | ||