Techneck/code/source-c/main.c

351 lines
9.2 KiB
C

#include <glad/glad.h>
#include <SDL2/SDL.h>
#include <stdbool.h>
#include <linmath.h>
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_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)
{
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);
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);
// 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);
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);
}
++frame_index;
SDL_Delay(1000/60);
}
cleanup();
SDL_Quit();
return 0;
}