hexnando/main.c

196 lines
6.6 KiB
C

#include <GL/glew.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include "hex_math.h"
#define log_err(str, ...) do { fprintf(stderr, "[ERROR] (%s:%d): " str "\n", __FILE__, __LINE__, ##__VA_ARGS__); } while (0)
#define log_debug(str, ...) do { fprintf(stderr, "[DEBUG] (%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";
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 = 2;
grid.columns = 2;
grid.hexes = calloc(1, sizeof(hex_t) * grid.rows * grid.columns);
float scale = 1.0f / 5.0f;
for (size_t i = 0; i < grid.columns; ++i)
{
for (size_t j = 0; j < grid.rows; ++j)
{
float offset = 0.0f;
if (j % 2)
offset = sint(1.0f/6);
grid.hexes[i*grid.rows+j].position.x = (0.0f + j*(1 + cost(1.0f/6)));
grid.hexes[i*grid.rows+j].position.y = (0.0f + i*(sint(1.0f/6))*2.0f) + offset;
grid.hexes[i*grid.rows+j].position.z = 0.0f;
grid.hexes[i*grid.rows+j].position.w = 1.0f;
fprintf(stdout, "Position of hex %ld %ld is %f %f\n", i, j, grid.hexes[i*grid.rows+j].position.x, grid.hexes[i*grid.rows+j].position.y);
}
}
// Get OpenGL objects
for (size_t i = 0; i < grid.rows * grid.columns; ++i)
{
hex_t *hex = &grid.hexes[i];
// VAO setup
glGenVertexArrays(1, &hex->vao);
glBindVertexArray(hex->vao);
// VBO setup
float *vertices = hex->vertices;
vertices[0] = hex->position.x * scale;
vertices[1] = hex->position.y * scale;
vertices[2] = hex->position.z;
log_debug("Adding vertex %f %f %f", vertices[0], vertices[1], vertices[2]);
for (int j = 1; j < 7; ++j)
{
vertices[j*3] = (hex->position.x + cost((j-1)/6.0f)) * scale;
vertices[j*3+1] = (hex->position.y + sint((j-1)/6.0f)) * scale;
vertices[j*3+2] = hex->position.z;
log_debug("Adding vertex %f %f %f", vertices[j*3], vertices[j*3+1], vertices[j*3+2]);
}
glGenBuffers(1,&hex->vbo);
glBindBuffer(GL_ARRAY_BUFFER, hex->vbo);
glBufferData(GL_ARRAY_BUFFER, 7*3*sizeof(float), vertices, GL_STATIC_DRAW);
// EBO setup
unsigned int *indices = hex->indices;
indices[0] = 0; indices[1] = 1; indices[2] = 2;
indices[3] = 0; indices[4] = 2; indices[5] = 3;
indices[6] = 0; indices[7] = 3; indices[8] = 4;
indices[9] = 0; indices[10] = 4; indices[11] = 5;
indices[12] = 0; indices[13] = 5; indices[14] = 6;
indices[15] = 0; indices[16] = 6; indices[17] = 1;
glGenBuffers(1,&hex->ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, hex->ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*3 * sizeof(unsigned int), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (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);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
for (size_t i = 0; i < grid.rows * grid.columns; ++i)
{
glBindVertexArray(grid.hexes[i].vao);
//log_debug("Binding VAO %d VBO %d EBO %d", grid.hexes[i].vao, grid.hexes[i].vbo, grid.hexes[i].ebo);
glBindBuffer(GL_ARRAY_BUFFER, grid.hexes[i].vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grid.hexes[i].ebo);
glDrawElements(GL_TRIANGLES, 3*6, GL_UNSIGNED_INT, 0);
}
glfwPollEvents();
glfwSwapBuffers(window);
}
}