diff options
| author | Ray <[email protected]> | 2016-10-16 18:24:13 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2016-10-16 18:24:13 +0200 |
| commit | a9315fc422a3a036891f50f0c2be5059c3db8b31 (patch) | |
| tree | 9f5213dac656079e2163bc5d091200dc837672b8 /src/rlgl.c | |
| parent | 53056f3e7e84e18b8ebfc4a2ab2f7f1fbe7ae36c (diff) | |
| parent | 1c05017548ea21dd1a44c31e9fc80b8700891f11 (diff) | |
| download | raylib-a9315fc422a3a036891f50f0c2be5059c3db8b31.tar.gz raylib-a9315fc422a3a036891f50f0c2be5059c3db8b31.zip | |
Merge pull request #189 from raysan5/develop
Develop branch integration
Diffstat (limited to 'src/rlgl.c')
| -rw-r--r-- | src/rlgl.c | 300 |
1 files changed, 187 insertions, 113 deletions
@@ -337,6 +337,8 @@ static int screenHeight; // Default framebuffer height // Lighting data static Light lights[MAX_LIGHTS]; // Lights pool static int lightsCount = 0; // Enabled lights counter +static int lightsLocs[MAX_LIGHTS][8]; // Lights location points in shader: 8 possible points per light: + // enabled, type, position, target, radius, diffuse, intensity, coneAngle //---------------------------------------------------------------------------------- // Module specific Functions Declaration @@ -362,9 +364,10 @@ static void SetStereoConfig(VrDeviceInfo info); // Set internal projection and modelview matrix depending on eyes tracking data static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView); -static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array +static void GetShaderLightsLocations(Shader shader); // Get shader locations for lights (up to MAX_LIGHTS) +static void SetShaderLightsValues(Shader shader); // Set shader uniform values for lights -static char *ReadTextFile(const char *fileName); // Read chars array from text file +static char *ReadTextFile(const char *fileName); // Read chars array from text file #endif #if defined(RLGL_OCULUS_SUPPORT) @@ -415,14 +418,14 @@ void rlMatrixMode(int mode) } } -void rlFrustum(double left, double right, double bottom, double top, double near, double far) +void rlFrustum(double left, double right, double bottom, double top, double zNear, double zFar) { - glFrustum(left, right, bottom, top, near, far); + glFrustum(left, right, bottom, top, zNear, zFar); } -void rlOrtho(double left, double right, double bottom, double top, double near, double far) +void rlOrtho(double left, double right, double bottom, double top, double zNear, double zFar) { - glOrtho(left, right, bottom, top, near, far); + glOrtho(left, right, bottom, top, zNear, zFar); } void rlPushMatrix(void) { glPushMatrix(); } @@ -705,7 +708,7 @@ void rlVertex3f(float x, float y, float z) case RL_LINES: { // Verify that MAX_LINES_BATCH limit not reached - if (lines.vCounter / 2 < MAX_LINES_BATCH) + if (lines.vCounter/2 < MAX_LINES_BATCH) { lines.vertices[3*lines.vCounter] = x; lines.vertices[3*lines.vCounter + 1] = y; @@ -719,7 +722,7 @@ void rlVertex3f(float x, float y, float z) case RL_TRIANGLES: { // Verify that MAX_TRIANGLES_BATCH limit not reached - if (triangles.vCounter / 3 < MAX_TRIANGLES_BATCH) + if (triangles.vCounter/3 < MAX_TRIANGLES_BATCH) { triangles.vertices[3*triangles.vCounter] = x; triangles.vertices[3*triangles.vCounter + 1] = y; @@ -733,7 +736,7 @@ void rlVertex3f(float x, float y, float z) case RL_QUADS: { // Verify that MAX_QUADS_BATCH limit not reached - if (quads.vCounter / 4 < MAX_QUADS_BATCH) + if (quads.vCounter/4 < MAX_QUADS_BATCH) { quads.vertices[3*quads.vCounter] = x; quads.vertices[3*quads.vCounter + 1] = y; @@ -1056,8 +1059,13 @@ void rlglInit(int width, int height) // We get a list of available extensions and we check for some of them (compressed textures) // NOTE: We don't need to check again supported extensions but we do (GLAD already dealt with that) glGetIntegerv(GL_NUM_EXTENSIONS, &numExt); - const char *extList[numExt]; +#ifdef _MSC_VER + const char **extList = malloc(sizeof(const char *)*numExt); +#else + const char *extList[numExt]; +#endif + for (int i = 0; i < numExt; i++) extList[i] = (char *)glGetStringi(GL_EXTENSIONS, i); #elif defined(GRAPHICS_API_OPENGL_ES2) @@ -1137,6 +1145,10 @@ void rlglInit(int width, int height) if (strcmp(extList[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) texCompASTCSupported = true; } +#ifdef _MSC_VER + free(extList); +#endif + #if defined(GRAPHICS_API_OPENGL_ES2) if (vaoSupported) TraceLog(INFO, "[EXTENSION] VAO extension detected, VAO functions initialized successfully"); else TraceLog(WARNING, "[EXTENSION] VAO extension not found, VAO usage not supported"); @@ -1510,7 +1522,7 @@ RenderTexture2D rlglLoadRenderTexture(int width, int height) target.texture.id = 0; target.texture.width = width; target.texture.height = height; - target.texture.format = UNCOMPRESSED_R8G8B8; + target.texture.format = UNCOMPRESSED_R8G8B8A8; target.texture.mipmaps = 1; target.depth.id = 0; @@ -1527,7 +1539,7 @@ RenderTexture2D rlglLoadRenderTexture(int width, int height) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, 0); #if defined(GRAPHICS_API_OPENGL_33) @@ -1930,9 +1942,14 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) glUseProgram(material.shader.id); // Upload to shader material.colDiffuse - float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 }; - glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse); + glUniform4f(material.shader.colDiffuseLoc, (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255); + // Upload to shader material.colAmbient (if available) + if (material.shader.colAmbientLoc != -1) glUniform4f(material.shader.colAmbientLoc, (float)material.colAmbient.r/255, (float)material.colAmbient.g/255, (float)material.colAmbient.b/255, (float)material.colAmbient.a/255); + + // Upload to shader material.colSpecular (if available) + if (material.shader.colSpecularLoc != -1) glUniform4f(material.shader.colSpecularLoc, (float)material.colSpecular.r/255, (float)material.colSpecular.g/255, (float)material.colSpecular.b/255, (float)material.colSpecular.a/255); + // At this point the modelview matrix just contains the view matrix (camera) // That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix() Matrix matView = modelview; // View matrix (camera) @@ -1941,32 +1958,35 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) // Calculate model-view matrix combining matModel and matView Matrix matModelView = MatrixMultiply(transform, matView); // Transform to camera-space coordinates - // Check if using standard shader to get location points - // NOTE: standard shader specific locations are got at render time to keep Shader struct as simple as possible (with just default shader locations) - if (material.shader.id == standardShader.id) + // If not using default shader, we check for some additional location points + // NOTE: This method is quite inefficient... it's a temporal solution while looking for a better one + if (material.shader.id != defaultShader.id) { - // Transpose and inverse model transformations matrix for fragment normal calculations - Matrix transInvTransform = transform; - MatrixTranspose(&transInvTransform); - MatrixInvert(&transInvTransform); - - // Send model transformations matrix to shader - glUniformMatrix4fv(glGetUniformLocation(material.shader.id, "modelMatrix"), 1, false, MatrixToFloat(transInvTransform)); - - // Send view transformation matrix to shader. View matrix 8, 9 and 10 are view direction vector axis values (target - position) - glUniform3f(glGetUniformLocation(material.shader.id, "viewDir"), matView.m8, matView.m9, matView.m10); - - // Setup shader uniforms for lights - SetShaderLights(material.shader); - - // Upload to shader material.colAmbient - glUniform4f(glGetUniformLocation(material.shader.id, "colAmbient"), (float)material.colAmbient.r/255, (float)material.colAmbient.g/255, (float)material.colAmbient.b/255, (float)material.colAmbient.a/255); - - // Upload to shader material.colSpecular - glUniform4f(glGetUniformLocation(material.shader.id, "colSpecular"), (float)material.colSpecular.r/255, (float)material.colSpecular.g/255, (float)material.colSpecular.b/255, (float)material.colSpecular.a/255); - - // Upload to shader glossiness - glUniform1f(glGetUniformLocation(material.shader.id, "glossiness"), material.glossiness); + // Check if model matrix is located in shader and upload value + int modelMatrixLoc = glGetUniformLocation(material.shader.id, "modelMatrix"); + if (modelMatrixLoc != -1) + { + // Transpose and inverse model transformations matrix for fragment normal calculations + Matrix transInvTransform = transform; + MatrixTranspose(&transInvTransform); + MatrixInvert(&transInvTransform); + + // Send model transformations matrix to shader + glUniformMatrix4fv(modelMatrixLoc, 1, false, MatrixToFloat(transInvTransform)); + } + + // Check if view direction is located in shader and upload value + // NOTE: View matrix values m8, m9 and m10 are view direction vector axis (target - position) + int viewDirLoc = glGetUniformLocation(material.shader.id, "viewDir"); + if (viewDirLoc != -1) glUniform3f(viewDirLoc, matView.m8, matView.m9, matView.m10); + + // Check if glossiness is located in shader and upload value + int glossinessLoc = glGetUniformLocation(material.shader.id, "glossiness"); + if (glossinessLoc != -1) glUniform1f(glossinessLoc, material.glossiness); + + // Set shader lights values for enabled lights + // NOTE: Lights array location points are obtained on shader loading (if available) + if (lightsCount > 0) SetShaderLightsValues(material.shader); } // Set shader textures (diffuse, normal, specular) @@ -2550,11 +2570,13 @@ void DestroyLight(Light light) { if (light != NULL) { + int lightId = light->id; + // Free dynamic memory allocation - free(lights[light->id]); - + free(lights[lightId]); + // Remove *obj from the pointers array - for (int i = light->id; i < lightsCount; i++) + for (int i = lightId; i < lightsCount; i++) { // Resort all the following pointers of the array if ((i + 1) < lightsCount) @@ -2562,7 +2584,6 @@ void DestroyLight(Light light) lights[i] = lights[i + 1]; lights[i]->id = lights[i + 1]->id; } - else free(lights[i]); } // Decrease enabled physic objects count @@ -2689,6 +2710,12 @@ bool IsVrDeviceReady(void) return (vrDeviceReady || vrSimulator) && vrEnabled; } +// Detect if VR simulator is running +bool IsVrSimulator(void) +{ + return vrSimulator; +} + // Enable/Disable VR experience (device or simulator) void ToggleVrMode(void) { @@ -2707,16 +2734,17 @@ void ToggleVrMode(void) #endif } -// Update VR tracking (position and orientation) -void UpdateVrTracking(void) +// Update VR tracking (position and orientation) and camera +void UpdateVrTracking(Camera *camera) { #if defined(RLGL_OCULUS_SUPPORT) - if (vrDeviceReady) UpdateOculusTracking(); - else -#endif + if (vrDeviceReady) { - // TODO: Use alternative inputs (mouse, keyboard) to simulate tracking data (eyes position/orientation) + UpdateOculusTracking(); + + // TODO: Update camera data (position, target, up) with tracking data } +#endif } // Begin Oculus drawing configuration @@ -2891,11 +2919,18 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength); +#ifdef _MSC_VER + char *log = malloc(maxLength); +#else char log[maxLength]; - +#endif glGetShaderInfoLog(vertexShader, maxLength, &length, log); TraceLog(INFO, "%s", log); + +#ifdef _MSC_VER + free(log); +#endif } else TraceLog(INFO, "[VSHDR ID %i] Vertex shader compiled successfully", vertexShader); @@ -2912,11 +2947,18 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength); +#ifdef _MSC_VER + char *log = malloc(maxLength); +#else char log[maxLength]; - +#endif glGetShaderInfoLog(fragmentShader, maxLength, &length, log); TraceLog(INFO, "%s", log); + +#ifdef _MSC_VER + free(log); +#endif } else TraceLog(INFO, "[FSHDR ID %i] Fragment shader compiled successfully", fragmentShader); @@ -2950,12 +2992,18 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); +#ifdef _MSC_VER + char *log = malloc(maxLength); +#else char log[maxLength]; - +#endif glGetProgramInfoLog(program, maxLength, &length, log); TraceLog(INFO, "%s", log); - + +#ifdef _MSC_VER + free(log); +#endif glDeleteProgram(program); program = 0; @@ -3070,7 +3118,7 @@ static Shader LoadStandardShader(void) shader = GetDefaultShader(); } #else - shader = defaultShader; + shader = GetDefaultShader(); TraceLog(WARNING, "[SHDR ID %i] Standard shader not available, using default shader", shader.id); #endif @@ -3082,12 +3130,12 @@ static Shader LoadStandardShader(void) static void LoadDefaultShaderLocations(Shader *shader) { // NOTE: Default shader attrib locations have been fixed before linking: - // vertex position location = 0 - // vertex texcoord location = 1 - // vertex normal location = 2 - // vertex color location = 3 - // vertex tangent location = 4 - // vertex texcoord2 location = 5 + // vertex position location = 0 + // vertex texcoord location = 1 + // vertex normal location = 2 + // vertex color location = 3 + // vertex tangent location = 4 + // vertex texcoord2 location = 5 // Get handles to GLSL input attibute locations shader->vertexLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_POSITION_NAME); @@ -3101,10 +3149,18 @@ static void LoadDefaultShaderLocations(Shader *shader) shader->mvpLoc = glGetUniformLocation(shader->id, "mvpMatrix"); // Get handles to GLSL uniform locations (fragment shader) - shader->tintColorLoc = glGetUniformLocation(shader->id, "colDiffuse"); + shader->colDiffuseLoc = glGetUniformLocation(shader->id, "colDiffuse"); + shader->colAmbientLoc = glGetUniformLocation(shader->id, "colAmbient"); + shader->colSpecularLoc = glGetUniformLocation(shader->id, "colSpecular"); + shader->mapTexture0Loc = glGetUniformLocation(shader->id, "texture0"); shader->mapTexture1Loc = glGetUniformLocation(shader->id, "texture1"); shader->mapTexture2Loc = glGetUniformLocation(shader->id, "texture2"); + + // TODO: Try to find all expected/recognized shader locations (predefined names, must be documented) + + // Try to get lights location points (if available) + GetShaderLightsLocations(*shader); } // Unload default shader @@ -3395,7 +3451,7 @@ static void DrawDefaultBuffers(int eyesCount) Matrix matMVP = MatrixMultiply(modelview, projection); glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP)); - glUniform4f(currentShader.tintColorLoc, 1.0f, 1.0f, 1.0f, 1.0f); + glUniform4f(currentShader.colDiffuseLoc, 1.0f, 1.0f, 1.0f, 1.0f); glUniform1i(currentShader.mapTexture0Loc, 0); // NOTE: Additional map textures not considered for default buffers drawing @@ -3493,7 +3549,7 @@ static void DrawDefaultBuffers(int eyesCount) for (int i = 0; i < drawsCounter; i++) { quadsCount = draws[i].vertexCount/4; - numIndicesToProcess = quadsCount*6; // Get number of Quads * 6 index by Quad + numIndicesToProcess = quadsCount*6; // Get number of Quads*6 index by Quad //TraceLog(DEBUG, "Quads to render: %i - Vertex Count: %i", quadsCount, draws[i].vertexCount); @@ -3590,82 +3646,100 @@ static void UnloadDefaultBuffers(void) free(quads.indices); } -// Setup shader uniform values for lights array -// NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0f -static void SetShaderLights(Shader shader) +// Get shader locations for lights (up to MAX_LIGHTS) +static void GetShaderLightsLocations(Shader shader) { - int locPoint = -1; - char locName[32] = "lights[x].position\0"; - + char locName[32] = "lights[x].\0"; + char locNameUpdated[64]; + for (int i = 0; i < MAX_LIGHTS; i++) { locName[7] = '0' + i; + + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "enabled\0"); + lightsLocs[i][0] = glGetUniformLocation(shader.id, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "type\0"); + lightsLocs[i][1] = glGetUniformLocation(shader.id, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "position\0"); + lightsLocs[i][2] = glGetUniformLocation(shader.id, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "direction\0"); + lightsLocs[i][3] = glGetUniformLocation(shader.id, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "radius\0"); + lightsLocs[i][4] = glGetUniformLocation(shader.id, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "diffuse\0"); + lightsLocs[i][5] = glGetUniformLocation(shader.id, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "intensity\0"); + lightsLocs[i][6] = glGetUniformLocation(shader.id, locNameUpdated); + + locNameUpdated[0] = '\0'; + strcpy(locNameUpdated, locName); + strcat(locNameUpdated, "coneAngle\0"); + lightsLocs[i][7] = glGetUniformLocation(shader.id, locNameUpdated); + } +} - if (lights[i] != NULL) // Only upload registered lights data +// Set shader uniform values for lights +// NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0 +static void SetShaderLightsValues(Shader shader) +{ + for (int i = 0; i < MAX_LIGHTS; i++) + { + if (i < lightsCount) { - memcpy(&locName[10], "enabled\0", strlen("enabled\0") + 1); - locPoint = GetShaderLocation(shader, locName); - glUniform1i(locPoint, lights[i]->enabled); - - memcpy(&locName[10], "type\0", strlen("type\0") + 1); - locPoint = GetShaderLocation(shader, locName); - glUniform1i(locPoint, lights[i]->type); - - memcpy(&locName[10], "diffuse\0", strlen("diffuse\0") + 2); - locPoint = glGetUniformLocation(shader.id, locName); - glUniform4f(locPoint, (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255); - - memcpy(&locName[10], "intensity\0", strlen("intensity\0")); - locPoint = glGetUniformLocation(shader.id, locName); - glUniform1f(locPoint, lights[i]->intensity); + glUniform1i(lightsLocs[i][0], lights[i]->enabled); + + glUniform1i(lightsLocs[i][1], lights[i]->type); + glUniform4f(lightsLocs[i][5], (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255); + glUniform1f(lightsLocs[i][6], lights[i]->intensity); switch (lights[i]->type) { case LIGHT_POINT: { - memcpy(&locName[10], "position\0", strlen("position\0") + 1); - locPoint = GetShaderLocation(shader, locName); - glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); - - memcpy(&locName[10], "radius\0", strlen("radius\0") + 2); - locPoint = GetShaderLocation(shader, locName); - glUniform1f(locPoint, lights[i]->radius); + glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); + glUniform1f(lightsLocs[i][4], lights[i]->radius); } break; case LIGHT_DIRECTIONAL: { - memcpy(&locName[10], "direction\0", strlen("direction\0") + 2); - locPoint = GetShaderLocation(shader, locName); - Vector3 direction = { lights[i]->target.x - lights[i]->position.x, lights[i]->target.y - lights[i]->position.y, lights[i]->target.z - lights[i]->position.z }; + Vector3 direction = VectorSubtract(lights[i]->target, lights[i]->position); VectorNormalize(&direction); - glUniform3f(locPoint, direction.x, direction.y, direction.z); + glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z); } break; case LIGHT_SPOT: { - memcpy(&locName[10], "position\0", strlen("position\0") + 1); - locPoint = GetShaderLocation(shader, locName); - glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); - - memcpy(&locName[10], "direction\0", strlen("direction\0") + 2); - locPoint = GetShaderLocation(shader, locName); + glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); - Vector3 direction = { lights[i]->target.x - lights[i]->position.x, lights[i]->target.y - lights[i]->position.y, lights[i]->target.z - lights[i]->position.z }; + Vector3 direction = VectorSubtract(lights[i]->target, lights[i]->position); VectorNormalize(&direction); - glUniform3f(locPoint, direction.x, direction.y, direction.z); + glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z); - memcpy(&locName[10], "coneAngle\0", strlen("coneAngle\0")); - locPoint = GetShaderLocation(shader, locName); - glUniform1f(locPoint, lights[i]->coneAngle); + glUniform1f(lightsLocs[i][7], lights[i]->coneAngle); } break; default: break; } - - // TODO: Pass to the shader any other required data from LightData struct } - else // Not enabled lights + else { - memcpy(&locName[10], "enabled\0", strlen("enabled\0") + 1); - locPoint = GetShaderLocation(shader, locName); - glUniform1i(locPoint, 0); + glUniform1i(lightsLocs[i][0], 0); // Light disabled } } } |
