From 677e749ac208cc848322759c6b07a54fe99f941a Mon Sep 17 00:00:00 2001 From: Andreas Ortmann Date: Thu, 29 Sep 2016 13:11:01 +0200 Subject: [PATCH] redesigned model a bit. --- game/renderer_polygon_3d/polygon_model.cpp | 126 +++++++++++++----- game/renderer_polygon_3d/polygon_model.hpp | 26 +++- .../renderer_polygon_3d.cpp | 23 ++-- game/state/trace.cpp | 1 + 4 files changed, 125 insertions(+), 51 deletions(-) diff --git a/game/renderer_polygon_3d/polygon_model.cpp b/game/renderer_polygon_3d/polygon_model.cpp index e49e1a8..04f4258 100644 --- a/game/renderer_polygon_3d/polygon_model.cpp +++ b/game/renderer_polygon_3d/polygon_model.cpp @@ -1,12 +1,83 @@ #include "polygon_model.hpp" +void discardLastGlError() +{ + glGetError(); +} + +void checkAndPrintGlError() +{ + GLenum err = glGetError(); + const char *errString; + switch(err) { + case GL_INVALID_ENUM: errString = "GL_INVALID_ENUM"; break; + case GL_INVALID_VALUE: errString = "GL_INVALID_VALUE"; break; + case GL_INVALID_OPERATION: errString = "GL_INVALID_OPERATION"; break; + case GL_OUT_OF_MEMORY: errString = "GL_OUT_OF_MEMORY"; break; + case GL_INVALID_FRAMEBUFFER_OPERATION: errString = "GL_INVALID_FRAMEBUFFER_OPERATION"; break; + default: errString = ""; break; + } + + if (err != GL_NO_ERROR) { + std::cout<<"glGetAttribLocation() returned error: " << errString << std::endl; + } +} namespace endofthejedi { - PolygonModel::PolygonModel(const std::string &filename) : m_filename(filename) + PolygonModel::PolygonModel(const std::string &filename) + : m_filename(filename) { clear(); } - bool PolygonModel::bind(Shader &shader) + // TODO: add change/set shader function because it stays for all calls of an + // instance the same. + void PolygonModel::setup(Shader *shader) + { + if (shader == nullptr) { + std::cout<<"shader is NULL" << std::endl; + exit(-1); + return; + } + + if (shader->program() == 0) { + std::cout<<"program is invalid" << std::endl; + exit(-1); + return; + } + + std::cout<<"program: " << shader->program() << std::endl; + + m_shader = shader; + + // TODO error checks + const char *names[] = { + "in_vertex", + "in_normal" + }; + + discardLastGlError(); + + for (int i=0; i<2; i++) { + const char *name = names[i]; + GLint loc = glGetAttribLocation(m_shader->program(), name); + m_attr_locations[i] = loc; + + checkAndPrintGlError(); + + if (m_attr_locations[i] == -1) { + std::cerr<<"[polygonmodel] warning: attribute location #" + << i << " (for '" << name + << "') is invalid!" << std::endl; + + } else { + std::cout<<"[polygonmodel] attribute location #" + << i << " (for '" << name + << "') is " << m_attr_locations[i] << std::endl; + } + } + } + + bool PolygonModel::bind() { if (!m_loaded_to_opengl) { std::cout<<"[polygonmodel] warning: try to bind model vbo " @@ -17,39 +88,25 @@ namespace endofthejedi { } // bind position vbo - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id_position); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); - - // bind normal vbo - GLint loc = glGetAttribLocation(shader.program(), "in_normal"); - glEnableVertexAttribArray(loc); - glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id_normal); - glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, NULL); + for (int i=0; i<2; i++) { + glEnableVertexAttribArray(m_attr_locations[0]); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id[i]); + glVertexAttribPointer(m_attr_locations[i], 3, GL_FLOAT, GL_FALSE, 0, NULL); + } m_binding_active = true; return true; } - bool PolygonModel::render(Shader& shader) + bool PolygonModel::render() { - (void) shader; - if (!m_binding_active || !m_loaded_to_opengl) { std::cout<<"[polygonmodel] warning: try to render model without bind()" << std::endl; exit(-1); return false; } - //GLint l0 = glGetAttribLocation(shader.program(), "in_normal"); - //GLint l1 = glGetAttribLocation(shader.program(), "in_vertex"); - //GLint l2 = glGetAttribLocation(shader.program(), "in_fakkkke"); - //std::cout<<"locations: " << l0 << " " << l1 << " " << l2 << std::endl; - - //glBindAttribLocation(shader.program(), 0, "in_vertex"); - //glBindAttribLocation(shader.program(), 1, "in_normal"); - glDrawArrays(GL_TRIANGLES, 0, m_numVertices); return true; } @@ -116,13 +173,14 @@ namespace endofthejedi { /* Position data */ /************************************************************/ - glEnableVertexAttribArray(0); + glGenBuffers(2, m_vbo_id); // Generate buffer - glGenBuffers(1, &m_vbo_id_position); // Generate buffer - glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id_position); // Bind buffer + glEnableVertexAttribArray(m_attr_locations[0]); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id[0]); // Bind buffer - glVertexAttribPointer(0, - 3, // three floats per vertex + glVertexAttribPointer( + m_attr_locations[0], + 3, // three floats per vertex GL_FLOAT, // Data is floating point type GL_FALSE, // No fixed point scaling 0, // stride: no @@ -139,12 +197,11 @@ namespace endofthejedi { /* Normal data */ /************************************************************/ - glEnableVertexAttribArray(1); - glGenBuffers(1, &m_vbo_id_normal); // Generate buffer - glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id_normal); // Bind buffer + glEnableVertexAttribArray(m_attr_locations[1]); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id[1]); // Bind buffer glVertexAttribPointer( - 1, + m_attr_locations[1], 3, // three floats per normal GL_FLOAT, // Data is floating point type GL_FALSE, // No fixed point scaling @@ -206,8 +263,11 @@ namespace endofthejedi { m_data_position.clear(); m_data_normal.clear(); - m_vbo_id_position = 0; - m_vbo_id_normal = 0; + for (int i=0; i<2; i++) { + m_vbo_id[i] = -1; + m_attr_locations[i] = -1; + } + m_numVertices = 0; } } diff --git a/game/renderer_polygon_3d/polygon_model.hpp b/game/renderer_polygon_3d/polygon_model.hpp index 9b67a9a..7f710b9 100644 --- a/game/renderer_polygon_3d/polygon_model.hpp +++ b/game/renderer_polygon_3d/polygon_model.hpp @@ -23,13 +23,25 @@ namespace endofthejedi { public: PolygonModel(const std::string &filename); - void clear(); - + // (re) load data from file bool import(); + // connect stuff with the shader for rendering + // supply the current shader that should be used for this model. + // when it recompiles, call setup() again. + void setup(Shader *shader); + + // upload model data to GPU bool uploadToOpenGl(); - bool bind(Shader &shader); - bool render(Shader& shader); + + // call bind before rendering + bool bind(); + + // call to render + bool render(); + + // clear everything and delete data + void clear(); private: bool copyVertices(const aiScene *scene); @@ -48,7 +60,9 @@ namespace endofthejedi { size_t m_numVertices; - GLuint m_vbo_id_position; - GLuint m_vbo_id_normal; + // TODO: watch for shader recompile + GLint m_attr_locations[2]; + GLuint m_vbo_id[2]; + Shader *m_shader; }; } diff --git a/game/renderer_polygon_3d/renderer_polygon_3d.cpp b/game/renderer_polygon_3d/renderer_polygon_3d.cpp index 0b3b2a5..6f35867 100644 --- a/game/renderer_polygon_3d/renderer_polygon_3d.cpp +++ b/game/renderer_polygon_3d/renderer_polygon_3d.cpp @@ -13,12 +13,6 @@ namespace endofthejedi { std::cout<<"setup polygon 3d" << std::endl; - //m_missileModel = new PolygonModel("../data/mesh/quad_screen_coords.stl"); - - addModel("../data/mesh/small_atomic_bomb.stl", &m_missileModel); - addModel("../data/mesh/planet_64.stl", &m_planetModel); - addModel("../data/mesh/ship_ufo.stl", &m_shipModel); - std::string vss_simple = #include "simple.vert" ; @@ -48,6 +42,10 @@ namespace endofthejedi { m_shader.load(vss_game_objects.c_str(), GL_VERTEX_SHADER); m_shader.load(fss_game_objects.c_str(), GL_FRAGMENT_SHADER); #endif + + addModel("../data/mesh/small_atomic_bomb.stl", &m_missileModel); + addModel("../data/mesh/planet_64.stl", &m_planetModel); + addModel("../data/mesh/ship_ufo.stl", &m_shipModel); } void RendererPolygon3d::render(const game::State *state) @@ -154,7 +152,7 @@ namespace endofthejedi { void RendererPolygon3d::renderPlanets() { - m_planetModel->bind(m_shader); + m_planetModel->bind(); for (const game::Planet *planet : m_state->planets) { glm::mat4 model = computeModelMatrix(planet); @@ -164,13 +162,13 @@ namespace endofthejedi { glUniform3f(m_shader.location("materialColor"), c.x, c.y, c.z); glUniform3f(m_shader.location("color"), c.x, c.y, c.z); - m_planetModel->render(m_shader); + m_planetModel->render(); } } void RendererPolygon3d::renderMissiles() { - m_missileModel->bind(m_shader); + m_missileModel->bind(); for (const game::Player *player : m_state->players) { for (const game::Missile *missile : player->missiles) { @@ -180,14 +178,14 @@ namespace endofthejedi { glm::mat4 model = computeModelMatrix(missile); glUniformMatrix4fv(m_shader.location("model"), 1, GL_FALSE, glm::value_ptr(model)); - m_missileModel->render(m_shader); + m_missileModel->render(); } } } void RendererPolygon3d::renderShips() { - m_shipModel->bind(m_shader); + m_shipModel->bind(); for (const game::Ship *ship : m_state->ships) { glm::mat4 model = computeModelMatrix(ship); @@ -196,7 +194,7 @@ namespace endofthejedi { glm::vec3 c = glm::vec3(0.1, 1.0, 0.2); glUniform3f(m_shader.location("materialColor"), c.x, c.y, c.z); - m_shipModel->render(m_shader); + m_shipModel->render(); } } @@ -210,6 +208,7 @@ namespace endofthejedi { exit(-1); } + (*dest)->setup(&m_shader); (*dest)->uploadToOpenGl(); m_models.push_back(*dest); diff --git a/game/state/trace.cpp b/game/state/trace.cpp index ef89fc5..f3f3268 100644 --- a/game/state/trace.cpp +++ b/game/state/trace.cpp @@ -30,6 +30,7 @@ namespace game { void Trace::addPointFromMissile(bool forceAdd) { + // TODO: make configurable fidelityCounter++; if (forceAdd || fidelityCounter >= 10) { fidelityCounter = 0;