commit 546648cbdde569728e0aa48caa478847e87104db Author: Phireh Date: Mon Nov 7 22:09:25 2022 +0100 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c5858bb --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +hexnando diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..473a8ba --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +CFLAGS=-Wall -Wextra -g -fenable-matrix +LIBS=`pkg-config --libs glfw3 glew opengl` -lm + +hexnando: main.c + clang ${CFLAGS} ${LIBS} main.c -o hexnando diff --git a/hex_math.h b/hex_math.h new file mode 100644 index 0000000..c722dbc --- /dev/null +++ b/hex_math.h @@ -0,0 +1,60 @@ +#include +#include +/* Types */ +typedef float _v2f __attribute__((matrix_type(1,2))); +typedef float _v3f __attribute__((matrix_type(1,3))); +typedef float _v4f __attribute__((matrix_type(1,4))); + +typedef struct { + union { + struct { + float first; + _v3f tail; + }; + struct { + _v2f first_half; + _v2f second_half; + }; + struct { + _v3f v3f; + float last; + }; + _v4f v4f; + struct { + float r; + float g; + float b; + float a; + }; + struct { + float x; + float y; + float z; + float w; + }; + }; +} vec4f; + +typedef struct { + vec4f position; // center pos + float radius; // side length +} hex_t; + +typedef struct { + hex_t *hexes; + uint32_t rows; + uint32_t columns; +} hexgrid_t; + +_Static_assert(sizeof(vec4f) == sizeof(float) * 4, "Bad vector size"); + +/* Functions */ +double sint(double turns) +{ + return sin(turns*2*M_PI); +} + +double cost(double turns) +{ + return cos(turns*2*M_PI); +} diff --git a/main.c b/main.c new file mode 100644 index 0000000..fc228f2 --- /dev/null +++ b/main.c @@ -0,0 +1,178 @@ +#include +#define GLFW_INCLUDE_NONE +#include + +#include +#include +#include +#include + +#include "hex_math.h" + +#define log_err(x) do { fprintf(stderr, "[ERROR] (%s:%d): " str "\n", __FILE__, __LINE__, ##__VA_ARGS__); } while (0) + +/* Globals */ +const char *vertexShaderSource = "#version 330 core\n" + "layout (location = 0) in vec3 aPos;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" + "}\0"; +const char *fragmentShaderSource = "#version 330 core\n" + "out vec4 FragColor;\n" + "void main()\n" + "{\n" + " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" + "}\n\0"; + +GLuint vao; +GLuint vbo; +GLuint ebo; + +static void glfw_error_callback(int errcode, const char *description) +{ + fprintf(stderr, "[GLFW ERROR][ERRCODE %d] %s\n", errcode, description); +} + +int main() +{ + GLFWwindow *window; + + if (!glfwInit()) return -1; + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + + window = glfwCreateWindow(800, 800, "Hello World", NULL, NULL); + if (!window) return -1; + glfwMakeContextCurrent(window); + if (glewInit() != GLEW_OK) return -1; + + glfwSetErrorCallback(glfw_error_callback); + + // build and compile our shader program + // ------------------------------------ + // vertex shader + unsigned int vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, &vertexShaderSource, NULL); + glCompileShader(vertex_shader); + // check for shader compile errors + int success; + char infoLog[512]; + glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(vertex_shader, 512, NULL, infoLog); + fprintf(stderr, "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n %s\n", infoLog); + } + // fragment shader + unsigned int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragmentShaderSource, NULL); + glCompileShader(fragment_shader); + // check for shader compile errors + if (!success) + { + glGetShaderInfoLog(fragment_shader, 512, NULL, infoLog); + fprintf(stderr, "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n %s\n", infoLog); + } + // link shaders + unsigned int shader_program = glCreateProgram(); + glAttachShader(shader_program, vertex_shader); + glAttachShader(shader_program, fragment_shader); + glLinkProgram(shader_program); + // check for linking errors + glGetProgramiv(shader_program, GL_LINK_STATUS, &success); + if (!success) { + glGetShaderInfoLog(shader_program, 512, NULL, infoLog); + fprintf(stderr, "ERROR::SHADER::PROGRAM::COMPILATION_FAILED\n %s\n", infoLog); + } + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + + + vec4f background_color; + background_color.r = 0.1f; + background_color.g = 0.2f; + background_color.b = 0.3f; + background_color.a = 1.0f; + + + + hexgrid_t grid; + grid.rows = 1; + grid.columns = 1; + grid.hexes = calloc(1, sizeof(hex_t) * grid.rows * grid.columns); + + for (size_t i = 0; i < grid.rows * grid.columns; ++i) + { + grid.hexes[i].position.x = 0.0f; + grid.hexes[i].position.y = 0.0f; + grid.hexes[i].position.z = 0.0f; + grid.hexes[i].position.w = 1.0f; + } + + // Get OpenGL objects + + float *vertices = calloc(1, 7*3*grid.rows*grid.columns*sizeof(float)); + + for (uint64_t i = 0; i < grid.columns * grid.rows; ++i) + { + vertices[i*21] = grid.hexes[i].position.x; + vertices[i*21+1] = grid.hexes[i].position.y; + vertices[i*21+2] = grid.hexes[i].position.z; + + for (int j = 1; j < 7; ++j) + { + vertices[i*21+j*3] = grid.hexes[i].position.x + cost((j-1)/6.0f); + vertices[i*21+j*3+1] = grid.hexes[i].position.y + sint((j-1)/6.0f); + vertices[i*21+j*3+2] = grid.hexes[i].position.z; + } + } + + unsigned int indices[] = + { + 0,1,2, + 0,2,3, + 0,3,4, + 0,4,5, + 0,5,6, + 0,6,1 + }; + + glGenVertexArrays(1, &vao); + glGenBuffers(1,&vbo); + glGenBuffers(1,&ebo); + + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, 7*3*grid.rows*grid.columns*sizeof(float), vertices, GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + while (!glfwWindowShouldClose(window)) + { + int width, height; + glfwGetFramebufferSize(window, &width, &height); + glViewport(0, 0, width, height); + + glClearColor(background_color.r, background_color.g, background_color.b, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glUseProgram(shader_program); + glBindVertexArray(vao); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glDrawElements(GL_TRIANGLES, 3*6, GL_UNSIGNED_INT, 0); + + glfwPollEvents(); + glfwSwapBuffers(window); + } +}