180 lines
4.7 KiB
C
180 lines
4.7 KiB
C
#define GL_GLEXT_PROTOTYPES
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <GL/gl.h>
|
|
#include <stdlib.h>
|
|
#include "renderer.h"
|
|
|
|
void checkGlError() {
|
|
//const char *err = SDL_GetError();
|
|
//if (*err != 0) {
|
|
// printf("OpenGL error: %s", err);
|
|
//}
|
|
}
|
|
|
|
/// returns 0 if failed.
|
|
GLuint compile_shader(GLuint type, const char *src) {
|
|
GLuint id = glCreateShader(type);
|
|
glShaderSource(id, 1, &src, 0);
|
|
glCompileShader(id);
|
|
|
|
int result;
|
|
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
|
if (result == GL_FALSE) {
|
|
int length;
|
|
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &result);
|
|
char *message = alloca(length * sizeof(char));
|
|
glGetShaderInfoLog(id, length, &length, message);
|
|
printf("failed to compile %s shader\n", type == GL_VERTEX_SHADER ? "vertex" : "fragment");
|
|
printf("%s\n", message);
|
|
glDeleteShader(id);
|
|
return 0;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
const char *vertex_shader_src =
|
|
//"attribute vec4 vPosition; \n"
|
|
//"void main() \n"
|
|
//"{ \n"
|
|
//" gl_Position = vPosition; \n"
|
|
//"} \n";
|
|
"#version 320 es\n"
|
|
"\n"
|
|
"layout(location = 0) in vec2 aPos;\n"
|
|
"\n"
|
|
"void main() {\n"
|
|
" gl_Position = vec4(aPos, 0.0, 1.0);\n"
|
|
"}\n";
|
|
|
|
/// returns 0 if failed.
|
|
GLuint create_shader(const char *fragment_src) {
|
|
GLuint program = glCreateProgram();
|
|
GLuint vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_src);
|
|
GLuint fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_src);
|
|
if (!((fragment_shader == 0) || (vertex_shader == 0))) {
|
|
glAttachShader(program, vertex_shader);
|
|
glAttachShader(program, fragment_shader);
|
|
glLinkProgram(program);
|
|
glValidateProgram(program);
|
|
glDeleteShader(vertex_shader);
|
|
glDeleteShader(fragment_shader);
|
|
return program;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
GLuint load_shader(const char *path) {
|
|
FILE *handle = fopen(path, "r");
|
|
if (handle == NULL) {
|
|
printf("failed to open shader file\n");
|
|
exit(1);
|
|
}
|
|
fseek(handle, 0L, SEEK_END);
|
|
long length = ftell(handle);
|
|
fseek(handle, 0L, SEEK_SET);
|
|
char *string = malloc(length * sizeof(char));
|
|
if (!fread(string, sizeof(char), length, handle)) {
|
|
printf("failed to read shader file\n");
|
|
exit(1);
|
|
}
|
|
fclose(handle);
|
|
|
|
GLuint shader = create_shader(string);
|
|
|
|
//if (shader == 0) {
|
|
// // print file
|
|
// int line_count = 1;
|
|
// printf("%i\t", line_count);
|
|
// line_count++;
|
|
// for (int i = 0; i < length; i++) {
|
|
// printf("%c", string[i]);
|
|
// if (string[i] == '\n') {
|
|
// printf("%i\t", line_count);
|
|
// line_count++;
|
|
// }
|
|
// }
|
|
// printf("\n");
|
|
//}
|
|
|
|
free(string);
|
|
return shader;
|
|
}
|
|
|
|
Renderer new_renderer() {
|
|
const char *version_str = (const char *)glGetString(GL_VERSION);
|
|
const char *renderer_str = (const char *)glGetString(GL_RENDERER);
|
|
printf("GL_VERSION: %s\n", version_str);
|
|
printf("GL_RENDERER: %s\n", renderer_str);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
// buffers
|
|
// Load the vertex data
|
|
GLfloat vertices[] = {
|
|
-1.0, 1.0,
|
|
-1.0, -1.0,
|
|
1.0, -1.0,
|
|
|
|
1.0, -1.0,
|
|
1.0, 1.0,
|
|
-1.0, 1.0,
|
|
};
|
|
GLuint vao, vbo;
|
|
glGenVertexArrays(1, &vao);
|
|
glBindVertexArray(vao);
|
|
glGenBuffers(1, &vbo);
|
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
glBufferData(GL_ARRAY_BUFFER,
|
|
sizeof(vertices),
|
|
vertices,
|
|
GL_STATIC_DRAW);
|
|
|
|
glEnableVertexAttribArray(0);
|
|
glVertexAttribPointer(
|
|
0, // location
|
|
2, // vec2
|
|
GL_FLOAT,
|
|
GL_FALSE,
|
|
0,
|
|
(void *)0
|
|
);
|
|
|
|
Renderer renderer = { "", 0, vao };
|
|
return renderer;
|
|
}
|
|
|
|
/// shader_path cannot be NULL.
|
|
void render(Renderer *state, int w, int h, double time, char *shader_path, int reload_shader) {
|
|
if (reload_shader || strcmp(state->shader_path, shader_path)) {
|
|
state->shader = load_shader(shader_path);
|
|
state->shader_path = shader_path;
|
|
}
|
|
|
|
checkGlError();
|
|
|
|
// Rendorrrr
|
|
glViewport(0, 0, w, h);
|
|
|
|
glClearColor(0.3f, 0.3f, 0.3f, 1.0f); // Dark gray background
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
// Shader parameters.
|
|
glUseProgram(state->shader);
|
|
|
|
int uniform_WindowSize = glGetUniformLocation(state->shader, "WindowSize");
|
|
glUniform2f(uniform_WindowSize, w, h);
|
|
|
|
int uniform_time = glGetUniformLocation(state->shader, "time");
|
|
glUniform1f(uniform_time, (float)time);
|
|
|
|
//glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
|
|
//glEnableVertexAttribArray(0);
|
|
//glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
|
|
glBindVertexArray(state->vao);
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
}
|
|
|