Browse Source

added line borders and correct colors to hex rendering

master
dummy 9 years ago
parent
commit
0603f6934c
  1. 3
      .gitmodules
  2. 1
      ext/aixlog
  3. 3
      src/hexgame.cpp
  4. 1
      src/hexgame.h
  5. 5
      src/hexlib.h
  6. 255
      src/renderer.h

3
.gitmodules vendored

@ -1,3 +1,6 @@
[submodule "ext/imgui"]
path = ext/imgui
url = https://github.com/ocornut/imgui.git
[submodule "ext/aixlog"]
path = ext/aixlog
url = https://github.com/badaix/aixlog.git

1
ext/aixlog

@ -0,0 +1 @@
Subproject commit d4e8ab4f1fe0e44d8246b37c349f566b356636f6

3
src/hexgame.cpp

@ -38,7 +38,6 @@
#include "hexgame.h"
#include "hexlib.h"
#include "renderer.h"
//#include "gooey.h"
using std::string;
using std::stringstream;
@ -61,8 +60,6 @@ debugLog(string error)
v2i viewportDims(1280, 720);
vector<hex_info> *hexInfoArray;
Layout global_layout(layout_flat, Point(25, 25), Point(viewportDims.x/2,viewportDims.y/2));
uint32 selected_line_color = 0xFFFFFFFF;
uint32 line_color = 0xFFFFFFFF;
uint32 selected_fill_color = 0xF46000FF;
uint32 fill_color = 0x5C5C5CFF;

1
src/hexgame.h

@ -3,6 +3,7 @@
#define HEXGAME_H
#include <vector>
#include <limits>
#include <cassert>
#include <SDL2/SDL.h>

5
src/hexlib.h

@ -16,9 +16,10 @@ using std::vector;
struct Point
{
const double x;
const double y;
double x;
double y;
Point(double x_, double y_): x(x_), y(y_) {}
Point(): x(0), y(0) {}
};

255
src/renderer.h

