Implement matrices
This commit is contained in:
parent
b9ed7c486e
commit
677177cd49
8 changed files with 192 additions and 92 deletions
|
@ -1,6 +1,7 @@
|
||||||
# CMake entry point
|
# CMake entry point
|
||||||
cmake_minimum_required (VERSION 3.0)
|
cmake_minimum_required (VERSION 3.0)
|
||||||
project(OpenGL_Analog_Clock C)
|
project(OpenGL_Analog_Clock C)
|
||||||
|
cmake_policy(SET CMP0072 OLD)
|
||||||
|
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(GLEW REQUIRED)
|
find_package(GLEW REQUIRED)
|
||||||
|
@ -17,7 +18,7 @@ set(ALL_LIBS
|
||||||
GLEW
|
GLEW
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb")
|
set(CMAKE_C_FLAGS "-O0 -ggdb")
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DTW_STATIC
|
-DTW_STATIC
|
||||||
|
@ -29,7 +30,9 @@ add_definitions(
|
||||||
|
|
||||||
add_executable(clock
|
add_executable(clock
|
||||||
src/main.c
|
src/main.c
|
||||||
|
src/clock.c
|
||||||
src/shader.c
|
src/shader.c
|
||||||
|
src/matrix.c
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(clock
|
target_link_libraries(clock
|
||||||
|
|
28
Include/clock.h
Normal file
28
Include/clock.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef CLOCK_H
|
||||||
|
#define CLOCK_H
|
||||||
|
|
||||||
|
// Include standard headers
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
// Include GLEW
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
// Include GLFW
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
// Include project headers
|
||||||
|
#include <shader.h>
|
||||||
|
#include <matrix.h>
|
||||||
|
|
||||||
|
// Define macros
|
||||||
|
#define xfree(p) if (p) free((void *)p)
|
||||||
|
|
||||||
|
// Declare functions
|
||||||
|
|
||||||
|
int clock_init(GLFWwindow **);
|
||||||
|
|
||||||
|
#endif
|
9
Include/matrix.h
Normal file
9
Include/matrix.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef MATRIX_H
|
||||||
|
#define MATRIX_H
|
||||||
|
|
||||||
|
GLdouble *matrix_new(void);
|
||||||
|
|
||||||
|
int matrix_transform(GLdouble *, int,
|
||||||
|
GLdouble **, int);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,7 +1,5 @@
|
||||||
#ifndef SHADER_HPP
|
#ifndef SHADER_H
|
||||||
#define SHADER_HPP
|
#define SHADER_H
|
||||||
|
|
||||||
#define xfree(p) if (p) free((void *)p)
|
|
||||||
|
|
||||||
int LoadShaders(GLuint *, const char *, const char *);
|
int LoadShaders(GLuint *, const char *, const char *);
|
||||||
|
|
||||||
|
|
42
src/clock.c
Normal file
42
src/clock.c
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#include <clock.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
117
src/main.c
117
src/main.c
|
@ -1,64 +1,20 @@
|
||||||
// Include standard headers
|
// Include APIs
|
||||||
#include <stdio.h>
|
#include "clock.h"
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// Include GLEW
|
int main(int argc, char *argv[]) {
|
||||||
#include <GL/glew.h>
|
|
||||||
|
|
||||||
// Include GLFW
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
|
GLFWwindow *window;
|
||||||
GLuint VertexArrayID;
|
GLuint VertexArrayID;
|
||||||
|
GLuint programID;
|
||||||
|
|
||||||
|
if (clock_init(&window)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
glGenVertexArrays(1, &VertexArrayID);
|
glGenVertexArrays(1, &VertexArrayID);
|
||||||
glBindVertexArray(VertexArrayID);
|
glBindVertexArray(VertexArrayID);
|
||||||
|
|
||||||
// Create and compile our GLSL program from the shaders
|
// Create and compile our GLSL program from the shaders
|
||||||
GLuint programID;
|
|
||||||
if (LoadShaders(&programID,
|
if (LoadShaders(&programID,
|
||||||
"../shaders/SimpleVertexShader.vertexshader",
|
"../shaders/SimpleVertexShader.vertexshader",
|
||||||
"../shaders/SimpleFragmentShader.fragmentshader")) {
|
"../shaders/SimpleFragmentShader.fragmentshader")) {
|
||||||
|
@ -66,10 +22,10 @@ int main(void) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLfloat g_vertex_buffer_data[] = {
|
static GLdouble g_vertex_buffer_data[] = {
|
||||||
-1.0f, -1.0f, 1.0f,
|
-0.3f, -0.3f, 0.3f,
|
||||||
1.0f, -1.0f, -1.0f,
|
0.3f, -0.3f, -0.3f,
|
||||||
0.0f, 1.0f, -0.2f
|
0.0f, 0.3f, -0.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint vertexbuffer;
|
GLuint vertexbuffer;
|
||||||
|
@ -77,24 +33,20 @@ int main(void) {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
|
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;
|
double xpos, ypos;
|
||||||
glfwGetCursorPos(window, &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 {
|
do {
|
||||||
// Clear the screen. It's not mentioned before Tutorial 02,
|
// Clear the screen. It's not mentioned before Tutorial 02,
|
||||||
|
@ -103,15 +55,17 @@ int main(void) {
|
||||||
|
|
||||||
// Use our shader
|
// Use our shader
|
||||||
glUseProgram(programID);
|
glUseProgram(programID);
|
||||||
glfwGetCursorPos(window, &xpos, &ypos);
|
//glfwGetCursorPos(window, &xpos, &ypos);
|
||||||
g_vertex_buffer_data[0] = (float)xpos / 1280 * 2 - 1 - 0.15;
|
//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[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[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[4] = 2 - (float)ypos / 720 * 2 - 1 - 0.15;
|
||||||
|
|
||||||
g_vertex_buffer_data[6] = (float)xpos / 1280 * 2 - 1;
|
//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[7] = 2 - (float)ypos / 720 * 2 - 1 + 0.15;
|
||||||
|
matrix_transform(g_vertex_buffer_data, 3,
|
||||||
|
matrices, 1);
|
||||||
|
|
||||||
GLuint vertexbuffer;
|
GLuint vertexbuffer;
|
||||||
glGenBuffers(1, &vertexbuffer);
|
glGenBuffers(1, &vertexbuffer);
|
||||||
|
@ -124,7 +78,7 @@ int main(void) {
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
|
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
|
||||||
3, // size
|
3, // size
|
||||||
GL_FLOAT, // type
|
GL_DOUBLE, // type
|
||||||
GL_FALSE, // normalized?
|
GL_FALSE, // normalized?
|
||||||
0, // stride
|
0, // stride
|
||||||
NULL // array buffer offset
|
NULL // array buffer offset
|
||||||
|
@ -140,6 +94,7 @@ int main(void) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
// Check if the ESC key was pressed or the window was closed
|
// Check if the ESC key was pressed or the window was closed
|
||||||
|
usleep(1000000/60);
|
||||||
} while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
|
} while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
|
||||||
glfwWindowShouldClose(window) == 0);
|
glfwWindowShouldClose(window) == 0);
|
||||||
|
|
||||||
|
|
70
src/matrix.c
Normal file
70
src/matrix.c
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
#include <stdio.h>
|
#include "clock.h"
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <GL/glew.h>
|
|
||||||
|
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
Loading…
Reference in a new issue