diff --git a/build.sh b/build.sh index 536671c..254d930 100644 --- a/build.sh +++ b/build.sh @@ -4,4 +4,6 @@ CFLAGS="-Wall -Werror -Wfatal-errors -g -Og -std=gnu23 -Iinclude $(pkg-config -- #gcc $CFLAGS src/main.c -gcc $CFLAGS src/vertex_color.c +#gcc $CFLAGS src/vertex_color.c + +gcc $CFLAGS src/vertex_color_translate.c diff --git a/src/vertex_color.vp.glsl b/src/vertex_color.vp.glsl index ec465e4..9c4309c 100644 --- a/src/vertex_color.vp.glsl +++ b/src/vertex_color.vp.glsl @@ -1,7 +1,5 @@ #version 120 -uniform float time; - attribute vec3 position; attribute vec3 color; diff --git a/src/vertex_color_translate.c b/src/vertex_color_translate.c new file mode 100644 index 0000000..4860b80 --- /dev/null +++ b/src/vertex_color_translate.c @@ -0,0 +1,220 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static void * read_file(const char * filename) +{ + int fd = open(filename, O_RDONLY); + if (fd == -1) { + fprintf(stderr, "open(%s): %s\n", filename, strerror(errno)); + return NULL; + } + + off_t size = lseek(fd, 0, SEEK_END); + if (size == (off_t)-1) { + fprintf(stderr, "lseek(%s, SEEK_END): %s\n", filename, strerror(errno)); + return NULL; + } + + off_t start = lseek(fd, 0, SEEK_SET); + if (start == (off_t)-1) { + fprintf(stderr, "lseek(%s, SEEK_SET): %s\n", filename, strerror(errno)); + return NULL; + } + + void * buf = malloc(size+1); + + ssize_t read_size = read(fd, buf, size); + if (read_size == -1) { + fprintf(stderr, "read(%s): %s\n", filename, strerror(errno)); + return NULL; + } + ((char*)buf)[read_size] = 0; + + return buf; +} + +void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +unsigned int compile_shaders() +{ + void * vertexShaderSource = read_file("src/vertex_color_translate.vp.glsl"); + unsigned int vertexShader; + vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, (const char **)&vertexShaderSource, NULL); + glCompileShader(vertexShader); + { + int success; + char infoLog[512]; + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); + if(!success) { + glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); + printf("vertex shader compile failed:\n%s\n", infoLog); + } + } + free(vertexShaderSource); + + void * fragmentShaderSource = read_file("src/vertex_color_translate.fp.glsl"); + unsigned int fragmentShader; + fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, (const char **)&fragmentShaderSource, NULL); + glCompileShader(fragmentShader); + { + int success; + char infoLog[512]; + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); + if(!success) { + glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); + printf("fragment shader compile failed:\n%s\n", infoLog); + } + } + free(fragmentShaderSource); + + unsigned int shaderProgram; + shaderProgram = glCreateProgram(); + + glAttachShader(shaderProgram, vertexShader); + glAttachShader(shaderProgram, fragmentShader); + glLinkProgram(shaderProgram); + + { + int success; + char infoLog[512]; + glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); + if(!success) { + glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); + printf("program link failed:\n%s\n", infoLog); + } + } + + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + return shaderProgram; +} + +static int make_buffer(unsigned int target, + const void * data, + size_t size) +{ + unsigned int buffer; + glGenBuffers(1, &buffer); + glBindBuffer(target, buffer); + glBufferData(target, size, data, GL_STATIC_DRAW); + return buffer; +} + +static const float vertex_buffer_data[] = { + // position // color + 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom right + -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom left + 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // top +}; + +struct location { + struct { + unsigned int position; + unsigned int color; + } attrib; + struct { + unsigned int translate; + } uniform; +}; + +int main() +{ + glfwInit(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); + //glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); + + GLFWwindow* window = glfwCreateWindow(1600, 1200, "LearnOpenGL", NULL, NULL); + if (window == NULL) { + const char* description; + glfwGetError(&description); + printf("Failed to create GLFW window: %s\n", description); + glfwTerminate(); + return -1; + } + glfwMakeContextCurrent(window); + + glViewport(0, 0, 1600, 1200); + //glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + unsigned int vertex_buffer = make_buffer(GL_ARRAY_BUFFER, + vertex_buffer_data, + (sizeof (vertex_buffer_data))); + + printf("compile start\n"); + unsigned int shaderProgram = compile_shaders(); + printf("compile end\n"); + + struct location location; + + location.attrib.position = glGetAttribLocation(shaderProgram, "position"); + location.attrib.color = glGetAttribLocation(shaderProgram, "color"); + printf("attributes:\n position %u\n color %u\n", + location.attrib.position, + location.attrib.color); + + location.uniform.translate = glGetUniformLocation(shaderProgram, "translate"); + printf("attributes:\n translate %u\n\n", + location.uniform.translate); + + float time = 0; + + while(!glfwWindowShouldClose(window)) { + if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(window, true); + + // + // render + // + glUseProgram(shaderProgram); + + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); + glVertexAttribPointer(location.attrib.position, + 3, + GL_FLOAT, + GL_FALSE, + (sizeof (float)) * 6, + (void*)0 + ); + glVertexAttribPointer(location.attrib.color, + 3, + GL_FLOAT, + GL_FALSE, + (sizeof (float)) * 6, + (void*)(3 * 4) + ); + glEnableVertexAttribArray(location.attrib.position); + glEnableVertexAttribArray(location.attrib.color); + + glUniform1f(location.uniform.translate, sinf(time) * 0.5f); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + glfwSwapBuffers(window); + glfwPollEvents(); + + glClearColor(0.1f, 0.1f, 0.1f, 0.1f); + glClear(GL_COLOR_BUFFER_BIT); + + time += 0.05; + } + + glfwTerminate(); + + return 0; +} diff --git a/src/vertex_color_translate.fp.glsl b/src/vertex_color_translate.fp.glsl new file mode 100644 index 0000000..d5ebca6 --- /dev/null +++ b/src/vertex_color_translate.fp.glsl @@ -0,0 +1,6 @@ +#version 120 + +void main() +{ + gl_FragColor = gl_Color; +} diff --git a/src/vertex_color_translate.vp.glsl b/src/vertex_color_translate.vp.glsl new file mode 100644 index 0000000..9fdcd87 --- /dev/null +++ b/src/vertex_color_translate.vp.glsl @@ -0,0 +1,12 @@ +#version 120 + +uniform float translate; + +attribute vec3 position; +attribute vec3 color; + +void main() +{ + gl_Position = vec4(translate + position.x, position.yz, 1); + gl_FrontColor = vec4(color, 1); +}