@ -2,8 +2,7 @@
#ifndef RENDERER_H
#define RENDERER_H
#include <cstdlib> // rand, srand, RAND_MAX
#include <ctime> // time
#include <vector>
// TODO: remove for better logging
#include <iostream> // std::cout
@ -21,20 +20,21 @@
bool initRenderer(SDL_Handles &handles, v2i vpDims);
// TODO: re-implement debug erender
void debugRender(HexDrawMode mode, hex_info *startHex, hex_info *currentHex);
void renderFrame(const vector<hex_info> *hexes);
void renderFrame(const std::vector<hex_info> *hexes);
void freeBuffers();
// forward declarations
GLuint initShaders();
bool initShaders(GLuint &programID1, GLuint &programID2);
// enable debug output https://www.khronos.org/opengl/wiki/OpenGL_Error
void openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
GLsizei length, const GLchar* message, const void* userParam);
void createScene(vector<hex_info>* hexes);
void createScene(std::vector<hex_info>* hexes);
void parseHexToGLBuffer(GLfloat buf[], int idx, const hex_info &hex);
void fillColorBuffer(GLfloat* buf, int len);
bool fillColorBuffer(GLfloat* buf, int len, std::vector<hex_info> *hexes);
// TODO: organize these into a struct/structs since we're using at least 2 now
glm::mat4 g_projection_matrix;
glm::mat4 g_view_matrix;
glm::mat4 g_model_matrix;
@ -44,9 +44,14 @@ GLuint g_vertex_buffer_triangle_count;
GLuint g_color_buffer;
size_t g_buf_size;
GLfloat *g_color_buf_data;
GLuint g_programID;
GLuint g_hex_programID;
GLuint g_matrixID;
GLuint g_hex_line_vertexbuffer;
size_t g_line_buf_size;
GLuint g_line_programID;
GLuint g_line_matrixID;
bool
initRenderer(SDL_Handles &handles, v2i vpDims)
{
@ -97,17 +102,24 @@ initRenderer(SDL_Handles &handles, v2i vpDims)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
// TODO: glDebugMessageCallback is only availabe from >v4.3
// check and warn if context doesn't support this function here
glEnable (GL_DEBUG_OUTPUT);
glDebugMessageCallback((GLDEBUGPROC) openglDebugCallback, 0);
g_programID = initShaders();
g_matrixID = glGetUniformLocation(g_programID, "g_MVP"); // shader variable for mvp xform
// hide VRAM debug messages
glDebugMessageControl(GL_DONT_CARE, 33361, GL_DONT_CARE, 0, 0, GL_FALSE);
initShaders(g_hex_programID, g_line_programID);
g_matrixID = glGetUniformLocation(g_hex_programID, "g_MVP"); // shader variables for mvp xform
g_line_matrixID = glGetUniformLocation(g_line_programID, "g_MVP");
return true;
}
// TODO: figure out how to keep track of shader state, and pass in struct here
GLuint
initShaders()
// TODO: make reusable by creating 1 program at a time
bool
initShaders(GLuint &programID1, GLuint &programID2)
{
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
@ -131,44 +143,57 @@ initShaders()
"out vec3 color;\n"
"void main()\n"
"{\n"
//" color = vec3(0.5,0,0);\n"
" color = fragmentColor;\n"
"}";
#if 1
const char * LineFragmentShaderCode =
"#version 330 core\n"
"out vec3 color;\n"
"void main()\n"
"{\n"
" color = vec3(0,0,0);\n"
"}";
#endif
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
GLuint LineFragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(VertexShaderID, 1, &VertexShaderCode, NULL);
glShaderSource(FragmentShaderID, 1, &FragmentShaderCode, NULL);
glShaderSource(LineFragmentShaderID, 1, &LineFragmentShaderCode, NULL);
glCompileShader(VertexShaderID);
glCompileShader(FragmentShaderID);
GLuint programID = glCreateProgram();
glAttachShader(programID, VertexShaderID);
glAttachShader(programID, FragmentShaderID);
glLinkProgram(programID);
glDetachShader(programID, VertexShaderID);
glDetachShader(programID, FragmentShaderID);
glCompileShader(LineFragmentShaderID);
programID1 = glCreateProgram();
glAttachShader(programID1, VertexShaderID);
glAttachShader(programID1, FragmentShaderID);
glLinkProgram(programID1);
programID2 = glCreateProgram();
glAttachShader(programID2, VertexShaderID);
glAttachShader(programID2, LineFragmentShaderID);
glLinkProgram(programID2);
glDetachShader(programID1, VertexShaderID);
glDetachShader(programID1, FragmentShaderID);
glDetachShader(programID2, LineFragmentShaderID);
glDetachShader(programID2, FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
glDeleteShader(LineFragmentShaderID);
return programID;
// TODO: what kind of errors can happen here?
return true;
}
void
createScene(vector<hex_info>* hexes)
createScene(std::vector<hex_info>* hexes)
{
////////////////////
// Model, View, Projection Matrices
g_projection_matrix = glm::ortho(
0.f, // left
1280.0f, // right
0.f, // bottom
720.0f, // top
0.1f, // zNear
100.0f // zFar
);
// left, right, bottom, top, zNear, zFar
g_projection_matrix = glm::ortho(0.f, 1280.0f, 0.f, 720.0f, 0.1f, 100.0f);
g_view_matrix = glm::lookAt(
glm::vec3(0.0f, 0.0f, 2.0f), // camera position
@ -186,7 +211,7 @@ createScene(vector<hex_info>* hexes)
// TODO: index duplicate vertices
// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/
// 6 triangles * 3 vertices per triange * 3 floats per vertex = 54
// 6 triangles * 3 vertices per triangle * 3 floats per vertex = 54
int buf_index = 54;
size_t hex_count = hexes->size();
g_buf_size = 6 * 9 * hex_count;
@ -202,14 +227,64 @@ createScene(vector<hex_info>* hexes)
glBindBuffer(GL_ARRAY_BUFFER, g_vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * g_buf_size, vbuf_data, GL_STATIC_DRAW);
// make some pretty colors
srand(time(0)); // seed c library rng
g_color_buf_data = (GLfloat*) std::malloc(sizeof(GLfloat) * g_buf_size);
fillColorBuffer(g_color_buf_data, int(g_buf_size));
// color data for hex vertices
g_color_buf_data = (GLfloat*) std::calloc( g_buf_size, sizeof(GLfloat));
if (!fillColorBuffer(g_color_buf_data, (int) g_buf_size, hexes))
{
// TODO: log fatal error
return;
}
glGenBuffers(1, &g_color_buffer);
glBindBuffer(GL_ARRAY_BUFFER, g_color_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * g_buf_size, g_color_buf_data, GL_DYNAMIC_DRAW);
// Hex Line Vertex Data
// TODO: surely there's a way to use indexed drawing for line vertices eg) LINE_LOOP
// and still use one buffer for multiple shapes/paths glDrawArraysIntanced?, glDrawElements?
// https://gamedev.stackexchange.com/questions/104310/opengl-4-5-primitive-restart-vs-base-index
int line_vertices_per_hex = 6 * 2; // 12 vertices since we're using line segments atm
g_line_buf_size = hex_count * line_vertices_per_hex * 3; // 3 floats per vertex
GLfloat line_buf_data[g_line_buf_size] = { 0 };
int line_buf_idx = 0;
for (int i = 0; i < (int) hex_count; i++)
{
hex_info hxi = (*hexes)[i];
for (int j = 0; j < 6; j ++)
{
Point p1, p2;
if (j == 5) // wrap
{
p1 = hxi.vertices[j];
p2 = hxi.vertices[0];
}
else
{
p1 = hxi.vertices[j];
p2 = hxi.vertices[j + 1];
}
line_buf_data[line_buf_idx + 0] = p1.x;
line_buf_data[line_buf_idx + 1] = p1.y;
line_buf_data[line_buf_idx + 2] = 0.f;
line_buf_data[line_buf_idx + 3] = p2.x;
line_buf_data[line_buf_idx + 4] = p2.y;
line_buf_data[line_buf_idx + 5] = 0.f;
line_buf_idx += 6;
}
}
glGenBuffers(1, &g_hex_line_vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, g_hex_line_vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * g_line_buf_size, line_buf_data, GL_STATIC_DRAW);
}
void
@ -218,7 +293,7 @@ parseHexToGLBuffer(GLfloat buf[], int idx, const hex_info &hex)
// triangles
for (int i = 0; i < 6; i++)
{
if (i == 5) // wrap
if (i == 5) // re-use the first point for the last triangle
{
// vertex 0
buf[idx + 0] = (GLfloat) hex.XPos;
@ -258,23 +333,53 @@ parseHexToGLBuffer(GLfloat buf[], int idx, const hex_info &hex)
}
}
void
fillColorBuffer(GLfloat* buf, int len)
bool
fillColorBuffer(GLfloat buf[], int len, std::vector<hex_info> *hexes)
{
for (int i = 0; i < len; i++)
if (!buf || len < 1)
{
// TODO: log fatal error
return false;
}
if (!hexes || hexes->size() == 0)
{
// TODO: log fatal error
return false;
}
// 3 floats per vertex, 3 vertexes per triangle, 6 triangles per hex
if (len != (int) hexes->size() * 3 * 3 * 6)
{
// should be normalized between 0 and 1
buf[i] = GLfloat((GLfloat) rand() / (GLfloat) RAND_MAX);
// TODO: log fatal error
return false;
}
int buf_idx;
int buf_len_per_hex = 54; // NOTE: 3 * 3 * 6
for (int i = 0; i < (int) hexes->size(); i++)
{
buf_idx = i * buf_len_per_hex;
hex_info hxi = (*hexes)[i];
GLfloat color = (GLfloat) hxi.current_color / (GLfloat) UINT32_MAX;
for (int j = 0; j < buf_len_per_hex; j++)
{
buf[buf_idx + j] = color;
}
}
return true;
}
struct
typedef struct clear_col
{
real32 R = 75.0f / 255.0f;
real32 G = 135.0f / 255.0f;
real32 B = 135.0f / 255.0f;
real32 A = 1;
} gl_clear_color;
real32 R;
real32 G;
real32 B;
real32 A;
} clear_col;
clear_col g_clear_col { 75.f / 255.f, 135.f / 255.f, 135.f / 255.f, 1.f };
void
openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
@ -289,56 +394,56 @@ openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
}
void
renderFrame(const vector<hex_info> *hexes)
renderFrame(std::vector<hex_info> *hexes)
{
glClearColor(gl_clear_color.R, gl_clear_color.G, gl_clear_color.B,
gl_clear_color.A);
glClearColor(g_clear_col.R, g_clear_col.G, g_clear_col.B, g_clear_col.A);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glUseProgram(g_programID);
// Send our transformation to the currently bound shader,
// in the "g_MVP" uniform
#if 1
glUseProgram(g_hex_programID);
// Send our transformation to the currently bound shader, in the "g_MVP" uniform
glUniformMatrix4fv(g_matrixID, 1, GL_FALSE, &g_MVP[0][0]);
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, g_vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// 2nd attribute buffer : colors
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, g_color_buffer);
glVertexAttribPointer(
1,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// get new colors every frame
fillColorBuffer(g_color_buf_data, int(g_buf_size));
fillColorBuffer(g_color_buf_data, (int) g_buf_size, hexes);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * g_buf_size, g_color_buf_data);
glDrawArrays(GL_TRIANGLES, 0, g_vertex_buffer_triangle_count);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
#endif
#if 1
glUseProgram(g_line_programID);
// Send our transformation to the currently bound shader, in the "g_MVP" uniform
glUniformMatrix4fv(g_matrixID, 1, GL_FALSE, &g_MVP[0][0]);
// 1st attribute buffer : vertices
GLuint attrib_index = 0; // TODO: line buffer doesn't render if this is anything other than 0
glEnableVertexAttribArray(attrib_index);
glBindBuffer(GL_ARRAY_BUFFER, g_hex_line_vertexbuffer);
glVertexAttribPointer(attrib_index, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glDrawArrays(GL_LINES, 0, g_line_buf_size / 3);
#endif
}
void
freeBuffers()
{
if (g_color_buf_data)
{
free(g_color_buf_data);
g_color_buf_data = 0;
}
}
#endif // RENDERER_H

Loading…
Cancel
Save