opengl

Sample code from LearnOpenGL.com
Log | Files | Refs

shader.c (3548B)


      1 // Shader.c provides utilities for shader management.
      2 // GLFW and GLAD must be initialized before any functions can be used.
      3 #include <errno.h>
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <string.h>
      7 
      8 #include <glad/glad.h>
      9 #include <GLFW/glfw3.h>
     10 
     11 #include "main.h"
     12 #include "err.h"
     13 
     14 char *
     15 readfile(const char *file)
     16 {
     17 	FILE *f = fopen(file, "r");
     18 	if (f == NULL) {
     19 		snprintf(errstr, sizeof(errstr), "fopen: errno = %d", errno);
     20 		return NULL;
     21 	}
     22 	
     23 	size_t bufsize = 128;
     24 	size_t bytesRead = 0;
     25 	char *c;
     26 	c = (char *)malloc(bufsize);
     27 	if (c == NULL) {
     28 		snprintf(errstr, sizeof(errstr),
     29 			"allocate memory: errno = %d", errno);
     30 		return NULL;
     31 	}	
     32 	
     33 	for (;;) {
     34 		size_t read = fread(&c[bytesRead], sizeof(c[0]),
     35 			bufsize-bytesRead, f);
     36 		bytesRead += read;
     37 		if (read < bufsize - bytesRead) {
     38 			break;
     39 		}
     40 		bufsize *= 2; // TODO: check overflow.
     41 		char* newc = (char *)realloc(c, bufsize);
     42 		if (newc == NULL) {
     43 			snprintf(errstr, sizeof(errstr),
     44 				"allocate memory: errno = %d", errno);
     45 			free(c);
     46 			return NULL;
     47 		}
     48 		c = newc;
     49 	}
     50 	if (!feof(f) || ferror(f)) {
     51 		snprintf(errstr, sizeof(errstr),
     52 			"read from file %s: errno = %d", file, errno);
     53 		free(c);
     54 		return NULL;
     55 	}
     56 	
     57 	c[bytesRead] = '\0';	
     58 	return c;
     59 }
     60 
     61 Shader *
     62 ShaderInit(const char *vs, const char *fs)
     63 {
     64 	char *vertexShaderSource = readfile(vs);
     65 	if (vertexShaderSource == NULL) {
     66 		char *olderr = strdup(errstr);
     67 		snprintf(errstr, sizeof(errstr),
     68 			"read vertex shader: %s", olderr);
     69 		return NULL;
     70 	}
     71 	char *fragmentShaderSource = readfile(fs);
     72 	if (vertexShaderSource == NULL) {
     73 		char *olderr = strdup(errstr);
     74 		snprintf(errstr, sizeof(errstr),
     75 			"read fragment shader: %s", olderr);
     76 		return NULL;
     77 	}
     78 	
     79 	unsigned int vertexShader;
     80 	int success;
     81 	char log[512];
     82 	vertexShader = glCreateShader(GL_VERTEX_SHADER);
     83 	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
     84 	glCompileShader(vertexShader);
     85 	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
     86 	if (!success) {
     87 		glGetShaderInfoLog(vertexShader, sizeof(log), NULL, log);
     88 		snprintf(errstr, sizeof(errstr),
     89 			"compile vertex shader: %s", log);
     90 		return NULL;
     91 	}
     92 	unsigned int fragmentShader;
     93 	fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
     94 	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
     95 	glCompileShader(fragmentShader);
     96 	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
     97 	if (!success) {
     98 		glGetShaderInfoLog(fragmentShader, sizeof(log), NULL, log);
     99 		snprintf(errstr, sizeof(errstr),
    100 			"compile fragment shader: %s", log);
    101 		return NULL;
    102 	}
    103 	unsigned int shaderProgram;
    104 	shaderProgram = glCreateProgram();
    105 	glAttachShader(shaderProgram, vertexShader);
    106 	glAttachShader(shaderProgram, fragmentShader);
    107 	glLinkProgram(shaderProgram);
    108 	glGetShaderiv(shaderProgram, GL_COMPILE_STATUS, &success);
    109 	if (!success) {
    110 		glGetShaderInfoLog(shaderProgram, sizeof(log), NULL, log);
    111 		snprintf(errstr, sizeof(errstr),
    112 			"link shaders: %s", log);
    113 		return NULL;
    114 	}
    115 	
    116 	free(vertexShaderSource);
    117 	free(fragmentShaderSource);
    118 	glDeleteShader(vertexShader);
    119 	glDeleteShader(fragmentShader);
    120 	
    121 	Shader *shader = (Shader *) malloc(sizeof(Shader));
    122 	shader->ID = shaderProgram;
    123 	return shader;
    124 }
    125 
    126 void
    127 ShaderUse(Shader *s)
    128 {
    129 	glUseProgram(s->ID);
    130 }
    131 
    132 void
    133 ShaderDelete(Shader *s)
    134 {
    135 	glDeleteProgram(s->ID);
    136 }
    137 
    138 void
    139 ShaderSetFloat(Shader *s, const char *name, float value)
    140 {
    141 	glUniform1f(glGetUniformLocation(s->ID, name), value);
    142 }
    143 
    144 void
    145 ShaderSetMat4(Shader *s, const char *name, float *mat)
    146 {
    147 	glUniformMatrix4fv(glGetUniformLocation(s->ID, name), 1,
    148 		GL_FALSE, mat);
    149 }