From 79af104cfca1ba9ceaf53883f5ab0644ffdba6f8 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Mon, 20 Jul 2015 21:07:02 +0200 Subject: [PATCH] [DEV] continue integration --- gale/renderer/openGL/openGL-include.h | 46 ++++++ gale/renderer/openGL/openGL.cpp | 230 ++++++++++++++++++++------ gale/renderer/openGL/openGL.h | 34 +++- gale/resource/Program.cpp | 80 +++------ gale/resource/Program.h | 8 +- gale/resource/Shader.cpp | 84 +++------- gale/resource/Shader.h | 10 +- gale/resource/Texture.cpp | 1 + gale/resource/Texture.h | 4 +- gale/resource/VirtualBufferObject.cpp | 3 +- gale/resource/VirtualBufferObject.h | 4 +- sample/basic.cpp | 4 +- 12 files changed, 321 insertions(+), 187 deletions(-) create mode 100644 gale/renderer/openGL/openGL-include.h diff --git a/gale/renderer/openGL/openGL-include.h b/gale/renderer/openGL/openGL-include.h new file mode 100644 index 0000000..47b3d87 --- /dev/null +++ b/gale/renderer/openGL/openGL-include.h @@ -0,0 +1,46 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#ifndef __OPEN_GL_INCLUDE_H__ +#define __OPEN_GL_INCLUDE_H__ + +extern "C" { + #if defined(__TARGET_OS__Linux) + // TO ENABLE THE SHADER api ... + #define GL_GLEXT_PROTOTYPES + #include + // TODO : Check it it work + // This is to prevent the use of these element that is not allowed in the openGL ES + #undef glVertexPointer + #undef glTexCoordPointer + #undef glColorPointer + #undef glPopMatrix + #undef glPushMatrix + #undef glMatrixMode + #undef glLoadIdentity + #undef glTranslatef + #elif defined(__TARGET_OS__Android) + // Include openGL ES 2 + #include + #include + #elif defined(__TARGET_OS__Windows) + // TO ENABLE THE SHADER api ... + //#define GL_GLEXT_PROTOTYPES + #define GLEW_STATIC + #include + #elif defined(__TARGET_OS__MacOs) + #include + #include + #elif defined(__TARGET_OS__IOs) + #include + #else + #error you need to specify a __TAGET_OS__ ... + #endif +} + +#endif diff --git a/gale/renderer/openGL/openGL.cpp b/gale/renderer/openGL/openGL.cpp index ab44fcf..0e89680 100644 --- a/gale/renderer/openGL/openGL.cpp +++ b/gale/renderer/openGL/openGL.cpp @@ -12,42 +12,7 @@ #include #include //#define DIRECT_MODE - - -extern "C" { - #if defined(__TARGET_OS__Linux) - // TO ENABLE THE SHADER api ... - #define GL_GLEXT_PROTOTYPES - #include - // TODO : Check it it work - // This is to prevent the use of these element that is not allowed in the openGL ES - #undef glVertexPointer - #undef glTexCoordPointer - #undef glColorPointer - #undef glPopMatrix - #undef glPushMatrix - #undef glMatrixMode - #undef glLoadIdentity - #undef glTranslatef - #elif defined(__TARGET_OS__Android) - // Include openGL ES 2 - #include - #include - #elif defined(__TARGET_OS__Windows) - // TO ENABLE THE SHADER api ... - //#define GL_GLEXT_PROTOTYPES - #define GLEW_STATIC - #include - #elif defined(__TARGET_OS__MacOs) - #include - #include - #elif defined(__TARGET_OS__IOs) - #include - #else - #error you need to specify a __TAGET_OS__ ... - #endif -} - +#include #define CHECK_ERROR_OPENGL @@ -182,18 +147,24 @@ void gale::openGL::swap() { } +void gale::openGL::setViewPort(const ivec2& _start, const ivec2& _stop) { + glViewport(_start.x(), _start.y(), _stop.x(), _stop.y()); +} + +void gale::openGL::setViewPort(const vec2& _start, const vec2& _stop) { + glViewport(_start.x(), _start.y(), _stop.x(), _stop.y()); +} + struct correspondenceTableClear { enum gale::openGL::clearFlag curentFlag; GLbitfield OGlFlag; }; - static struct correspondenceTableClear basicFlagClear[] = { {gale::openGL::clearFlag_colorBuffer, GL_COLOR_BUFFER_BIT}, {gale::openGL::clearFlag_depthBuffer, GL_DEPTH_BUFFER_BIT}, {gale::openGL::clearFlag_stencilBuffer, GL_STENCIL_BUFFER_BIT} }; - static int32_t basicFlagClearCount = sizeof(basicFlagClear) / sizeof(struct correspondenceTableClear); @@ -211,7 +182,7 @@ void gale::openGL::clearStencil(int32_t _value) { void gale::openGL::clear(uint32_t _flags) { GLbitfield field = 0; for (int32_t iii=0; iii= 0) { updateAllFlags(); glDrawArrays(convertRenderMode[_mode], _first, _count); @@ -572,10 +543,14 @@ bool gale::openGL::bindBuffer(uint32_t _bufferId) { return true; } - GL_STREAM_DRAW, GL_STATIC_DRAW, or GL_DYNAMIC_DRAW - -bool gale::openGL::bufferData(size_t _size, const void* _data, GLenum _usage) { - glBufferData(GL_ARRAY_BUFFER, _size, _data, _usage); +static GLenum convertUsage[] = { + GL_STREAM_DRAW, + GL_STATIC_DRAW, + GL_DYNAMIC_DRAW +}; + +bool gale::openGL::bufferData(size_t _size, const void* _data, enum gale::openGL::usage _usage) { + glBufferData(GL_ARRAY_BUFFER, _size, _data, convertUsage[_usage]); checkGlError("glBufferData", __LINE__); return true; } @@ -586,3 +561,166 @@ bool gale::openGL::unbindBuffer() { return true; } +static void checkGlError(const char* _op) { + for (GLint error = glGetError(); error; error = glGetError()) { + GALE_ERROR("after " << _op << "() glError (" << error << ")"); + } +} +#define LOG_OGL_INTERNAL_BUFFER_LEN (8192) +static char l_bufferDisplayError[LOG_OGL_INTERNAL_BUFFER_LEN] = ""; + +int64_t gale::openGL::shader::create(enum gale::openGL::shader::type _type) { + GLuint shader = 0; + if (_type == gale::openGL::shader::type_vertex) { + shader = glCreateShader(GL_VERTEX_SHADER); + } else if (_type == gale::openGL::shader::type_fragment) { + shader = glCreateShader(GL_FRAGMENT_SHADER); + } else { + GALE_ERROR("create shader with wrong type ..."); + return -1; + } + if (shader == 0) { + GALE_ERROR("glCreateShader return error ..."); + checkGlError("glCreateShader"); + return -1; + } + return int64_t(shader); +} + +void gale::openGL::shader::remove(int64_t& _shader) { + if (_shader < 0) { + return; + } + glDeleteShader(GLuint(_shader)); + _shader = -1; +} + +bool gale::openGL::shader::compile(int64_t _shader, const std::string& _data) { + const char* data = &_data[0]; + glShaderSource(GLuint(_shader), 1, (const char**)&data, nullptr); + glCompileShader(GLuint(_shader)); + GLint compiled = 0; + glGetShaderiv(GLuint(_shader), GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLen = 0; + l_bufferDisplayError[0] = '\0'; + glGetShaderInfoLog(GLuint(_shader), LOG_OGL_INTERNAL_BUFFER_LEN, &infoLen, l_bufferDisplayError); + GALE_ERROR("Error " << l_bufferDisplayError); + std::vector lines = etk::split(_data, '\n'); + for (size_t iii=0; iii= 256) { + tmpLog[idOut] = '\0'; + GALE_ERROR(" == > " << tmpLog); + idOut=0; + } else { + idOut++; + } + if (l_bufferDisplayError[iii] == '\0') { + break; + } + } + if (idOut != 0) { + tmpLog[idOut] = '\0'; + GALE_ERROR(" == > " << tmpLog); + } + return false; + } + return true; +} + +int32_t gale::openGL::program::getAttributeLocation(int64_t _prog, const std::string& _name) { + if (_prog < 0) { + GALE_ERROR("wrong program ID"); + return -1; + } + if (_name.size() == 0) { + GALE_ERROR("wrong name of attribure"); + return -1; + } + GLint val = glGetAttribLocation(GLuint(_prog), _name.c_str()); + if (val < 0) { + checkGlError("glGetAttribLocation", __LINE__); + GALE_WARNING("glGetAttribLocation(\"" << _name << "\") = " << val); + } + return val; +} + +int32_t gale::openGL::program::getUniformLocation(int64_t _prog, const std::string& _name) { + if (_prog < 0) { + GALE_ERROR("wrong program ID"); + return -1; + } + if (_name.size() == 0) { + GALE_ERROR("wrong name of uniform"); + return -1; + } + GLint val = glGetUniformLocation(GLuint(_prog), _name.c_str()); + if (val < 0) { + checkGlError("glGetUniformLocation", __LINE__); + GALE_WARNING("glGetUniformLocation(\"" << _name << "\") = " << val); + } + return val; +} + diff --git a/gale/renderer/openGL/openGL.h b/gale/renderer/openGL/openGL.h index bcde087..9302910 100644 --- a/gale/renderer/openGL/openGL.h +++ b/gale/renderer/openGL/openGL.h @@ -12,6 +12,7 @@ #include #include #include +#include #include namespace gale { @@ -70,6 +71,8 @@ namespace gale { * @brief */ void swap(); + void setViewPort(const ivec2& _start, const ivec2& _stop); + void setViewPort(const vec2& _start, const vec2& _stop); /** * @brief Specifies the clear color value When clear is requested @@ -138,9 +141,9 @@ namespace gale { render_triangle, render_triangleStrip, //!< Not supported in GALE (TODO : Later) render_triangleFan, //!< Not supported in GALE (TODO : Later) - renderQuad, //!< Not supported in OpenGL-ES2 - renderQuadStrip, //!< Not supported in OpenGL-ES2 - renderPolygon //!< Not supported in OpenGL-ES2 + render_quad, //!< Not supported in OpenGL-ES2 + render_quadStrip, //!< Not supported in OpenGL-ES2 + render_polygon //!< Not supported in OpenGL-ES2 }; /** @@ -186,8 +189,31 @@ namespace gale { bool genBuffers(std::vector& _buffers); bool deleteBuffers(std::vector& _buffers); bool bindBuffer(uint32_t _bufferId); - bool bufferData(size_t _size, const void* _data, GLenum _usage); + enum usage { + usage_streamDraw, + usage_staticDraw, + usage_dynamicDraw + }; + bool bufferData(size_t _size, const void* _data, enum gale::openGL::usage _usage); bool unbindBuffer(); + /* Shader wrapping : */ + namespace shader { + enum type { + type_vertex, + type_fragment + }; + int64_t create(enum gale::openGL::shader::type _type); + void remove(int64_t& _shader); + bool compile(int64_t _shader, const std::string& _data); + }; + namespace program { + int64_t create(); + void remove(int64_t& _prog); + bool attach(int64_t _prog, int64_t _shader); + bool compile(int64_t _prog); + int32_t getAttributeLocation(int64_t _prog, const std::string& _name); + int32_t getUniformLocation(int64_t _prog, const std::string& _name); + }; }; std::ostream& operator <<(std::ostream& _os, const enum openGL::flag& _obj); std::ostream& operator <<(std::ostream& _os, const enum openGL::renderMode& _obj); diff --git a/gale/resource/Program.cpp b/gale/resource/Program.cpp index 9d23f0a..8de9401 100644 --- a/gale/resource/Program.cpp +++ b/gale/resource/Program.cpp @@ -12,6 +12,7 @@ #include #include #include +#include //#define LOCAL_DEBUG GALE_VERBOSE #define LOCAL_DEBUG GALE_DEBUG @@ -153,6 +154,7 @@ void gale::resource::Program::checkGlError(const char* _op, int32_t _localLine, #define LOG_OGL_INTERNAL_BUFFER_LEN (8192) static char l_bufferDisplayError[LOG_OGL_INTERNAL_BUFFER_LEN] = ""; + bool gale::resource::Program::checkIdValidity(int32_t _idElem) { if ( _idElem < 0 || (size_t)_idElem > m_elementList.size()) { @@ -171,12 +173,11 @@ int32_t gale::resource::Program::getAttribute(std::string _elementName) { progAttributeElement tmp; tmp.m_name = _elementName; tmp.m_isAttribute = true; - tmp.m_elementId = glGetAttribLocation(m_program, tmp.m_name.c_str()); + tmp.m_elementId = gale::openGL::program::getAttributeLocation(m_program, tmp.m_name); tmp.m_isLinked = true; if (tmp.m_elementId<0) { GALE_WARNING(" [" << m_elementList.size() << "] glGetAttribLocation(\"" << tmp.m_name << "\") = " << tmp.m_elementId); tmp.m_isLinked = false; - checkGlError("glGetAttribLocation", __LINE__, tmp.m_elementId); } else { GALE_INFO(" [" << m_elementList.size() << "] glGetAttribLocation(\"" << tmp.m_name << "\") = " << tmp.m_elementId); } @@ -194,12 +195,11 @@ int32_t gale::resource::Program::getUniform(std::string _elementName) { progAttributeElement tmp; tmp.m_name = _elementName; tmp.m_isAttribute = false; - tmp.m_elementId = glGetUniformLocation(m_program, tmp.m_name.c_str()); + tmp.m_elementId = gale::openGL::program::getUniformLocation(m_program, tmp.m_name); tmp.m_isLinked = true; if (tmp.m_elementId<0) { GALE_WARNING(" [" << m_elementList.size() << "] glGetUniformLocation(\"" << tmp.m_name << "\") = " << tmp.m_elementId); tmp.m_isLinked = false; - checkGlError("glGetUniformLocation", __LINE__, tmp.m_elementId); } else { GALE_INFO(" [" << m_elementList.size() << "] glGetUniformLocation(\"" << tmp.m_name << "\") = " << tmp.m_elementId); } @@ -213,82 +213,44 @@ void gale::resource::Program::updateContext() { } else { // create the Shader GALE_INFO("Create the Program ... \"" << m_name << "\""); - m_program = glCreateProgram(); - if (0 == m_program) { - GALE_ERROR("program creation return error ..."); - checkGlError("glCreateProgram", __LINE__); + m_program = gale::openGL::program::create(); + if (m_program < 0) { return; } - GALE_DEBUG("Create program with oglID=" << m_program); // first attach vertex shader, and after fragment shader for (size_t iii=0; iiigetShaderType() == GL_VERTEX_SHADER) { - glAttachShader(m_program, m_shaderList[iii]->getGL_ID()); - checkGlError("glAttachShader", __LINE__); + if (m_shaderList[iii]->getShaderType() == gale::openGL::shader::type_vertex) { + gale::openGL::program::attach(m_program, m_shaderList[iii]->getGL_ID()); } } } for (size_t iii=0; iiigetShaderType() == GL_FRAGMENT_SHADER) { - glAttachShader(m_program, m_shaderList[iii]->getGL_ID()); - checkGlError("glAttachShader", __LINE__); + if (m_shaderList[iii]->getShaderType() == gale::openGL::shader::type_fragment) { + gale::openGL::program::attach(m_program, m_shaderList[iii]->getGL_ID()); } } } - glLinkProgram(m_program); - checkGlError("glLinkProgram", __LINE__); - GLint linkStatus = GL_FALSE; - glGetProgramiv(m_program, GL_LINK_STATUS, &linkStatus); - checkGlError("glGetProgramiv", __LINE__); - if (linkStatus != GL_TRUE) { - GLint bufLength = 0; - l_bufferDisplayError[0] = '\0'; - glGetProgramInfoLog(m_program, LOG_OGL_INTERNAL_BUFFER_LEN, &bufLength, l_bufferDisplayError); - char tmpLog[256]; - int32_t idOut=0; + if (gale::openGL::program::compile(m_program) == false) { GALE_ERROR("Could not compile \"PROGRAM\": \"" << m_name << "\""); - for (size_t iii=0; iii= 256) { - tmpLog[idOut] = '\0'; - GALE_ERROR(" == > " << tmpLog); - idOut=0; - } else { - idOut++; - } - if (l_bufferDisplayError[iii] == '\0') { - break; - } - } - if (idOut != 0) { - tmpLog[idOut] = '\0'; - GALE_ERROR(" == > " << tmpLog); - } - glDeleteProgram(m_program); - checkGlError("glDeleteProgram", __LINE__); - m_program = 0; + gale::openGL::program::remove(m_program); return; } m_exist = true; // now get the old attribute requested priviously ... for(size_t iii=0; iii too dangerous ... } else { // create the Shader - if (nullptr == m_fileData) { - m_shader = 0; + if (m_fileData.size() == 0) { + m_shader = -1; return; } GALE_INFO("Create Shader : '" << m_name << "'"); - m_shader = glCreateShader(m_type); - if (!m_shader) { - GALE_ERROR("glCreateShader return error ..."); - checkGlError("glCreateShader"); + m_shader = gale::openGL::shader::create(m_type); + if (m_shader < 0) { GALE_CRITICAL(" can not load shader"); return; } else { GALE_INFO("Compile shader with GLID=" << m_shader); - glShaderSource(m_shader, 1, (const char**)&m_fileData, nullptr); - glCompileShader(m_shader); - GLint compiled = 0; - glGetShaderiv(m_shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - GLint infoLen = 0; - l_bufferDisplayError[0] = '\0'; - glGetShaderInfoLog(m_shader, LOG_OGL_INTERNAL_BUFFER_LEN, &infoLen, l_bufferDisplayError); - const char * tmpShaderType = "GL_FRAGMENT_SHADER"; - if (m_type == GL_VERTEX_SHADER){ - tmpShaderType = "GL_VERTEX_SHADER"; + bool ret = gale::openGL::shader::compile(m_shader, m_fileData); + if (ret == false) { + const char * tmpShaderType = "FRAGMENT SHADER"; + if (m_type == gale::openGL::shader::type_vertex){ + tmpShaderType = "VERTEX SHADER"; } - GALE_ERROR("Could not compile \"" << tmpShaderType << "\" name='" << m_name << "'"); - GALE_ERROR("Error " << l_bufferDisplayError); - std::vector lines = etk::split(m_fileData, '\n'); - for (size_t iii=0 ; iii we need to sqared it to prevent some openGl api error the the displayable size is not all the time 0.0 -> 1.0. bool m_loaded; //!< internal state of the openGl system. // Gale internal API: @@ -38,7 +38,7 @@ namespace gale { void removeContextToLate(); // middleware interface: public: - GLuint getRendererId() const { + uint32_t getRendererId() const { return m_texId; }; const vec2& getUsableSize() const { diff --git a/gale/resource/VirtualBufferObject.cpp b/gale/resource/VirtualBufferObject.cpp index 353f772..4a94f8f 100644 --- a/gale/resource/VirtualBufferObject.cpp +++ b/gale/resource/VirtualBufferObject.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #undef __class__ #define __class__ "resource::VirtualBufferObject" @@ -49,7 +50,7 @@ void gale::resource::VirtualBufferObject::updateContext() { // select the buffer to set data inside it ... if (m_buffer[iii].size()>0) { gale::openGL::bindBuffer(m_vbo[iii]); - gale::openGL::bufferData(sizeof(float)*m_buffer[iii].size(), &((m_buffer[iii])[0]), GL_STATIC_DRAW); + gale::openGL::bufferData(sizeof(float)*m_buffer[iii].size(), &((m_buffer[iii])[0]), gale::openGL::usage_staticDraw); } } } diff --git a/gale/resource/VirtualBufferObject.h b/gale/resource/VirtualBufferObject.h index 430e45f..40a9074 100644 --- a/gale/resource/VirtualBufferObject.h +++ b/gale/resource/VirtualBufferObject.h @@ -24,7 +24,7 @@ namespace gale { class VirtualBufferObject : public gale::Resource { private : bool m_exist; //!< This data is availlable in the Graphic card - std::vector m_vbo; //!< openGl ID of this VBO + std::vector m_vbo; //!< openGl ID of this VBO std::vector m_vboUsed; //!< true if the VBO is allocated or used ... std::vector> m_buffer; //!< data that is availlable in the VBO system ... std::vector m_vboSizeDataOffset; //!< Internal size of the VBO (dynamicly set) @@ -46,7 +46,7 @@ namespace gale { * @brief get the real openGL ID. * @return the Ogl id reference of this VBO. */ - GLuint getGL_ID(int32_t _id) { + int64_t getGL_ID(int32_t _id) { return m_vbo[_id]; }; /** diff --git a/sample/basic.cpp b/sample/basic.cpp index fc67bc6..756af27 100644 --- a/sample/basic.cpp +++ b/sample/basic.cpp @@ -36,7 +36,7 @@ class MainApplication : public gale::Application { void onDraw(gale::Context& _context) { ivec2 size = getSize(); // set the basic openGL view port: (position drawed in the windows) - glViewport(0,0,size.x(),size.y()); + gale::openGL::setViewPort(ivec2(0,0),size); // Clear all the stacked matrix ... gale::openGL::setBasicMatrix(mat4()); // clear background @@ -76,7 +76,7 @@ class MainApplication : public gale::Application { // color : m_GLprogram->sendAttribute(m_GLColor, 4/*r,g,b,a*/, color, 4*sizeof(float)); // Request the draw od the elements : - gale::openGL::drawArrays(GL_TRIANGLES, 0, 3 /*number of points*/); + gale::openGL::drawArrays(gale::openGL::render_triangle, 0, 3 /*number of points*/); m_GLprogram->unUse(); // Restore context of matrix gale::openGL::pop();