#include #include #include #include SDL_Window *window = NULL; SDL_GLContext gl_context; int main_shader = 0; mat4x4 projection_matrix; mat4x4 view_matrix; float triangle_vertices[9] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, -1.0f }; typedef struct tc_vec3 { float x; float y; float z; } tc_vec3_s; tc_vec3_s tc_camera_position = { 0.0f, 0.0f, 0.0f }; tc_vec3_s tc_camera_rotation = { 0.0f, 0.0f, 0.0f }; typedef struct tc_object { int vbo; int vao; tc_vec3_s position; tc_vec3_s rotation; } tc_object_s; typedef struct tc_block { tc_vec3_s position; tc_object_s drawing; } tc_block_s; tc_block_s block; void render_block(tc_block_s block) { mat4x4 model_matrix; mat4x4_translate(model_matrix, block.position.x, block.position.y, block.position.z); // mat4x4_rotate_X(view_matrix, model_matrix, block.rotation.x); // mat4x4_rotate_Y(view_matrix, model_matrix, block.rotation.y); // mat4x4_rotate_Z(view_matrix, model_matrix, block.rotation.z); int model_matrix_uniform_location = glGetUniformLocation(main_shader, "model_matrix"); glUniformMatrix4fv(model_matrix_uniform_location, 1, GL_FALSE, &model_matrix[0][0]); glBindBuffer(GL_ARRAY_BUFFER, block.drawing.vbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLES, 0, 3); } tc_block_s tc_new_block_at_3f(float x, float y, float z) { tc_block_s block; block.position.x = x; block.position.y = y; block.position.z = z; glGenBuffers(1, &block.drawing.vbo); glBindBuffer(GL_ARRAY_BUFFER, block.drawing.vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 9, &triangle_vertices[0], GL_STATIC_DRAW); return block; } char * load_file(char *path, int *out_len) { FILE *file = NULL; if((file = fopen(path, "r")) != NULL) { fseek(file, 0, SEEK_END); int length = ftell(file); fseek(file, 0, SEEK_SET); char *content = malloc(length+1); fread(content, 1, length, file); if(out_len != NULL) { *out_len = length; } return content; } return NULL; } int setup_shaders(char *vertex_path, char *fragment_path) { int vertex_shader = glCreateShader(GL_VERTEX_SHADER); int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); int len_vertex_source = 0; char *vertex_source = load_file(vertex_path, &len_vertex_source); int len_fragment_source = 0; char *fragment_source = load_file(fragment_path, &len_fragment_source); glShaderSource(vertex_shader, 1, &vertex_source, &len_vertex_source); glShaderSource(fragment_shader, 1, &fragment_source, &len_fragment_source); glCompileShader(vertex_shader); glCompileShader(fragment_shader); int vertex_compile_status = 0; glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &vertex_compile_status); if(vertex_compile_status != GL_TRUE) { int log_length = 0; glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &log_length); char *info_log = malloc(log_length+1); glGetShaderInfoLog(vertex_shader, log_length, &log_length, info_log); printf("VERTEX SHADER FAILED COMPILING! ERROR: %s\n", info_log); return -1; } int fragment_compile_status = 0; glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &fragment_compile_status); if(fragment_compile_status != GL_TRUE) { int log_length = 0; glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &log_length); char *info_log = malloc(log_length+1); glGetShaderInfoLog(fragment_shader, log_length, &log_length, info_log); printf("FRAGMENT SHADER FAILED COMPILING! ERROR: %s\n", info_log); return -1; } int program = glCreateProgram(); glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); glLinkProgram(program); return program; } void cleanup() { SDL_GL_DeleteContext(gl_context); SDL_DestroyWindow(window); } void render() { float color[4] = { 0.0f, 1.0f, 0.0f, 1.0f }; glClearBufferfv(GL_COLOR, 0, color); mat4x4_perspective(projection_matrix, 120, 1200 / 800, 0.0001f, 1000.0f); mat4x4_translate(view_matrix, -tc_camera_position.x, -tc_camera_position.y, tc_camera_position.z); // mat4x4_rotate_X(view_matrix, view_matrix, tc_camera_rotation.x); // mat4x4_rotate_Y(view_matrix, view_matrix, tc_camera_rotation.y); // mat4x4_rotate_Z(view_matrix, view_matrix, tc_camera_rotation.z); glUseProgram(main_shader); int projection_uniform_location = glGetUniformLocation(main_shader, "projection_matrix"); glUniformMatrix4fv(projection_uniform_location, 1, GL_FALSE, &projection_matrix[0][0]); int view_uniform_location = glGetUniformLocation(main_shader, "view_matrix"); glUniformMatrix4fv(view_uniform_location, 1, GL_FALSE, &view_matrix[0][0]); // printf("%d\n", view_uniform_location); render_block(block); SDL_GL_SwapWindow(window); } bool shift_pressed = false; bool go_up = false; bool go_left = false; bool go_right = false; bool go_forward = false; bool go_backwards = false; bool update() { SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: SDL_HideWindow(window); return false; break; case SDL_WINDOWEVENT: { if(event.window.event == SDL_WINDOWEVENT_RESIZED) { puts("RESIZED"); } } break; case SDL_KEYDOWN: if(event.key.keysym.scancode == SDL_SCANCODE_W) { go_forward = true; } if(event.key.keysym.scancode == SDL_SCANCODE_S) { go_backwards = true; } if(event.key.keysym.scancode == SDL_SCANCODE_A) { go_left = true; } if(event.key.keysym.scancode == SDL_SCANCODE_D) { go_right = true;; } if(event.key.keysym.scancode == SDL_SCANCODE_SPACE) { go_up = true; } if(event.key.keysym.scancode == SDL_SCANCODE_LSHIFT) { shift_pressed = true; } break; case SDL_KEYUP: if(event.key.keysym.scancode == SDL_SCANCODE_W) { go_forward = false; } if(event.key.keysym.scancode == SDL_SCANCODE_S) { go_backwards = false; } if(event.key.keysym.scancode == SDL_SCANCODE_A) { go_left = false; } if(event.key.keysym.scancode == SDL_SCANCODE_D) { go_right = false;; } if(event.key.keysym.scancode == SDL_SCANCODE_SPACE) { go_up = false; } if(event.key.keysym.scancode == SDL_SCANCODE_LSHIFT) { shift_pressed = false; } break; } } if(shift_pressed) { tc_camera_position.y -= 0.25; } if(go_up) { tc_camera_position.y += 0.25; } if(go_left) { tc_camera_position.x -= 0.25; } if(go_right) { tc_camera_position.x += 0.25; } if(go_forward) { tc_camera_position.z += 0.25; } if(go_backwards) { tc_camera_position.z -= 0.25; } return true; } int main(int argc, char **argv) { SDL_Init(SDL_INIT_EVERYTHING); window = SDL_CreateWindow( "Techneck", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1200, 800, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE ); gl_context = SDL_GL_CreateContext(window); gladLoadGLLoader(&SDL_GL_GetProcAddress); gladLoadGL(); main_shader = setup_shaders("vertex_shader.glsl", "fragment_shader.glsl"); block = tc_new_block_at_3f(0.0, 0.0, 0.0); int64_t frame_index = 1; while(frame_index > 0) { if(!update()) { frame_index = -1; } render(); if(frame_index == 1) { SDL_ShowWindow(window); } block.position.x += 0.1f; ++frame_index; SDL_Delay(1000/60); } cleanup(); SDL_Quit(); return 0; }