#define GL_GLEXT_PROTOTYPES #include #include #include #include #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); }