From f78c7eb549b2a316d0de547fb62ed678e63c6f54 Mon Sep 17 00:00:00 2001 From: ktyl Date: Sun, 4 Jul 2021 02:53:37 +0100 Subject: [PATCH] hello triangle --- makefile | 31 ++++++++++++++++ res/shader/shader.frag | 7 ++++ res/shader/shader.vert | 7 ++++ res/tex.png | 3 ++ src/gfx.c | 80 ++++++++++++++++++++++++++++++++++++++++++ src/gfx.h | 20 +++++++++++ src/io.c | 40 +++++++++++++++++++++ src/io.h | 8 +++++ src/main.c | 79 +++++++++++++++++++++++++++++++++++++++++ src/main.h | 1 + todo.md | 3 ++ 11 files changed, 279 insertions(+) create mode 100644 makefile create mode 100644 res/shader/shader.frag create mode 100644 res/shader/shader.vert create mode 100644 res/tex.png create mode 100644 src/gfx.c create mode 100644 src/gfx.h create mode 100644 src/io.c create mode 100644 src/io.h create mode 100644 src/main.c create mode 100644 src/main.h create mode 100644 todo.md diff --git a/makefile b/makefile new file mode 100644 index 0000000..08d8984 --- /dev/null +++ b/makefile @@ -0,0 +1,31 @@ +SRC_DIR = src +BIN_DIR = bin +RES_DIR = res + +TARGET = $(BIN_DIR)/oglc +CC = gcc +LIBS = `pkg-config --static --libs glew sdl2` +CFLAGS = -I$(SRC_DIR) -Wall + +SRC = $(shell find $(SRC_DIR) -name *.c) +OBJ = $(SRC:%.c=%.o) + +# create dirs if they dont exist +_dummy := $(shell mkdir -p $(BIN_DIR)) + +$(TARGET): $(OBJ) + $(CC) $(CFLAGS) -o $@ $^ $(LIBS) + cp -r $(RES_DIR) $(BIN_DIR) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + -rm -r $(BIN_DIR) + -rm */*.o + +run: $(TARGET) + $(TARGET) + + +.PHONY: run clean diff --git a/res/shader/shader.frag b/res/shader/shader.frag new file mode 100644 index 0000000..0c56a32 --- /dev/null +++ b/res/shader/shader.frag @@ -0,0 +1,7 @@ +#version 330 core +out vec4 FragColor; + +void main() +{ + FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); +} diff --git a/res/shader/shader.vert b/res/shader/shader.vert new file mode 100644 index 0000000..c74ea10 --- /dev/null +++ b/res/shader/shader.vert @@ -0,0 +1,7 @@ +#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/res/tex.png b/res/tex.png new file mode 100644 index 0000000..b983971 --- /dev/null +++ b/res/tex.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:94a4eea9b39f31fa150c4ce82786b0fb7428e4b61257581c458c3ef01956f8a7 +size 1115422 diff --git a/src/gfx.c b/src/gfx.c new file mode 100644 index 0000000..fd498ca --- /dev/null +++ b/src/gfx.c @@ -0,0 +1,80 @@ +#include "gfx.h" + +SDL_Window* createWindow() +{ + // load sdl modules + if (SDL_Init(SDL_INIT_VIDEO) != 0) + { + printf("%s\n", "unable to set video mode"); + exit(1); + } + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + + SDL_Window* window = SDL_CreateWindow( + "oglc", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + 800, + 600, + SDL_WINDOW_OPENGL); + + return window; +} + +struct GraphicsContext createContext() +{ + SDL_Window* window = createWindow(); + + SDL_GLContext context = SDL_GL_CreateContext(window); + + glewExperimental = GL_TRUE; + glewInit(); + + struct GraphicsContext ctx = {window, context}; + + return ctx; +} + +GLuint compileShader(const char* path, GLenum type) +{ + // read shader file into buffer + char* buffer; + buffer = calloc(1, getFileSize(path)+1); // calloc -> contiguous allocation + readFile(path, buffer); + + GLuint shader = glCreateShader(type); + GLint result = GL_FALSE; + int logLength; + + // compile + const char* src = buffer; // glShaderSource expects a const char* + + glShaderSource(shader, 1, &src, NULL); + glCompileShader(shader); + + free(buffer); + + // check + glGetShaderiv(shader, GL_COMPILE_STATUS, &result); + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); + + char err[logLength]; + glGetShaderInfoLog(shader, logLength, NULL, err); + if (logLength > 1) + { + fputs("error compiling shader ", stderr); + fputs(path, stderr); + fputs(":\n", stderr); + fputs(err, stderr); + + exit(1); + } + + printf(":: . compiled shader %s! :D\n", path); + + return shader; +} diff --git a/src/gfx.h b/src/gfx.h new file mode 100644 index 0000000..e7a5fc5 --- /dev/null +++ b/src/gfx.h @@ -0,0 +1,20 @@ +#pragma once + +#define GLEW_STATIC +#include "GL/glew.h" + +#include +#include + +#include "io.h" + +struct GraphicsContext +{ + SDL_Window* window; + SDL_GLContext* context; +}; + +SDL_Window* createWindow(); +struct GraphicsContext createContext(); +GLuint compileShader(const char* path, GLenum type); + diff --git a/src/io.c b/src/io.c new file mode 100644 index 0000000..dad5b20 --- /dev/null +++ b/src/io.c @@ -0,0 +1,40 @@ +#include "io.h" + +long getFileSize(const char* path) +{ + FILE* fp; + long fSize; + + // open file and die if u cant + fp = fopen(path, "r"); + if (!fp) perror(path), exit(1); + + // seek the end of the file to find its length, then back to the start + fseek(fp, 0L, SEEK_END); // TODO: look @ fseek docs + fSize = ftell(fp); // TODO: look @ ftell docs + rewind(fp); + + // close the file + fclose(fp); + + return fSize; +} + +void readFile(const char* path, char* buffer) +{ + FILE* fp; + long fSize = getFileSize(path); + + // open file, throw if it doesnt exist + fp = fopen(path, "r"); + if (!fp) perror(path), exit(1); + + if (!buffer) fclose(fp), fputs("memory alloc fails", stderr), exit(1); + + // copy the file into the buffer + if (1!=fread(buffer, fSize, 1, fp)) // TODO: fread? + fclose(fp), free(buffer), fputs("entire read fails", stderr), exit(1); + + // close file now that it has been read into a buffer + fclose(fp); +} diff --git a/src/io.h b/src/io.h new file mode 100644 index 0000000..9554b87 --- /dev/null +++ b/src/io.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include + +long getFileSize(const char* path); +void readFile(const char* path, char* buffer); + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..10e14ba --- /dev/null +++ b/src/main.c @@ -0,0 +1,79 @@ +#include "main.h" + +#include "gfx.h" + +// data ! +const char* vertShaderPath = "res/shader/shader.vert"; +const char* fragShaderPath = "res/shader/shader.frag"; + +float vertices[] = { + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.0f, 0.5f, 0.0f +}; + +// forward declarations +int checkQuit(); + + +int main() +{ + // initialise opengl graphics context + const struct GraphicsContext ctx = createContext(); + + // compile shaders + printf(":: compiling shaders\n"); + GLuint vertShader = compileShader(vertShaderPath, GL_VERTEX_SHADER); + GLuint fragShader = compileShader(fragShaderPath, GL_FRAGMENT_SHADER); + + printf(":: linking shader program\n"); + unsigned int shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, vertShader); + glAttachShader(shaderProgram, fragShader); + glLinkProgram(shaderProgram); + + glDeleteShader(vertShader); + glDeleteShader(fragShader); + + // TODO: check program linking success + + // set up vertex array object + unsigned int VAO; + glGenVertexArrays(1, &VAO); + + // set up vertex buffer object + unsigned int VBO; + glGenBuffers(1, &VBO); + + glBindVertexArray(VAO); + + // copy our vertices into a buffer opengl can use + glBindBuffer(GL_ARRAY_BUFFER, VBO); // bind it to the GL_ARRAY_BUFFER target + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // copy user-defined data into currently bound buffer + + // set vertex attributes + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0); // TODO: wtf + glEnableVertexAttribArray(0); + + // wait for exit + while (!checkQuit()) + { + glUseProgram(shaderProgram); + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 3); + + SDL_GL_SwapWindow(ctx.window); + } + + return 0; +} + +int checkQuit() +{ + SDL_Event event; + + if (SDL_PollEvent(&event) && event.type == SDL_QUIT) return 1; + + return 0; +} + diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..c8b49f2 --- /dev/null +++ b/src/main.h @@ -0,0 +1 @@ +#include diff --git a/todo.md b/todo.md new file mode 100644 index 0000000..1dc2960 --- /dev/null +++ b/todo.md @@ -0,0 +1,3 @@ +* [x] basic opengl initialisation +* [ ] render a texture to a full-screen quad +* [ ] output image to a file