diff --git a/Makefile b/Makefile index c2a250f..c613b66 100644 --- a/Makefile +++ b/Makefile @@ -7,22 +7,24 @@ SRCDIR = src LIBNAME = libTangerine.a RENDER_SOURCES = $(wildcard $(SRCDIR)/*.cpp) -RENDER_OBJECTS = $(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(RENDER_SOURCES)) +RENDER_OBJECTS = $(patsubst $(SRCDIR)/%.cpp, $(OBJDIR)/%.o, $(RENDER_SOURCES)) -all: $(RENDER_OBJECTS) - ar -crs $(OBJDIR)/$(LIBNAME) $(RENDER_OBJECTS) +all: $(LIBNAME) examples .PHONY: all -include $(OBJDIR)/*.d +$(LIBNAME): $(RENDER_OBJECTS) + ar -crs $(OBJDIR)/$(LIBNAME) $(RENDER_OBJECTS) + $(RENDER_OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp $(CXX) $(CXXFLAGS) -c -MMD $< -o $@ -examples: +examples: $(LIBNAME) $(MAKE) -C $(EXAMPLEDIR) .PHONY: examples clean: - rm $(OBJDIR)/* + rm -rf $(OBJDIR)/* bin/* .PHONY: clean diff --git a/README.txt b/README.txt index 3816124..1d3b30d 100644 --- a/README.txt +++ b/README.txt @@ -5,7 +5,8 @@ Tangerine NOTE: This is still a work in progress Dependencies: + assimp glew + glm SDL2 - assimp stb_image diff --git a/examples/Makefile b/examples/Makefile index 14be360..2018d8f 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -4,7 +4,7 @@ CXXFLAGS = -std=c++11 -g -ggdb3 -Wall -I../include -I/usr/include/SDL2 -I../ext/ LDFLAGS = -lSDL2 -lGLEW -lGL -lassimp OBJDIR = ../build BINARY = example -BINDIR = bin +BINDIR = ../bin all: $(CXX) $(CXXFLAGS) -c -MMD main.cpp -o $(OBJDIR)/$(BINARY).o diff --git a/examples/main.cpp b/examples/main.cpp index 026ea05..9703f57 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -5,5 +5,7 @@ int main() { + render_state* rs = renInit(); + return 0; } diff --git a/include/renderer.h b/include/renderer.h index 0b27ec8..ab868ff 100644 --- a/include/renderer.h +++ b/include/renderer.h @@ -36,6 +36,7 @@ struct render_state util_image palette_image; // TODO: this needs to be initialized outside struct because calloc GLuint palette_id = UINT_MAX; + util_RGBA clear_col; render_group* filled_hex_render_group; render_group* hex_line_render_group; @@ -48,7 +49,7 @@ struct render_state uint max_lights; }; -bool renInit(render_state* rs); +render_state* renInit(); void renFreeBuffers(render_state* rs); diff --git a/src/renderer.cpp b/src/renderer.cpp index 281cb27..e6fba78 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -24,22 +24,113 @@ #define CLEAR_COL_G 55.f / 255.f #define CLEAR_COL_B 55.f / 255.f #define CLEAR_COL_A 1.f +#define DEFAULT_WIDTH 1280 +#define DEFAULT_HEIGHT 720 #define USE_SECOND_MONITOR 0 -// TODO: add this to json scene properties and render_state -util_RGBA g_clear_col = {1.f,1.f,1.f,1.f}; - // forward declarations void openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); +bool initSDL(SDL_Handles& handles, v2i& viewport_dims); +bool initContext(SDL_Handles& handles); +bool initGL(); +bool initShaders(render_state* rs); +bool initPalette(uint palette_id, util_image& image); bool initDebugRenderGroup(render_state* rs); +void setDefaults(render_state* rs); // interface +render_state* +renInit() +{ + render_state* rs = UTIL_ALLOC(1, render_state); + setDefaults(rs); + + if (initSDL(rs->handles, rs->viewport_dims) && + initContext(rs->handles) && + initGL() && + initShaders(rs) && + initPalette(rs->palette_id, rs->palette_image) && + initDebugRenderGroup(rs) ) + { + return rs; + } else { + LOG(Error) << "renderer initialization failed, aborting\n"; + return nullptr; + } +} + +void +renFreeBuffers(render_state* rs) +{ + utilSafeFree(rs->lights); + utilFreeImage(rs->palette_image); + glDeleteTextures(1, &rs->palette_id); + rgFree(rs->filled_hex_render_group); + rgFree(rs->hex_line_render_group); + rgFree(rs->debug_render_group); +} + +void +renRenderFrame(render_state* rs, Entity* entities, uint32 entity_count) +{ + glClearColor(rs->clear_col.R, rs->clear_col.G, rs->clear_col.B, rs->clear_col.A); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + //glm::mat4 m_model = rs->cam.model; + glm::mat4 m_view = rs->cam.view; + glm::mat4 m_projection = rs->cam.projection; +#if 0 + // filled hexes + + // get new colors every frame + hgUpdateUVBuffer(hg, rs->filled_hex_render_group); + rgDraw(rs->filled_hex_render_group, m_model, m_view, m_projection, + rs->lights, rs->num_lights); + + // hex lines + rgDraw(rs->hex_line_render_group, m_model, m_view, m_projection, + rs->lights, rs->num_lights); +#endif + // entities + for (uint i = 0; i < entity_count; i++) { + rgDraw(entities[i].ren_group, entities[i].world_transform , m_view, m_projection, + rs->lights, rs->num_lights); + } +} +#if 0 +void +renRenderDebug(render_state* rs, std::vector &vertices) +{ + GLfloat* buf = rs->debug_render_group->render_objects[0]->vertex_buffer.buffer; + buf[0] = vertices[0].x; buf[1] = vertices[0].y; buf[2] = 0; + buf[3] = vertices[1].x; buf[4] = vertices[1].y; buf[2] = 0; + buf[6] = vertices[2].x; buf[7] = vertices[2].y; buf[8] = 0; + buf[9] = vertices[3].x; buf[10] = vertices[3].y; buf[11] = 0; + + rgDraw(rs->debug_render_group, rs->cam.model, rs->cam.view, + rs->cam.projection, rs->lights, rs->num_lights, true); +} +#endif + +// internal + +void +openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, const GLchar* message, const void* userParam) +{ + LOG((type == GL_DEBUG_TYPE_ERROR) ? Error : Debug) + << (type == GL_DEBUG_TYPE_ERROR ? "** GL Error **" : "") + << ", type: " << type + << ", severity: " << severity + << ", message: " << message << "\n"; +} + bool -renInit(render_state* rs) +initSDL(SDL_Handles& handles, v2i& viewport_dims) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); @@ -48,29 +139,35 @@ renInit(render_state* rs) SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GetCurrentDisplayMode(0, &rs->handles.currentDisplayMode); + SDL_GetCurrentDisplayMode(0, &handles.currentDisplayMode); uint display_id = 0; if (USE_SECOND_MONITOR && SDL_GetNumVideoDisplays() > 1) display_id = 1; - rs->handles.window = SDL_CreateWindow( + handles.window = SDL_CreateWindow( "hexgame", SDL_WINDOWPOS_CENTERED_DISPLAY(display_id), SDL_WINDOWPOS_CENTERED_DISPLAY(display_id), - rs->viewport_dims.x, - rs->viewport_dims.y, + viewport_dims.x, + viewport_dims.y, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE ); - if (!rs->handles.window) { + if (!handles.window) { LOG(Error) << "Error creating window: " << SDL_GetError() << "\n"; return false; } - rs->handles.glContext = SDL_GL_CreateContext(rs->handles.window); + return true; +} - if (!rs->handles.glContext) { +bool +initContext(SDL_Handles& handles) +{ + handles.glContext = SDL_GL_CreateContext(handles.window); + + if (!handles.glContext) { LOG(Error) << "Error creating glContext: " << SDL_GetError() << "\n"; return false; } @@ -80,6 +177,12 @@ renInit(render_state* rs) return false; } + return true; +} + +bool +initGL() +{ if (glewInit()) { LOG(Error) << "failed to initialize OpenGL\n"; return false; @@ -106,6 +209,12 @@ renInit(render_state* rs) // hide VRAM debug messages glDebugMessageControl(GL_DONT_CARE, 33361, GL_DONT_CARE, 0, 0, GL_FALSE); + return true; +} + +bool +initShaders(render_state* rs) +{ const char* vs_code = utilDumpTextFile(DEFAULT_VERTEX_SHADER_FILE); const char* fs_code = utilDumpTextFile(DEFAULT_FRAGMENT_SHADER_FILE); @@ -119,92 +228,20 @@ renInit(render_state* rs) return false; } - rs->max_lights = MAX_LIGHTS; - rs->lights = UTIL_ALLOC(rs->max_lights, rg_point_light); - rs->palette_image = utilLoadImage(DEFAULT_PALETTE_DIR, DEFAULT_PALETTE_FILE); - - if (!rgInitGLTexture(rs->palette_id, rs->palette_image)) { - LOG(Error) << "Error creating texture\n"; - return false; - } - - if (!initDebugRenderGroup(rs)) { - LOG(Error) << "Error initializing debug render group\n"; - return false; - } - - g_clear_col.R = CLEAR_COL_R; - g_clear_col.B = CLEAR_COL_B; - g_clear_col.G = CLEAR_COL_G; - g_clear_col.A = CLEAR_COL_A; - return true; } -void -renFreeBuffers(render_state* rs) -{ - utilSafeFree(rs->lights); - utilFreeImage(rs->palette_image); - glDeleteTextures(1, &rs->palette_id); - rgFree(rs->filled_hex_render_group); - rgFree(rs->hex_line_render_group); - rgFree(rs->debug_render_group); -} - -void -renRenderFrame(render_state* rs, Entity* entities, uint32 entity_count) +bool +initPalette(uint palette_id, util_image& image) { - 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); + image = utilLoadImage(DEFAULT_PALETTE_DIR, DEFAULT_PALETTE_FILE); - //glm::mat4 m_model = rs->cam.model; - glm::mat4 m_view = rs->cam.view; - glm::mat4 m_projection = rs->cam.projection; -#if 0 - // filled hexes - - // get new colors every frame - hgUpdateUVBuffer(hg, rs->filled_hex_render_group); - rgDraw(rs->filled_hex_render_group, m_model, m_view, m_projection, - rs->lights, rs->num_lights); - - // hex lines - rgDraw(rs->hex_line_render_group, m_model, m_view, m_projection, - rs->lights, rs->num_lights); -#endif - // entities - for (uint i = 0; i < entity_count; i++) { - rgDraw(entities[i].ren_group, entities[i].world_transform , m_view, m_projection, - rs->lights, rs->num_lights); + if (!rgInitGLTexture(palette_id, image)) { + LOG(Error) << "Error creating texture\n"; + return false; } -} -#if 0 -void -renRenderDebug(render_state* rs, std::vector &vertices) -{ - GLfloat* buf = rs->debug_render_group->render_objects[0]->vertex_buffer.buffer; - buf[0] = vertices[0].x; buf[1] = vertices[0].y; buf[2] = 0; - buf[3] = vertices[1].x; buf[4] = vertices[1].y; buf[2] = 0; - buf[6] = vertices[2].x; buf[7] = vertices[2].y; buf[8] = 0; - buf[9] = vertices[3].x; buf[10] = vertices[3].y; buf[11] = 0; - - rgDraw(rs->debug_render_group, rs->cam.model, rs->cam.view, - rs->cam.projection, rs->lights, rs->num_lights, true); -} -#endif - -// internal -void -openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, - GLsizei length, const GLchar* message, const void* userParam) -{ - LOG((type == GL_DEBUG_TYPE_ERROR) ? Error : Debug) - << (type == GL_DEBUG_TYPE_ERROR ? "** GL Error **" : "") - << ", type: " << type - << ", severity: " << severity - << ", message: " << message << "\n"; + return true; } bool @@ -213,8 +250,10 @@ initDebugRenderGroup(render_state* rs) uint debug_buf_len = 12; // 4 vertices, 3 floats per vertex rs->debug_render_group = rgInitSingle(rs->default_shader, debug_buf_len, true, 0, GL_LINE_LOOP); - if (rs->debug_render_group == nullptr) + if (rs->debug_render_group == nullptr) { + LOG(Error) << "Error initializing debug render group\n"; return false; + } gl_buffer& debug_vertex_buf = rs->debug_render_group->render_objects[0]->vertex_buffer; gl_buffer& debug_normal_buf = rs->debug_render_group->render_objects[0]->normal_buffer; @@ -230,3 +269,16 @@ initDebugRenderGroup(render_state* rs) return true; } + +void +setDefaults(render_state* rs) +{ + rs->viewport_dims = v2i(DEFAULT_WIDTH, DEFAULT_HEIGHT); + rs->palette_id = UINT_MAX; + rs->max_lights = MAX_LIGHTS; + rs->lights = UTIL_ALLOC(rs->max_lights, rg_point_light); + rs->clear_col.R = CLEAR_COL_R; + rs->clear_col.B = CLEAR_COL_B; + rs->clear_col.G = CLEAR_COL_G; + rs->clear_col.A = CLEAR_COL_A; +}