diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d83e98..7407979 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,13 @@ cmake_minimum_required (VERSION 3.0) project (OpenGL_Analog_Clock) find_package(OpenGL REQUIRED) +find_package(GLEW REQUIRED) +find_package(glfw3 REQUIRED) + +include_directories( + Include/ + . +) set(ALL_LIBS ${OPENGL_LIBRARY} @@ -10,6 +17,8 @@ set(ALL_LIBS GLEW ) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb") + add_definitions( -DTW_STATIC -DTW_NO_LIB_PRAGMA @@ -20,6 +29,7 @@ add_definitions( add_executable(clock main.c + shader.c ) target_link_libraries(clock diff --git a/Include/shader.h b/Include/shader.h new file mode 100644 index 0000000..9d3f5c9 --- /dev/null +++ b/Include/shader.h @@ -0,0 +1,6 @@ +#ifndef SHADER_HPP +#define SHADER_HPP + +GLuint LoadShaders(const char *vertex_file_path, const char *fragment_file_path); + +#endif diff --git a/main.c b/main.c index 2d6e478..526bc96 100644 --- a/main.c +++ b/main.c @@ -7,6 +7,10 @@ // Include GLFW #include + +// Include shader +#include "shader.h" + GLFWwindow* window; int main(void) { @@ -49,13 +53,48 @@ int main(void) { // Dark grey background glClearColor(0.15f, 0.15f, 0.15f, 0.0f); + GLuint VertexArrayID; + glGenVertexArrays(1, &VertexArrayID); + glBindVertexArray(VertexArrayID); + + // Create and compile our GLSL program from the shaders + GLuint programID = LoadShaders("shaders/SimpleVertexShader.vertexshader", "shaders/SimpleFragmentShader.fragmentshader"); + + static const GLfloat g_vertex_buffer_data[] = { + -1.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 0.0f, + 0.0f, 1.0f, 0.0f + }; + + GLuint vertexbuffer; + glGenBuffers(1, &vertexbuffer); + glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); + do { // Clear the screen. It's not mentioned before Tutorial 02, // but it can cause flickering, so it's there nonetheless. glClear(GL_COLOR_BUFFER_BIT); - // Draw nothing, see you in tutorial 2 ! + // Use our shader + glUseProgram(programID); + // 1rst attribute buffer : vertices + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); + glVertexAttribPointer( + 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized? + 0, // stride + NULL // array buffer offset + ); + + // Draw the triangle ! + glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle + + glDisableVertexAttribArray(0); // Swap buffers glfwSwapBuffers(window); diff --git a/shader.c b/shader.c new file mode 100644 index 0000000..b1115a0 --- /dev/null +++ b/shader.c @@ -0,0 +1,112 @@ +#include +#include +#include + +#include + +#include "shader.h" + +GLuint LoadShaders(const char *vertex_file_path, const char *fragment_file_path) { + + // Create the shaders + GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + // Read the Vertex Shader code from the file + FILE *vertex_file; + char *vertex_code = malloc(256 * sizeof(char)); + unsigned int cursor = 0; + + vertex_file = fopen(vertex_file_path, "r"); + if (vertex_file == NULL) { + fprintf(stderr, "Could not open %s.\n", vertex_file_path); + free(vertex_code); + return 0; + } + + while (!feof(vertex_file)) { + vertex_code[cursor] = getc(vertex_file); + cursor++; + } + + // Read the Fragment Shader code from the file + FILE *fragment_file; + char *fragment_code = malloc(256 * sizeof(char)); + cursor = 0; + + fragment_file = fopen(fragment_file_path, "r"); + if (fragment_file == NULL) { + fprintf(stderr, "Could not open %s.\n", fragment_file_path); + free(vertex_code); + free(fragment_code); + return 0; + } + + while (!feof(fragment_file)) { + fragment_code[cursor] = getc(fragment_file); + cursor++; + } + + GLint Result = GL_FALSE; + int InfoLogLength; + + + // Compile Vertex Shader + printf("Compiling shader : %s\n", vertex_file_path); + glShaderSource(VertexShaderID, 1, (const char **)&vertex_code, NULL); + glCompileShader(VertexShaderID); + + // Check Vertex Shader + glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + //if ( InfoLogLength > 0 ){ + // std::vector VertexShaderErrorMessage(InfoLogLength+1); + // glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); + // printf("%s\n", &VertexShaderErrorMessage[0]); + //} + + + + // Compile Fragment Shader + printf("Compiling shader : %s\n", fragment_file_path); + glShaderSource(FragmentShaderID, 1, (const char **)&fragment_code, NULL); + glCompileShader(FragmentShaderID); + + // Check Fragment Shader + glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + //if ( InfoLogLength > 0 ){ + // std::vector FragmentShaderErrorMessage(InfoLogLength+1); + // glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); + // printf("%s\n", &FragmentShaderErrorMessage[0]); + //} + + + + // Link the program + printf("Linking program\n"); + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + // Check the program + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + //if ( InfoLogLength > 0 ){ + // std::vector ProgramErrorMessage(InfoLogLength+1); + // glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); + // printf("%s\n", &ProgramErrorMessage[0]); + //} + + + glDetachShader(ProgramID, VertexShaderID); + glDetachShader(ProgramID, FragmentShaderID); + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} + + diff --git a/shaders/SimpleFragmentShader.fragmentshader b/shaders/SimpleFragmentShader.fragmentshader new file mode 100644 index 0000000..3b04c78 --- /dev/null +++ b/shaders/SimpleFragmentShader.fragmentshader @@ -0,0 +1,12 @@ +#version 330 core + +// Ouput data +out vec3 color; + +void main() +{ + + // Output color = red + color = vec3(1,0,0); + +} \ No newline at end of file diff --git a/shaders/SimpleVertexShader.vertexshader b/shaders/SimpleVertexShader.vertexshader new file mode 100644 index 0000000..8afde95 --- /dev/null +++ b/shaders/SimpleVertexShader.vertexshader @@ -0,0 +1,12 @@ +#version 330 core + +// Input vertex data, different for all executions of this shader. +layout(location = 0) in vec3 vertexPosition_modelspace; + +void main(){ + + gl_Position.xyz = vertexPosition_modelspace; + gl_Position.w = 1.0; + +} +