/** * Copyright (c) 2021 Dominic Msters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "shader.h" void shaderCompile(shader_t *shader, char *vertexShaderSource, char* fragmentShaderSource ) { int isSuccess, maxLength; char *error; GLuint shaderVertex, shaderFragment, shaderProgram; // Load the vertex shader first shaderVertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(shaderVertex, 1, &vertexShaderSource, 0); glCompileShader(shaderVertex); // Validate glGetShaderiv(shaderVertex, GL_COMPILE_STATUS, &isSuccess); if(!isSuccess) { glGetShaderiv(shaderVertex, GL_INFO_LOG_LENGTH, &maxLength); error = malloc(maxLength); glGetShaderInfoLog(shaderVertex, maxLength, &maxLength, error); printf("Failed to compile vertex shader %s\n", error); free(error); return NULL; } // Now load the Frag shader shaderFragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(shaderFragment, 1, &fragmentShaderSource, 0); glCompileShader(shaderFragment); glGetShaderiv(shaderFragment, GL_COMPILE_STATUS, &isSuccess); if(!isSuccess) { glGetShaderiv(shaderFragment, GL_INFO_LOG_LENGTH, &maxLength); error = malloc(maxLength); glGetShaderInfoLog(shaderFragment, maxLength, &maxLength, error); printf("Failed to compile fragment shader %s\n", error); free(error); glDeleteShader(shaderVertex); return NULL; } // Now create the shader program. shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, shaderVertex); glAttachShader(shaderProgram, shaderFragment); //Bind, Verify & Use the shader program glLinkProgram(shaderProgram); glGetProgramiv(shaderProgram, GL_LINK_STATUS, &isSuccess); if(!isSuccess) { glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &maxLength); error = malloc(maxLength); glGetProgramInfoLog(shaderProgram, maxLength, &maxLength, error); printf("Failed to load shader program %s\n", error); free(error); glDeleteShader(shaderVertex); glDeleteShader(shaderFragment); return NULL; } // Everything is okay, let's create the encapsulated shader. shader->shaderVertex = shaderVertex; shader->shaderFrag = shaderFragment; shader->shaderProgram = shaderProgram; shader->uniProj = glGetUniformLocation(shader->shaderProgram,SHADER_UNI_PROJ); shader->uniView = glGetUniformLocation(shader->shaderProgram,SHADER_UNI_VIEW); shader->uniText = glGetUniformLocation(shader->shaderProgram,SHADER_UNI_TEXT); shader->uniModl = glGetUniformLocation(shader->shaderProgram,SHADER_UNI_MODL); // Bind the shader shaderUse(shader); // Reset position shaderUsePosition(shader, 0, 0, 0, 0, 0, 0); // Fetch the uniforms. return shader; } void shaderDispose(shader_t *shader) { glDeleteProgram(shader->shaderProgram); glDeleteShader(shader->shaderVertex); glDeleteShader(shader->shaderFrag); } void shaderUse(shader_t *shader) { glUseProgram(shader->shaderProgram); } void shaderUseCamera(shader_t *shader, camera_t *camera) { glUniformMatrix4fv(shader->uniView, 1, GL_FALSE, camera->view[0]); glUniformMatrix4fv(shader->uniProj, 1, GL_FALSE, camera->projection[0]); } void shaderUseTexture(shader_t *shader, texture_t *texture) { // OpenGL requires us to set the active texure. glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture->id); glUniform1i(shader->uniText, 0); } void shaderUsePosition(shader_t *shader, float x, float y, float z, float pitch, float yaw, float roll ) { mat4 MATRIX_POSITION; vec3 axis; // Identify mat. glm_mat4_identity(MATRIX_POSITION); //Position axis[0] = x, axis[1] = y, axis[2] = z; glm_translate_make(MATRIX_POSITION, axis); // Rotation (YZX order) axis[0] = 0, axis[1] = 1, axis[2] = 0; glm_rotate(MATRIX_POSITION, yaw, axis); axis[1] = 0, axis[2] = 1; glm_rotate(MATRIX_POSITION, roll, axis); axis[0] = 1, axis[2] = 0; glm_rotate(MATRIX_POSITION, pitch, axis); //Send to the shader. glUniformMatrix4fv(shader->uniModl, 1, GL_FALSE, MATRIX_POSITION[0]); } void shaderUsePositionAndScale(shader_t *shader, float x, float y, float z, float pitch, float yaw, float roll, float scaleX, float scaleY, float scaleZ ) { mat4 MATRIX_POSITION; vec3 axis; // Identify mat. glm_mat4_identity(MATRIX_POSITION); //Position axis[0] = x, axis[1] = y, axis[2] = z; glm_translate_make(MATRIX_POSITION, axis); // Rotation (YZX order) axis[0] = 0, axis[1] = 1, axis[2] = 0; glm_rotate(MATRIX_POSITION, yaw, axis); axis[1] = 0, axis[2] = 1; glm_rotate(MATRIX_POSITION, roll, axis); axis[0] = 1, axis[2] = 0; glm_rotate(MATRIX_POSITION, pitch, axis); // Scale axis[0] = scaleX, axis[1] = scaleY, axis[2] = scaleZ; glm_scale(MATRIX_POSITION, axis); glUniformMatrix4fv(shader->uniModl, 1, GL_FALSE, MATRIX_POSITION[0]); }