summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cube.c39
-rw-r--r--src/cube.h4
-rw-r--r--src/includes.h28
-rw-r--r--src/main.c152
-rw-r--r--src/main.h26
-rw-r--r--src/object.c109
-rw-r--r--src/object.h47
-rw-r--r--src/player.h13
-rw-r--r--src/shader.c39
-rw-r--r--src/shader.h4
-rw-r--r--src/shaders/basic.frag6
-rw-r--r--src/shaders/basic.vert6
-rw-r--r--src/shaders/test.frag10
-rw-r--r--src/shaders/test.vert19
14 files changed, 502 insertions, 0 deletions
diff --git a/src/cube.c b/src/cube.c
new file mode 100644
index 0000000..66723ac
--- /dev/null
+++ b/src/cube.c
@@ -0,0 +1,39 @@
+#include "cube.h"
+
+ViewModel createCube()
+{
+ float vertices[] = {
+ 1.0f, 1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f,
+ -1.0f, -1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f,
+
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, -1.0f, 1.0f,
+ -1.0f, -1.0f, 1.0f,
+ -1.0f, 1.0f, 1.0f
+ };
+ unsigned int indices[] = {
+ 0, 1, 2,
+ 0, 2, 3,
+
+ 4, 5, 6,
+ 4, 6, 7,
+
+ 0, 4, 5,
+ 2, 6, 3,
+
+ 3, 7, 6,
+ 1, 5, 0,
+
+ 3, 7, 0,
+ 0, 4, 7,
+
+ 2, 6, 1,
+ 1, 5, 6
+ };
+
+ ViewModel model;
+ createViewModel(&model, 8, vertices, 38, indices);
+ return model;
+}
diff --git a/src/cube.h b/src/cube.h
new file mode 100644
index 0000000..1e932c8
--- /dev/null
+++ b/src/cube.h
@@ -0,0 +1,4 @@
+#pragma once
+#include "object.h"
+
+ViewModel createCube();
diff --git a/src/includes.h b/src/includes.h
new file mode 100644
index 0000000..efbc626
--- /dev/null
+++ b/src/includes.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <stdio.h>
+#include <stddef.h>
+#include <math.h>
+
+#include <SDL3/SDL_init.h>
+#include <SDL3/SDL_video.h>
+#include <SDL3/SDL_events.h>
+#include <SDL3/SDL_iostream.h>
+#include <SDL3/SDL_time.h>
+#include <SDL3/SDL_timer.h>
+#include <SDL3/SDL_stdinc.h>
+#include <SDL3/SDL_thread.h>
+//#include <SDL3/SDL_image.h>
+
+#include <cglm/cglm.h>
+#include <cglm/mat4.h>
+#include <cglm/vec3.h>
+
+#include <glad/gl.h>
+
+#include <assimp/cimport.h>
+#include <assimp/scene.h>
+#include <assimp/mesh.h>
+#include <assimp/postprocess.h>
+
+#include "player.h"
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..eb655b7
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,152 @@
+#include "includes.h"
+#include "main.h"
+#include "shader.h"
+#include "object.h"
+#include "cube.h"
+
+inline void handleEvents(Game* game)
+{
+ SDL_Event event;
+ SDL_PollEvent(&event);
+ switch (event.type) {
+ case SDL_EVENT_QUIT:
+ game->running = 0;
+ break;
+ }
+}
+
+int initGame(Game* game)
+{
+ game->window_width = 600;
+ game->window_height = 400;
+
+ game->window = SDL_CreateWindow(
+ "OpenGL Test",
+ game->window_width,
+ game->window_height,
+ SDL_WINDOW_OPENGL
+ );
+
+ glm_vec3_zero(game->player.pos);
+
+ // OpenGL stuff starts here
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+ game->gpu = SDL_GL_CreateContext(game->window);
+
+ SDL_GL_MakeCurrent(game->window, game->gpu);
+
+ //VSYNC:
+// SDL_SetWindowSurfaceVSync(game->window, SDL_WINDOW_SURFACE_VSYNC_DISABLED);
+// SDL_GL_SetSwapInterval(0);
+
+ game->running = 1;
+
+ int version = gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress);
+ if (version == 0) {
+ return 1;
+ }
+
+ glEnable(GL_DEPTH_TEST);
+
+ return 0;
+}
+
+int killGame(Game* game)
+{
+ SDL_GL_DestroyContext(game->gpu);
+ SDL_DestroyWindow(game->window);
+ return 0;
+}
+
+void setupProjection(Game* game)
+{
+ glm_perspective(90.0f, ((float)game->window_width)/((float)game->window_height), 0.1f, 40.0f, game->projection);
+
+ glUniformMatrix4fv(game->projection_loc, 1, GL_FALSE, (float*)game->projection);
+}
+
+int main()
+{
+ Game game;
+ initGame(&game);
+
+ unsigned int vertex_shader, fragment_shader, shader_program;
+
+ vertex_shader = loadShader("../src/shaders/test.vert", GL_VERTEX_SHADER);
+ fragment_shader = loadShader("../src/shaders/test.frag", GL_FRAGMENT_SHADER);
+
+ shader_program = shaderProgram(vertex_shader, fragment_shader);
+
+ glClearColor(0.0f, 0.25f, 0.5f, 1.0f);
+
+// TODO: texture loading, will add when sdl 3.4
+//
+// float tex_coords[] = {
+// 1.0f, 1.0f,
+// 1.0f, 0.0f,
+// 0.0f, 0.0f,
+// 0.0f, 1.0f,
+// };
+//
+// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+//
+// float border_color[] = {1.0f, 1.0f, 1.0f, 1.0f};
+// glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
+//
+// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ ViewModel cubeModel = createCube();
+
+ ViewModel pengerModel = loadViewModel("../assets/objects/penger.obj");
+
+ Object myCube;
+
+ Object penger;
+
+ createObject(&myCube, &cubeModel);
+
+ createObject(&penger, &pengerModel);
+
+ moveObject(&penger, (vec3){0.0f, -0.5f, -1.0f});
+
+ scaleObject(&penger, (vec3){1.0f, 1.0f, 1.0f});
+
+ game.transform_loc = glGetUniformLocation(shader_program, "model");
+ game.projection_loc = glGetUniformLocation(shader_program, "projection");
+
+ SDL_Time time;
+
+// Enable/disable wireframe rendering:
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+ glUseProgram(shader_program);
+
+ setupProjection(&game);
+
+ bindViewModel(&pengerModel);
+ while (game.running) {
+ for (int i=0;i<628;i++) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ rotateObject(&penger, (float)i/100, (vec3){0.0f, 1.0f, 0.0f});
+ drawObject(&game, &penger);
+
+ SDL_GL_SwapWindow(game.window);
+
+ handleEvents(&game);
+ }
+
+ }
+
+ killViewModel(&pengerModel);
+ killViewModel(&cubeModel);
+ glDeleteShader(vertex_shader);
+ glDeleteShader(fragment_shader);
+ killGame(&game);
+ return 0;
+}
diff --git a/src/main.h b/src/main.h
new file mode 100644
index 0000000..389957b
--- /dev/null
+++ b/src/main.h
@@ -0,0 +1,26 @@
+#pragma once
+#include "includes.h"
+
+typedef struct {
+ SDL_Window *window;
+
+ int window_width;
+ int window_height;
+
+ mat4 projection;
+
+ SDL_GLContext gpu;
+
+ int transform_loc, projection_loc;
+
+ int running;
+
+ Player player;
+} Game;
+
+void handleEvents(Game* game);
+
+void setupProjection(float fov, Game* game);
+
+int initGame(Game* game);
+int killGame(Game* game);
diff --git a/src/object.c b/src/object.c
new file mode 100644
index 0000000..25d504f
--- /dev/null
+++ b/src/object.c
@@ -0,0 +1,109 @@
+#include "object.h"
+
+void createViewModel(ViewModel *model, int num_vertices, float *vert, int num_indices, unsigned int *indices)
+{
+ model->num_indices = num_indices;
+
+ glGenVertexArrays(1, &model->VAO);
+ glBindVertexArray(model->VAO);
+
+ glGenBuffers(1, &model->VBO);
+ glBindBuffer(GL_ARRAY_BUFFER, model->VBO);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_vertices*3, vert, GL_STATIC_DRAW);
+
+ glGenBuffers(1, &model->EBO);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->EBO);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*num_indices, indices, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+}
+
+void killViewModel(ViewModel *model)
+{
+ glDeleteVertexArrays(1, &model->VAO);
+ glDeleteBuffers(1, &model->VBO);
+ glDeleteBuffers(1, &model->EBO);
+}
+
+void bindViewModel(ViewModel *model)
+{
+ glBindVertexArray(model->VAO);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->EBO);
+}
+
+ViewModel loadViewModel(const char* filename)
+{
+ const struct aiScene* scene = aiImportFile(filename,
+ aiProcess_CalcTangentSpace |
+ aiProcess_Triangulate |
+ aiProcess_JoinIdenticalVertices |
+ aiProcess_SortByPType);
+
+ struct aiMesh *mesh = scene->mMeshes[0];
+
+ unsigned int *indices = malloc(mesh->mNumFaces*3*sizeof(unsigned int));
+ int index = 0;
+ for (unsigned int i=0;i<mesh->mNumFaces;i++) {
+ memcpy(&indices[index], mesh->mFaces[i].mIndices, 3*sizeof(unsigned int));
+ index+=3;
+ }
+
+ ViewModel model;
+ createViewModel(&model, mesh->mNumVertices, (float*)mesh->mVertices, mesh->mNumFaces*3, indices);
+ free(indices);
+ return model;
+}
+
+void createObject(Object *obj, ViewModel *model)
+{
+ obj->model = model;
+ glm_mat4_identity(obj->transform);
+
+ glm_vec3_zero(obj->pos);
+ glm_vec3_one(obj->size);
+
+ obj->rotation.angle = 0.0f;
+ glm_vec3_zero(obj->rotation.direction);
+}
+
+void moveObject(Object *obj, vec3 pos)
+{
+ glm_vec3_copy(
+ pos,
+ obj->pos
+ );
+ updateObjectTransform(obj);
+}
+
+void scaleObject(Object *obj, vec3 scale)
+{
+ glm_scale(obj->transform, scale);
+ updateObjectTransform(obj);
+}
+
+void rotateObject(Object *obj, float angle, vec3 direction)
+{
+ obj->rotation.angle = angle;
+ glm_vec3_copy(
+ direction,
+ obj->rotation.direction
+ );
+ updateObjectTransform(obj);
+}
+
+inline void updateObjectTransform(Object *obj)
+{
+ glm_mat4_identity(obj->transform);
+ glm_translate(obj->transform, obj->pos);
+ glm_rotate(obj->transform, obj->rotation.angle, obj->rotation.direction);
+ glm_scale(obj->transform, obj->size);
+}
+
+void drawObject(Game *game, Object *obj)
+{
+ glUniformMatrix4fv(game->transform_loc, 1, GL_FALSE, (float*)obj->transform);
+
+ glDrawElements(GL_TRIANGLES, obj->model->num_indices, GL_UNSIGNED_INT, 0);
+}
diff --git a/src/object.h b/src/object.h
new file mode 100644
index 0000000..b4cc06d
--- /dev/null
+++ b/src/object.h
@@ -0,0 +1,47 @@
+#pragma once
+#include "main.h"
+#include "includes.h"
+
+typedef struct {
+ float angle;
+ vec3 direction;
+} Rotation;
+
+typedef struct {
+ int num_indices;
+
+ unsigned int VAO, VBO, EBO;
+} ViewModel;
+
+typedef struct {
+ ViewModel *model;
+
+ vec3 pos, size;
+
+ Rotation rotation;
+
+ mat4 transform;
+} Object;
+
+void createViewModel(ViewModel *model, int num_vertices, float *vert, int num_indices, unsigned int *indices);
+
+void killViewModel(ViewModel *model);
+
+void bindViewModel(ViewModel *model);
+
+ViewModel loadViewModel(const char* filename);
+
+void createObject(Object *obj, ViewModel *model);
+
+
+void moveObject(Object *obj, vec3 pos);
+
+void scaleObject(Object *obj, vec3 scale);
+
+void rotateObject(Object *obj, float angle, vec3 direction);
+
+
+void updateObjectTransform(Object *obj);
+
+
+void drawObject(Game *game, Object *obj);
diff --git a/src/player.h b/src/player.h
new file mode 100644
index 0000000..f81760c
--- /dev/null
+++ b/src/player.h
@@ -0,0 +1,13 @@
+#pragma once
+
+typedef struct {
+ vec3 pos;
+ vec3 target;
+ vec3 direction;
+ vec3 up;
+} Camera;
+
+typedef struct {
+ vec3 pos;
+ Camera camera;
+} Player;
diff --git a/src/shader.c b/src/shader.c
new file mode 100644
index 0000000..022879e
--- /dev/null
+++ b/src/shader.c
@@ -0,0 +1,39 @@
+#include "shader.h"
+#include "includes.h"
+
+unsigned int loadShader(const char* filename, unsigned int shadertype)
+{
+ void* shader_source = SDL_LoadFile(filename, NULL);
+ unsigned int shader = glCreateShader(shadertype);
+ glShaderSource(shader, 1, (const char**)&shader_source, NULL);
+ glCompileShader(shader);
+ SDL_free(shader_source);
+
+ int success;
+
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
+ if (!success) {
+ printf("Couldn't compile shader\n");
+ return 0;
+ }
+
+ return shader;
+}
+
+unsigned int shaderProgram(unsigned int vertex_shader, unsigned int fragment_shader)
+{
+ unsigned int shader_program;
+ shader_program = glCreateProgram();
+ glAttachShader(shader_program, vertex_shader);
+ glAttachShader(shader_program, fragment_shader);
+ glLinkProgram(shader_program);
+
+ int success;
+ glGetProgramiv(shader_program, GL_LINK_STATUS, &success);
+ if (!success) {
+ printf("Couldn't link shader program\n");
+ return 0;
+ }
+
+ return shader_program;
+}
diff --git a/src/shader.h b/src/shader.h
new file mode 100644
index 0000000..3bb9421
--- /dev/null
+++ b/src/shader.h
@@ -0,0 +1,4 @@
+#pragma once
+
+unsigned int loadShader(const char* filename, unsigned int shadertype);
+unsigned int shaderProgram(unsigned int vertex_shader, unsigned int fragment_shader);
diff --git a/src/shaders/basic.frag b/src/shaders/basic.frag
new file mode 100644
index 0000000..00d2a13
--- /dev/null
+++ b/src/shaders/basic.frag
@@ -0,0 +1,6 @@
+#version 330 core
+out vec4 FragColor;
+void main()
+{
+ FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
+}
diff --git a/src/shaders/basic.vert b/src/shaders/basic.vert
new file mode 100644
index 0000000..684ddbb
--- /dev/null
+++ b/src/shaders/basic.vert
@@ -0,0 +1,6 @@
+#version 330 core
+layout (location = 0) in vec3 aPos;
+void main()
+{
+ gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
+}
diff --git a/src/shaders/test.frag b/src/shaders/test.frag
new file mode 100644
index 0000000..cd2ee4c
--- /dev/null
+++ b/src/shaders/test.frag
@@ -0,0 +1,10 @@
+#version 330 core
+
+out vec4 FragColor;
+
+in vec4 vertexColor;
+
+void main()
+{
+ FragColor = vertexColor;
+}
diff --git a/src/shaders/test.vert b/src/shaders/test.vert
new file mode 100644
index 0000000..851352d
--- /dev/null
+++ b/src/shaders/test.vert
@@ -0,0 +1,19 @@
+#version 330 core
+
+layout (location = 0) in vec3 aPos;
+
+uniform mat4 projection;
+uniform mat4 model;
+
+out vec4 vertexColor;
+
+void main()
+{
+ vec4 v = vec4(aPos, 1.0);
+ vec4 newPosition = model * v;
+ vec4 projectedPosition = projection * newPosition;
+ gl_Position = projectedPosition ;
+
+// gl_Position = u_mvp * vec4(aPos, 1.0);
+ vertexColor = vec4(0.0, 0.5, 0.0, 1.0);
+}