3 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
5 # include "gl_core_3_3.h"
7 # include "gl_compat_4_4.h"
24 int uLightsDiffuse[8];
25 int uLightsAmbient[8];
26 int uLightsSpecular[8];
36 void shader_LoadMatrixf(MatrixMode mode, float * m)
39 glUniformMatrix4fv(uTextureMatrix, 1, GL_FALSE, m);
40 else if(mode == projection)
41 glUniformMatrix4fv(uPrjMatrix, 1, GL_FALSE, m);
43 glUniformMatrix4fv(uMVMatrix, 1, GL_FALSE, m);
46 void shader_setGlobalAmbient(float r, float g, float b, float a)
48 glUniform3f(uGlobalAmbient, r, g, b);
51 void shader_color(float r, float g, float b, float a)
53 glUniform4f(uColor, r, g, b, a);
56 void shader_lighting(bool on)
58 glUniform1ui(uLightingOn, on);
61 void shader_texturing(bool on)
63 glUniform1ui(uTexturingOn, on);
66 void shader_setMaterial(Material material, bool perVertexColor)
68 glUniform1ui(uPerVertexColor, perVertexColor);
69 glUniform1ui(uMatTwoSided, !material.flags.singleSideLight);
70 glUniform3f(uMatDiffuse, material.diffuse.r, material.diffuse.g, material.diffuse.b);
71 glUniform3f(uMatAmbient, material.ambient.r, material.ambient.g, material.ambient.b);
72 glUniform3f(uMatSpecular, material.specular.r, material.specular.g, material.specular.b);
73 glUniform3f(uMatEmissive, material.emissive.r, material.emissive.g, material.emissive.b);
74 glUniform1f(uMatPower, material.power);
75 glUniform1f(uMatOpacity, material.opacity);
78 void shader_setLight(Display display, uint id, Light light)
82 Object lightObject = light.lightObject;
83 float multiplier = light.multiplier;
85 glUniform1i(uLightsOn[id], 1);
87 if(!multiplier) multiplier = 1.0f;
89 glUniform3f(uLightsDiffuse[id],
90 light.diffuse.r * multiplier,
91 light.diffuse.g * multiplier,
92 light.diffuse.b * multiplier);
94 glUniform3f(uLightsAmbient[id],
95 light.ambient.r * multiplier,
96 light.ambient.g * multiplier,
97 light.ambient.b * multiplier);
99 glUniform3f(uLightsSpecular[id],
100 light.specular.r * multiplier,
101 light.specular.g * multiplier,
102 light.specular.b * multiplier);
107 Vector3D positionVector;
110 if(lightObject.flags.root || !lightObject.parent)
112 positionVector = lightObject.transform.position;
113 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
117 positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
118 if(display.display3D.camera)
119 positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
125 if(!light.direction.x && !light.direction.y && !light.direction.z)
127 Vector3Df vector { 0,0,-1 };
129 mat.RotationQuaternion(light.orientation);
130 positionVector.MultMatrixf(vector, mat);
134 positionVector = light.direction;
139 position[0] = (float)positionVector.x;
140 position[1] = (float)positionVector.y;
141 position[2] = (float)positionVector.z;
143 glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
145 if(light.flags.attenuation)
147 glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
148 glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
149 glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
156 float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
157 // Figure out exponent out of the hot spot
158 exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
160 glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
161 glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
162 glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
169 Vector3Df vector { 0,0,-1 };
170 Vector3Df vectorI { 0,0, 1 };
171 Vector3Df direction, directionI;
174 mat.RotationQuaternion(light.orientation);
175 direction.MultMatrix(vector, mat);
176 directionI.MultMatrix(vectorI, mat);
178 if(!display.display3D || !display.display3D.camera)
180 // Light in View Space (SetLight before setting camera)
181 l.Normalize(direction);
184 li.Normalize(directionI);
189 // Light in World Space (SetLight after setting camera)
190 Matrix m = display.display3D.camera.viewMatrix;
192 vector.MultMatrix(direction, m);
195 vectorI.MultMatrix(directionI, m);
196 li.Normalize(vectorI);
198 glUniform4f(uLightsPos[id], l.x, l.y, l.z, 0);
199 glUniform4f(uLightsPosI[id], li.x, li.y, li.z, 0);
203 glUniform1i(uLightsOn[id], 0);
206 void loadShaders(const String vertexShaderFile, const String fragmentShaderFile)
208 static char compileLog[65536];
209 #define BUFFER_SIZE 4096
210 int bufferLen = BUFFER_SIZE;
211 char * buffer = new byte[BUFFER_SIZE];
212 int vsLen = 0, fsLen = 0;
213 char * vsSource = null;
214 char * psSource = null;
215 File vf = FileOpen(vertexShaderFile, read);
216 File ff = FileOpen(fragmentShaderFile, read);
222 int count = vf.Read(buffer + vsLen, 1, BUFFER_SIZE);
224 if(count == BUFFER_SIZE && bufferLen < vsLen + BUFFER_SIZE)
226 bufferLen = vsLen + BUFFER_SIZE;
227 buffer = renew buffer byte[bufferLen];
230 vsSource = new byte[vsLen+1];
231 memcpy(vsSource, buffer, vsLen);
239 int count = ff.Read(buffer + fsLen, 1, BUFFER_SIZE);
241 if(count == BUFFER_SIZE && bufferLen < fsLen + BUFFER_SIZE)
243 bufferLen = fsLen + BUFFER_SIZE;
244 buffer = renew buffer byte[bufferLen];
247 psSource = new byte[fsLen+1];
248 memcpy(psSource, buffer, fsLen);
254 printf("We've got OpenGL Version %s\n\n", (char *)glGetString(GL_VERSION));
255 printf("We've got Shading Language Version %s\n\n", (char *)glGetString(GL_SHADING_LANGUAGE_VERSION));
258 int program = glCreateProgram();
259 int vShader = glCreateShader(GL_VERTEX_SHADER);
260 int fShader = glCreateShader(GL_FRAGMENT_SHADER);
261 const char * vptr[1] = { vsSource };
262 const char * fptr[1] = { psSource };
265 glShaderSource(vShader, 1, vptr, &vsLen);
266 glShaderSource(fShader, 1, fptr, &fsLen);
270 glCompileShader(vShader);
271 glGetShaderInfoLog(vShader, sizeof(compileLog), null, compileLog);
272 puts("Vertex Shader Compile Log:");
273 puts("--------------------------");
274 puts(compileLog[0] ? compileLog : "Success.");
276 glCompileShader(fShader);
277 glGetShaderInfoLog(fShader, sizeof(compileLog), null, compileLog);
280 puts("Fragment Shader Compile Log:");
281 puts("--------------------------");
282 puts(compileLog[0] ? compileLog : "Success.");
284 glAttachShader(program, vShader);
285 glAttachShader(program, fShader);
287 glBindAttribLocation(program, GLBufferContents::vertex, "vertex");
288 glBindAttribLocation(program, GLBufferContents::texCoord, "texCoord");
289 glBindAttribLocation(program, GLBufferContents::color, "color");
290 glBindAttribLocation(program, GLBufferContents::normal, "normal");
291 glBindFragDataLocation(program, 0, "fragColor");
293 glLinkProgram(program);
294 glValidateProgram(program);
296 glGetProgramInfoLog(program, sizeof(compileLog), null, compileLog);
299 puts("Shader Program Log:");
300 puts("--------------------------");
301 puts(compileLog[0] ? compileLog : "Success.");
303 uPrjMatrix = glGetUniformLocation(program, "projection_matrix");
304 uMVMatrix = glGetUniformLocation(program, "modelview_matrix");
305 uTextureMatrix = glGetUniformLocation(program, "texture_matrix");
306 uColor = glGetUniformLocation(program, "current_color");
307 uTexturingOn = glGetUniformLocation(program, "texturingOn");
308 uLightingOn = glGetUniformLocation(program, "lightingOn");
309 uGlobalAmbient = glGetUniformLocation(program, "globalAmbient");
310 uPerVertexColor = glGetUniformLocation(program, "perVertexColor");
311 uMatDiffuse = glGetUniformLocation(program, "matDiffuse");
312 uMatAmbient = glGetUniformLocation(program, "matAmbient");
313 uMatSpecular = glGetUniformLocation(program, "matSpecular");
314 uMatEmissive = glGetUniformLocation(program, "matEmissive");
315 uMatPower = glGetUniformLocation(program, "matPower");
316 uMatOpacity = glGetUniformLocation(program, "matOpacity");
317 uMatTwoSided = glGetUniformLocation(program, "matTwoSided");
319 for(i = 0; i < 8; i++)
323 sprintf(name, "lightsOn[%d]", i);
324 uLightsOn [i] = glGetUniformLocation(program, name);
326 sprintf(name, "lightsPos[%d]", i);
327 uLightsPos[i] = glGetUniformLocation(program, name);
329 sprintf(name, "lightsPosI[%d]", i);
330 uLightsPosI[i] = glGetUniformLocation(program, name);
332 sprintf(name, "lightsDiffuse[%d]", i);
333 uLightsDiffuse[i] = glGetUniformLocation(program, name);
335 sprintf(name, "lightsAmbient[%d]", i);
336 uLightsAmbient[i] = glGetUniformLocation(program, name);
338 sprintf(name, "lightsSpecular[%d]", i);
339 uLightsSpecular[i] = glGetUniformLocation(program, name);
342 shadingProgram = program;
344 glUseProgram(shadingProgram);
346 // Initialize uniforms to defaults
347 glmsMatrixMode(texture);
349 glmsMatrixMode(projection);
351 glmsMatrixMode(modelView);
353 shader_color(1.0, 1.0, 1.0, 1.0);