From 7ef8e2c36eeb4dfc6a4a91c29ac4fc8232973ac9 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Tue, 28 Oct 2025 12:08:01 -0500 Subject: [PATCH] add vertex_color_fp_render --- Makefile | 2 +- src/vertex_color_fp_render.c | 334 +++++++++++++++++++++++++++++ src/vertex_color_fp_render.fp.glsl | 16 ++ 3 files changed, 351 insertions(+), 1 deletion(-) create mode 100644 src/vertex_color_fp_render.c create mode 100644 src/vertex_color_fp_render.fp.glsl diff --git a/Makefile b/Makefile index a21eb6d..c0af023 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ OPT = -O0 CFLAGS += -std=gnu23 CFLAGS += -g -CFLAGS += -Wall -Werror -Wfatal-errors +CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable CFLAGS += $(shell pkg-config --libs --cflags glfw3) CFLAGS += -lm -lGL diff --git a/src/vertex_color_fp_render.c b/src/vertex_color_fp_render.c new file mode 100644 index 0000000..c96debe --- /dev/null +++ b/src/vertex_color_fp_render.c @@ -0,0 +1,334 @@ +#include +#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(const char * vp_path, const char * fp_path) +{ + void * vertexShaderSource = read_file(vp_path); + 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(fp_path); + 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 triangle_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 +}; + +static const float texture_vertex_buffer_data[] = { + // position // texture + 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // top right + 0.5f, -0.5f, 0.0f, 1.0f, 1.0f, // bottom right + -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // bottom left + + -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, // top left + 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // top right + -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // bottom left +}; + +struct location { + unsigned int program; + struct { + unsigned int position; + unsigned int color; + unsigned int texture; + } attrib; + struct { + unsigned int texture1; + } uniform; +}; + +int main() +{ + glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11); + 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 triangle_vertex_buffer = make_buffer(GL_ARRAY_BUFFER, + triangle_vertex_buffer_data, + (sizeof (triangle_vertex_buffer_data))); + + unsigned int texture_vertex_buffer = make_buffer(GL_ARRAY_BUFFER, + texture_vertex_buffer_data, + (sizeof (texture_vertex_buffer_data))); + + // vertex color start + struct location vertex_color; + printf("compile start: vertex color\n"); + vertex_color.program = compile_shaders("src/vertex_color.vp.glsl", + "src/vertex_color_fp_render.fp.glsl"); + printf("compile end: vertex color\n"); + + glUseProgram(vertex_color.program); + vertex_color.attrib.position = glGetAttribLocation(vertex_color.program, "position"); + vertex_color.attrib.color = glGetAttribLocation(vertex_color.program, "color"); + printf("vertex color attributes:\n position %u\n color %u\n", + vertex_color.attrib.position, + vertex_color.attrib.color); + vertex_color.uniform.texture1 = glGetUniformLocation(vertex_color.program, "test"); + + // vertex color end + + // texture start + struct location texture; + printf("compile start: texture\n"); + texture.program = compile_shaders("src/texture.vp.glsl", + "src/texture.fp.glsl"); + printf("compile end: texture\n"); + + glUseProgram(texture.program); + texture.attrib.position = glGetAttribLocation(texture.program, "pos"); + texture.attrib.texture = glGetAttribLocation(texture.program, "tex"); + texture.uniform.texture1 = glGetUniformLocation(texture.program, "texture1"); + printf("texture attributes:\n position %u\n texture %u\n", + texture.attrib.position, + texture.attrib.texture); + printf("texture uniforms:\n texture1 %u\n", + texture.uniform.texture1); + + + unsigned int texture1; + glGenTextures(1, &texture1); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + void * texture_buf = read_file("texture/butterfly_1024x1024_rgb888.data"); + assert(texture_buf != NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, texture_buf); + free(texture_buf); + + // texture end + + unsigned int fp_framebuffer; + glGenFramebuffers(1, &fp_framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, fp_framebuffer); + + unsigned int colorbuffer[2]; + glGenTextures(2, colorbuffer); + for (int i = 0; i < 2; i++) { + glBindTexture(GL_TEXTURE_2D, colorbuffer[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 1600, 1200, 0, GL_RGBA, GL_FLOAT, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, colorbuffer[i], 0); + } + unsigned int depthbuffer; + { + glGenRenderbuffers(1, &depthbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 1600, 1200); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer); + unsigned int attachments[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; + glDrawBuffers(2, attachments); + //glDrawBuffer(GL_COLOR_ATTACHMENT0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + printf("Framebuffer not complete!"); + } + + while(!glfwWindowShouldClose(window)) { + if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(window, true); + + //glBindFramebuffer(GL_FRAMEBUFFER, 0); + + + //glClearColor(0.1f, 0.1f, 0.1f, 0.1f); + //glClear(GL_COLOR_BUFFER_BIT); + + // + // render + // + //glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, fp_framebuffer); + glUseProgram(vertex_color.program); + + glBindBuffer(GL_ARRAY_BUFFER, triangle_vertex_buffer); + glVertexAttribPointer(vertex_color.attrib.position, + 3, + GL_FLOAT, + GL_FALSE, + (sizeof (float)) * 6, + (void*)0 + ); + glVertexAttribPointer(vertex_color.attrib.color, + 3, + GL_FLOAT, + GL_FALSE, + (sizeof (float)) * 6, + (void*)(3 * 4) + ); + glEnableVertexAttribArray(vertex_color.attrib.position); + glEnableVertexAttribArray(vertex_color.attrib.color); + + glUniform1i(vertex_color.uniform.texture1, 3); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + // + if (0) { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glUseProgram(texture.program); + + glBindBuffer(GL_ARRAY_BUFFER, texture_vertex_buffer); + glVertexAttribPointer(texture.attrib.position, + 3, + GL_FLOAT, + GL_FALSE, + (sizeof (float)) * 5, + (void*)0 + ); + glVertexAttribPointer(texture.attrib.texture, + 2, + GL_FLOAT, + GL_FALSE, + (sizeof (float)) * 5, + (void*)(3 * 4) + ); + glEnableVertexAttribArray(texture.attrib.position); + glEnableVertexAttribArray(texture.attrib.texture); + + glActiveTexture(GL_TEXTURE1); + //glBindTexture(GL_TEXTURE_2D, texture1); + glBindTexture(GL_TEXTURE_2D, colorbuffer[0]); + glUniform1i(texture.uniform.texture1, 1); + + glDrawArrays(GL_TRIANGLES, 0, 6); + } + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwTerminate(); + + return 0; +} diff --git a/src/vertex_color_fp_render.fp.glsl b/src/vertex_color_fp_render.fp.glsl new file mode 100644 index 0000000..5db7604 --- /dev/null +++ b/src/vertex_color_fp_render.fp.glsl @@ -0,0 +1,16 @@ +#version 120 + +//varying vec3 color_out; + +uniform sampler2D test; + +void main() +{ + gl_FragData[0] = gl_Color; + /* + gl_FragData[1] = vec4(dot(gl_Color.rg, gl_Color.bg), + dot(gl_Color.rr, gl_Color.gg), + dot(gl_Color.bb, gl_Color.gg), 1); + */ + gl_FragData[1] = texture2D(test, gl_Color.bg); +}