/* compile with */ /* gcc file.c -lglfw -lGLEW -lGL */ #define GLEW_STATIC #include #include #include #include #include #include const char* vs_norm = "#version 330 core\n\ in vec2 in_Vertex;\n\ void main()\n\ {\n\ gl_Position = vec4(in_Vertex, 0.0, 1.0);\n\ }"; const char* fs_hang = "#version 330 core\n\ out vec4 out_Color;\n\ void main()\n\ {\n\ out_Color = vec4(0.445463, 0.609773, 0.93109, 1.0);\n\ }"; const char* fs_no_hang = "#version 330 core\n\ out vec4 out_Color;\n\ out vec4 out_Color2;\n\ void main()\n\ {\n\ out_Color = vec4(0.5, 0.6, 0.8, 1.0);\n\ out_Color2 = vec4(0.9, 0.4, 0.2, 1.0);\n\ }"; const char* vs_tex = "#version 330 core\n\ in vec2 in_Vertex;\n\ in vec2 in_TexCoords;\n\ out vec2 out_TexCoords;\n\ uniform sampler2D tex;\n\ void main()\n\ {\n\ gl_Position = vec4(in_Vertex, 0.0, 1.0);\n\ out_TexCoords = in_TexCoords;\n\ }"; const char* fs_tex = "#version 330 core\n\ in vec2 out_TexCoords;\n\ out vec4 out_Color;\n\ uniform sampler2D tex;\n\ void main()\n\ {\n\ out_Color = texture(tex, out_TexCoords);\n\ }"; typedef struct s_Shader { GLuint fs; GLuint vs; GLuint program; }Shader; void compileShader(Shader* shader, const char* vs_str, const char* fs_str) { char* error; GLint isCompiled, length; shader->vs = glCreateShader(GL_VERTEX_SHADER); shader->fs = glCreateShader(GL_FRAGMENT_SHADER); shader->program = glCreateProgram(); glShaderSource(shader->vs, 1, &vs_str, 0); glShaderSource(shader->fs, 1, &fs_str, 0); glCompileShader(shader->vs); glGetShaderiv(shader->vs, GL_COMPILE_STATUS, &isCompiled); if(isCompiled == GL_FALSE) { glGetShaderiv(shader->vs, GL_INFO_LOG_LENGTH, &length); error = malloc(length); glGetShaderInfoLog(shader->vs, length, &length, error); printf("vs not compiled: \n%s\n", error); free(error); } glCompileShader(shader->fs); glGetShaderiv(shader->fs, GL_COMPILE_STATUS, &isCompiled); if(isCompiled == GL_FALSE) { glGetShaderiv(shader->fs, GL_INFO_LOG_LENGTH, &length); error = malloc(length); glGetShaderInfoLog(shader->fs, length, &length, error); printf("fs not compiled: \n%s\n", error); free(error); } glAttachShader(shader->program, shader->vs); glAttachShader(shader->program, shader->fs); glLinkProgram(shader->program); glGetProgramiv(shader->program, GL_LINK_STATUS, &isCompiled); if(isCompiled == GL_FALSE) { GLint maxLength = 0; glGetProgramiv(shader->program, GL_INFO_LOG_LENGTH, &length); error = malloc(length); glGetProgramInfoLog(shader->program, length, &length, error); printf("program not linked: \n%s\n", error); free(error); } } void debugCallback(GLenum source, GLenum type, GLuint id,GLenum severity, GLsizei length, const GLchar* message, void* userParam) { printf("%s", message); } int main() { GLFWwindow* window; Shader shader_draw, shader_tex; GLuint fbo, tex, tex2; GLuint vao, vbo; GLuint texVao, texVbo, texVboTexCoords; float vertices[] = {-0.5, -0.5, -0.5, 0.5, 0.5, -0.5}; float screenVertices[] = {-1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0}; float texCoords[] = {0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0}; GLenum buffs[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; if (!glfwInit()) { printf("Failed to load GLFW"); exit(0); } glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true); window = glfwCreateWindow(800, 600, "fast color clear", NULL, NULL); if(!window) { printf("Failed to create window\n"); exit(0); } glfwMakeContextCurrent(window); glewExperimental = true; if (glewInit() != GLEW_OK) { printf("Failed to init GLEW\n"); exit(0); } /*Error*/ glDebugMessageCallback(&debugCallback, NULL); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2 ,GL_FLOAT , GL_FALSE, 0, NULL); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); /*Tex*/ glGenVertexArrays(1, &texVao); glBindVertexArray(texVao); glGenBuffers(1, &texVbo); glGenBuffers(1, &texVboTexCoords); glBindBuffer(GL_ARRAY_BUFFER, texVbo); glBufferData(GL_ARRAY_BUFFER, sizeof(screenVertices), screenVertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2 ,GL_FLOAT , GL_FALSE, 0, NULL); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, texVboTexCoords); glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW); glVertexAttribPointer(1, 2 ,GL_FLOAT , GL_FALSE, 0, NULL); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); compileShader(&shader_draw, vs_norm, fs_hang); compileShader(&shader_tex, vs_tex, fs_tex); glGenTextures(1, &tex); glGenTextures(1, &tex2); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_INT, NULL); glBindTexture(GL_TEXTURE_2D, tex2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_INT, NULL); glBindTexture(GL_TEXTURE_2D, 0); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, tex2, 0); glDrawBuffers(2, buffs); /* Will hang after if GL_COLOR_ATTACHMENT1 is cleared but the shader doesn't write */ /* anything */ glClear(GL_COLOR_BUFFER_BIT); glDrawBuffer(GL_ZERO); glBindFramebuffer(GL_FRAMEBUFFER, 0); /*Loop*/ while(!glfwWindowShouldClose(window)) { glBindFramebuffer(GL_FRAMEBUFFER, fbo); glUseProgram(shader_draw.program); glBindVertexArray(vao); glDrawBuffers(2, buffs); glDrawArrays(GL_TRIANGLES, 0, 3); /* Hang here */ glDrawBuffer(GL_ZERO); glBindVertexArray(0); glUseProgram(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, tex); glUseProgram(shader_tex.program); glBindVertexArray(texVao); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); glUseProgram(0); glBindTexture(GL_TEXTURE_2D, 0); glfwSwapBuffers(window); glClear(GL_COLOR_BUFFER_BIT); glfwPollEvents(); } return 0; }