diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c752a8..7a8f9e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ # CMake entry point cmake_minimum_required (VERSION 3.0) project(OpenGL_Analog_Clock C) +cmake_policy(SET CMP0072 OLD) find_package(OpenGL REQUIRED) find_package(GLEW REQUIRED) @@ -17,7 +18,7 @@ set(ALL_LIBS GLEW ) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb") +set(CMAKE_C_FLAGS "-O0 -ggdb") add_definitions( -DTW_STATIC @@ -29,7 +30,9 @@ add_definitions( add_executable(clock src/main.c + src/clock.c src/shader.c + src/matrix.c ) target_link_libraries(clock diff --git a/Include/clock.h b/Include/clock.h new file mode 100644 index 0000000..c1046d7 --- /dev/null +++ b/Include/clock.h @@ -0,0 +1,28 @@ +#ifndef CLOCK_H +#define CLOCK_H + +// Include standard headers +#include +#include +#include +#include +#include + +// Include GLEW +#include + +// Include GLFW +#include + +// Include project headers +#include +#include + +// Define macros +#define xfree(p) if (p) free((void *)p) + +// Declare functions + +int clock_init(GLFWwindow **); + +#endif diff --git a/Include/matrix.h b/Include/matrix.h new file mode 100644 index 0000000..80eb229 --- /dev/null +++ b/Include/matrix.h @@ -0,0 +1,9 @@ +#ifndef MATRIX_H +#define MATRIX_H + +GLdouble *matrix_new(void); + +int matrix_transform(GLdouble *, int, + GLdouble **, int); + +#endif diff --git a/Include/shader.h b/Include/shader.h index b2d381b..6d8b68a 100644 --- a/Include/shader.h +++ b/Include/shader.h @@ -1,7 +1,5 @@ -#ifndef SHADER_HPP -#define SHADER_HPP - -#define xfree(p) if (p) free((void *)p) +#ifndef SHADER_H +#define SHADER_H int LoadShaders(GLuint *, const char *, const char *); diff --git a/src/clock.c b/src/clock.c new file mode 100644 index 0000000..592713f --- /dev/null +++ b/src/clock.c @@ -0,0 +1,42 @@ +#include + +int clock_init(GLFWwindow **window) { + // Initialise GLFW + if(!glfwInit()) { + fprintf(stderr, "Failed to initialize GLFW\n"); + getchar(); + return -1; + } + + glfwWindowHint(GLFW_SAMPLES, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + // Open a window and create its OpenGL context + *window = glfwCreateWindow(1280, 720, "OpenGL Clock", NULL, NULL); + if (*window == NULL) { + fprintf(stderr, "Failed to open GLFW window.\n"); + glfwTerminate(); + return -1; + } + + glfwMakeContextCurrent(*window); + + // Initialize GLEW + if (glewInit() != GLEW_OK) { + fprintf(stderr, "Failed to initialize GLEW\n"); + glfwTerminate(); + return -1; + } + + // Ensure we can capture the escape key being pressed below + glfwSetInputMode(*window, GLFW_STICKY_KEYS, GL_TRUE); + + // Dark grey background + glClearColor(0.15f, 0.15f, 0.15f, 0.0f); + + return 0; +} + diff --git a/src/main.c b/src/main.c index 53b2015..344ab96 100644 --- a/src/main.c +++ b/src/main.c @@ -1,64 +1,20 @@ -// Include standard headers -#include -#include +// Include APIs +#include "clock.h" -// Include GLEW -#include - -// Include GLFW -#include - -// Include shader -#include "shader.h" - -static GLFWwindow* window; - -int main(void) { - - // Initialise GLFW - if(!glfwInit()) { - fprintf(stderr, "Failed to initialize GLFW\n"); - getchar(); - return -1; - } - - glfwWindowHint(GLFW_SAMPLES, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - - // Open a window and create its OpenGL context - window = glfwCreateWindow(1280, 720, "OpenGL Clock", NULL, NULL); - if (window == NULL) { - fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n"); - getchar(); - glfwTerminate(); - return -1; - } - - glfwMakeContextCurrent(window); - - // Initialize GLEW - if (glewInit() != GLEW_OK) { - fprintf(stderr, "Failed to initialize GLEW\n"); - getchar(); - glfwTerminate(); - return -1; - } - - // Ensure we can capture the escape key being pressed below - glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); - - // Dark grey background - glClearColor(0.15f, 0.15f, 0.15f, 0.0f); +int main(int argc, char *argv[]) { + GLFWwindow *window; GLuint VertexArrayID; + GLuint programID; + + if (clock_init(&window)) { + return -1; + } + glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); // Create and compile our GLSL program from the shaders - GLuint programID; if (LoadShaders(&programID, "../shaders/SimpleVertexShader.vertexshader", "../shaders/SimpleFragmentShader.fragmentshader")) { @@ -66,10 +22,10 @@ int main(void) { return -1; } - static GLfloat g_vertex_buffer_data[] = { - -1.0f, -1.0f, 1.0f, - 1.0f, -1.0f, -1.0f, - 0.0f, 1.0f, -0.2f + static GLdouble g_vertex_buffer_data[] = { + -0.3f, -0.3f, 0.3f, + 0.3f, -0.3f, -0.3f, + 0.0f, 0.3f, -0.0f }; GLuint vertexbuffer; @@ -77,24 +33,20 @@ int main(void) { glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); - // position - double a[3]; - a[0] = 0; - a[1] = 0; - a[2] = 0; - // horizontal angle : toward -Z - double horizontalAngle = 3.14f; - // vertical angle : 0, look at the horizon - double verticalAngle = 0.0f; - // Initial Field of View - double initialFoV = 45.0f; - - double speed = 3.0f; // 3 units / second - double mouseSpeed = 0.005f; - // Get mouse position double xpos, ypos; glfwGetCursorPos(window, &xpos, &ypos); + GLdouble **matrices = calloc(1, sizeof(GLdouble *)); + + GLdouble *rot_mat = matrix_new(); + + rot_mat[0] = cos(M_PI*2/60); + rot_mat[1] = -sin(M_PI*2/60); + rot_mat[4] = sin(M_PI*2/60); + rot_mat[5] = cos(M_PI*2/60); + + *matrices = rot_mat; + do { // Clear the screen. It's not mentioned before Tutorial 02, @@ -103,15 +55,17 @@ int main(void) { // Use our shader glUseProgram(programID); - glfwGetCursorPos(window, &xpos, &ypos); - g_vertex_buffer_data[0] = (float)xpos / 1280 * 2 - 1 - 0.15; - g_vertex_buffer_data[1] = 2 - (float)ypos / 720 * 2 - 1 - 0.15; + //glfwGetCursorPos(window, &xpos, &ypos); + //g_vertex_buffer_data[0] = (float)xpos / 1280 * 2 - 1 - 0.15; + //g_vertex_buffer_data[1] = 2 - (float)ypos / 720 * 2 - 1 - 0.15; - g_vertex_buffer_data[3] = (float)xpos / 1280 * 2 - 1 + 0.15; - g_vertex_buffer_data[4] = 2 - (float)ypos / 720 * 2 - 1 - 0.15; + //g_vertex_buffer_data[3] = (float)xpos / 1280 * 2 - 1 + 0.15; + //g_vertex_buffer_data[4] = 2 - (float)ypos / 720 * 2 - 1 - 0.15; - g_vertex_buffer_data[6] = (float)xpos / 1280 * 2 - 1; - g_vertex_buffer_data[7] = 2 - (float)ypos / 720 * 2 - 1 + 0.15; + //g_vertex_buffer_data[6] = (float)xpos / 1280 * 2 - 1; + //g_vertex_buffer_data[7] = 2 - (float)ypos / 720 * 2 - 1 + 0.15; + matrix_transform(g_vertex_buffer_data, 3, + matrices, 1); GLuint vertexbuffer; glGenBuffers(1, &vertexbuffer); @@ -124,7 +78,7 @@ int main(void) { glVertexAttribPointer( 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. 3, // size - GL_FLOAT, // type + GL_DOUBLE, // type GL_FALSE, // normalized? 0, // stride NULL // array buffer offset @@ -140,6 +94,7 @@ int main(void) { glfwPollEvents(); // Check if the ESC key was pressed or the window was closed + usleep(1000000/60); } while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0); diff --git a/src/matrix.c b/src/matrix.c new file mode 100644 index 0000000..92fa0fb --- /dev/null +++ b/src/matrix.c @@ -0,0 +1,70 @@ +#include "clock.h" + +static GLdouble * +matrix_multip(GLdouble *mat1, GLdouble *mat2) { + GLdouble *result; + GLdouble dot_prod; + + result = matrix_new(); + + for (int i = 0; i < 4; i++) { + + for (int j = 0; j < 4; j++) { + dot_prod = 0; + for (int k = 0; k < 4; k++) { + dot_prod += mat1[i*4+k] * mat2[j+k*4]; + } + result[j+i*4] = dot_prod; + } + } + + return result; +} + +GLdouble * +matrix_new() { + GLdouble *mat; + + mat = calloc(16, sizeof(GLdouble)); + + for (int i = 0; i < 4; i++) { + mat[i*4+i] = 1; + } + + return mat; +} + + +int +matrix_transform(GLdouble *vects, int vectcount, + GLdouble **mats, int matcount) { + GLdouble *mat; + GLdouble dot_prod; + GLdouble *helper = NULL; + GLdouble *result; + + mat = matrix_new(); + result = calloc(vectcount*3, sizeof(GLdouble)); + + for (int i = matcount-1; i >= 0; i--) { + xfree(helper); + helper = matrix_multip(mats[i], mat); + free(mat); + mat = helper; + } + + for (int k = 0; k < vectcount; k++) { + for (int j = 0; j < 3; j++) { + dot_prod = 0; + for (int i = 0; i < 3; i++) { + dot_prod += vects[k*3+i] * mat[i+j*4]; + } + result[j+k*3] = dot_prod; + } + } + memcpy(vects, result, vectcount * 3 * sizeof(GLdouble)); + free(result); + + return 0; +} + diff --git a/src/shader.c b/src/shader.c index 75ac32b..e11d36a 100644 --- a/src/shader.c +++ b/src/shader.c @@ -1,9 +1,4 @@ -#include -#include -#include - -#include - +#include "clock.h" #include "shader.h" static int