144 lines
4.3 KiB
C
144 lines
4.3 KiB
C
/**
|
|
* Copyright (c) 2021 Dominic Msters
|
|
*
|
|
* This software is released under the MIT License.
|
|
* https://opensource.org/licenses/MIT
|
|
*/
|
|
|
|
#include "shader.h"
|
|
|
|
void shaderInit(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;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
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) {
|
|
shaderUseMatrix(shader, shader->uniView, &camera->view);
|
|
shaderUseMatrix(shader, shader->uniProj, &camera->projection);
|
|
}
|
|
|
|
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 shaderUseMatrix(shader_t *shader,shaderuniform_t uniform,matrix_t *matrix){
|
|
glUniformMatrix4fv(uniform, 1, GL_FALSE, matrix->internalMatrix[0]);
|
|
}
|
|
|
|
void shaderUsePosition(shader_t *shader,
|
|
float x, float y, float z,
|
|
float pitch, float yaw, float roll
|
|
) {
|
|
matrix_t matrix;
|
|
|
|
matrixIdentity(&matrix);
|
|
matrixTranslate(&matrix, x, y, z);
|
|
|
|
// Rotation (YZX order)
|
|
matrixRotate(&matrix, yaw, 0, 1, 0);
|
|
matrixRotate(&matrix, roll, 0, 0, 1);
|
|
matrixRotate(&matrix, pitch, 1, 0, 0);
|
|
shaderUseMatrix(shader, shader->uniModl, &matrix);
|
|
}
|
|
|
|
void shaderUsePositionAndScale(shader_t *shader,
|
|
float x, float y, float z,
|
|
float pitch, float yaw, float roll,
|
|
float scaleX, float scaleY, float scaleZ
|
|
) {
|
|
matrix_t matrix;
|
|
|
|
matrixIdentity(&matrix);
|
|
matrixTranslate(&matrix, x, y, z);
|
|
|
|
// Rotation (YZX order)
|
|
matrixRotate(&matrix, yaw, 0, 1, 0);
|
|
matrixRotate(&matrix, roll, 0, 0, 1);
|
|
matrixRotate(&matrix, pitch, 1, 0, 0);
|
|
|
|
matrixScale(&matrix, scaleX, scaleY, scaleZ);
|
|
|
|
shaderUseMatrix(shader, shader->uniModl, &matrix);
|
|
} |