219 lines
5.5 KiB
C
219 lines
5.5 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;
|
||
|
|
||
|
float triangle_vertices[9] = {
|
||
|
0.0f, 0.0f, 0.0f,
|
||
|
0.0f, 1.0f, 0.0f,
|
||
|
1.0f, 0.0f, 0.0f
|
||
|
};
|
||
|
|
||
|
typedef struct tc_vec3
|
||
|
{
|
||
|
float x;
|
||
|
float y;
|
||
|
float z;
|
||
|
|
||
|
} tc_vec3_s;
|
||
|
|
||
|
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);
|
||
|
glUseProgram(main_shader);
|
||
|
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);
|
||
|
|
||
|
render_block(block);
|
||
|
|
||
|
SDL_GL_SwapWindow(window);
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
{
|
||
|
SDL_Event event;
|
||
|
while(SDL_PollEvent(&event))
|
||
|
{
|
||
|
switch(event.type)
|
||
|
{
|
||
|
case SDL_QUIT:
|
||
|
SDL_HideWindow(window);
|
||
|
frame_index = -1;
|
||
|
break;
|
||
|
break;
|
||
|
|
||
|
case SDL_WINDOWEVENT:
|
||
|
{
|
||
|
if(event.window.event == SDL_WINDOWEVENT_RESIZED)
|
||
|
{
|
||
|
puts("RESIZED");
|
||
|
}
|
||
|
} break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
render();
|
||
|
|
||
|
if(frame_index == 1)
|
||
|
{
|
||
|
SDL_ShowWindow(window);
|
||
|
}
|
||
|
|
||
|
++frame_index;
|
||
|
SDL_Delay(1000/60);
|
||
|
}
|
||
|
|
||
|
cleanup();
|
||
|
SDL_Quit();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|