From 63547185567a4bc9c66ad2420134e2dc4a1a58ba Mon Sep 17 00:00:00 2001 From: chai Date: Fri, 18 Jan 2019 10:30:32 +0800 Subject: *opengl.h --- src/libjin/game/application.cpp | 2 +- src/libjin/graphics/fonts/ttf.cpp | 2 +- src/libjin/graphics/gl.cpp | 418 --------------------------------- src/libjin/graphics/gl.h | 270 --------------------- src/libjin/graphics/graphic.h | 2 +- src/libjin/graphics/opengl.cpp | 418 +++++++++++++++++++++++++++++++++ src/libjin/graphics/opengl.h | 270 +++++++++++++++++++++ src/libjin/graphics/shaders/shader.cpp | 2 +- src/libjin/graphics/window.cpp | 2 +- 9 files changed, 693 insertions(+), 693 deletions(-) delete mode 100644 src/libjin/graphics/gl.cpp delete mode 100644 src/libjin/graphics/gl.h create mode 100644 src/libjin/graphics/opengl.cpp create mode 100644 src/libjin/graphics/opengl.h (limited to 'src') diff --git a/src/libjin/game/application.cpp b/src/libjin/game/application.cpp index e67231f..c198336 100644 --- a/src/libjin/game/application.cpp +++ b/src/libjin/game/application.cpp @@ -6,7 +6,7 @@ #include "../time/timer.h" #include "../input/event.h" #include "../graphics/window.h" -#include "../graphics/gl.h" +#include "../graphics/opengl.h" #include "../math/math.h" #include "application.h" diff --git a/src/libjin/graphics/fonts/ttf.cpp b/src/libjin/graphics/fonts/ttf.cpp index f47e7e4..1357810 100644 --- a/src/libjin/graphics/fonts/ttf.cpp +++ b/src/libjin/graphics/fonts/ttf.cpp @@ -5,7 +5,7 @@ #include "../../common/array.hpp" -#include "../gl.h" +#include "../opengl.h" #include "../color.h" #include "../shaders/shader.h" diff --git a/src/libjin/graphics/gl.cpp b/src/libjin/graphics/gl.cpp deleted file mode 100644 index b90a29b..0000000 --- a/src/libjin/graphics/gl.cpp +++ /dev/null @@ -1,418 +0,0 @@ -#define OGL2D_IMPLEMENT -#include "../utils/log.h" - -#include "gl.h" -#include "color.h" -#include "canvas.h" -#include "texture.h" -#include "window.h" -#include "shaders/shader.h" -#include "fonts/font.h" - -using namespace JinEngine::Math; -using namespace JinEngine::Graphics; -using namespace JinEngine::Graphics::Shaders; - -namespace JinEngine -{ - namespace Graphics - { - - OpenGL gl; - - Canvas* const OpenGL::SCREEN = NULL; - - OpenGL::OpenGL() - { - memset(&mStats, 0, sizeof(mStats)); - memset(&mColor, 0xff, sizeof(mColor)); - // Set default modelview matrix. - mModelViewMatrices.push_back(Matrix()); - mModelViewMatrix.setIdentity(); - for (Matrix& m : mModelViewMatrices) - mModelViewMatrix *= m; - } - - OpenGL::~OpenGL() - { - } - - bool OpenGL::loadGL() - { - // Init glad library. - if (!gladLoadGLLoader(SDL_GL_GetProcAddress)) - { - jin_log_error("init opengl context failed"); - return false; - } - - return true; - } - - void OpenGL::init() - { - enable(GL_BLEND); - setClearColor(0, 0, 0, 0xff); - setColor(0xff, 0xff, 0xff, 0xff); - setBlendMode(OpenGL::BlendMode::ALPHA); - unbindCanvas(); - unuseShader(); - } - - void OpenGL::enable(GLenum cap) - { - glEnable(cap); - } - - void OpenGL::disable(GLenum cap) - { - glDisable(cap); - } - - void OpenGL::setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) - { - glClearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f); - } - - void OpenGL::popColor() - { - glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a); - } - - void OpenGL::flushError() - { - while (glGetError() != GL_NO_ERROR); - } - - GLuint OpenGL::genTexture() - { - GLuint t; - glGenTextures(1, &t); - return t; - } - - void OpenGL::bindTexture2D(GLuint texture) - { - glBindTexture(GL_TEXTURE_2D, texture); - } - - void OpenGL::deleteTexture(GLuint texture) - { - glDeleteTextures(1, &texture); - } - - void OpenGL::setTexParameter(GLenum pname, GLint param) - { - glTexParameteri(GL_TEXTURE_2D, pname, param); - } - - void OpenGL::texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) - { - glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, pixels); - } - - void OpenGL::texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) - { - glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, width, height, format, type, pixels); - } - - void OpenGL::activeTextureUnit(unsigned int unit) - { - // glActiveTexture selects which texture unit subsequent texture state calls will affect. - glActiveTexture(GL_TEXTURE0 + unit); - } - - void OpenGL::drawArrays(GLenum mode, GLint first, GLsizei count) - { - glDrawArrays(mode, first, count); - ++mStats.drawCalls; - } - - void OpenGL::drawBuffer(GLenum mode) - { - - } - - void OpenGL::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) - { - - } - - void OpenGL::enableClientState(GLenum arr) - { - glEnableClientState(arr); - } - - void OpenGL::disableClientState(GLenum arr) - { - glDisableClientState(arr); - } - - GLuint OpenGL::genFrameBuffer() - { - GLuint fbo; - glGenFramebuffers(1, &fbo); - return fbo; - } - - void OpenGL::bindFrameBuffer(GLuint fbo) - { - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - } - - void OpenGL::ortho(int w, float radio) - { - glOrtho(0, w, w*radio, 0, -1, 1); - } - - void OpenGL::orthox(int w, int h) - { - glOrtho(0, w, h, 0, -1, 1); - } - - void OpenGL::setColor(Channel r, Channel g, Channel b, Channel a) - { - setColor(Color(r, g, b, a)); - } - - void OpenGL::setColor(Color c) - { - mColor = c; - glColor4f(c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f); - } - - Color OpenGL::getColor() - { - return mColor; - } - - void OpenGL::clearMatrix() - { - mModelViewMatrices.clear(); - mModelViewMatrices.push_back(Matrix()); - mModelViewMatrix.setIdentity(); - } - - void OpenGL::pushMatrix() - { - mModelViewMatrices.push_back(Matrix()); - } - - void OpenGL::popMatrix() - { - if (mModelViewMatrices.size() == 1) - return; - mModelViewMatrices.pop_back(); - mModelViewMatrix.setIdentity(); - for (Matrix& m : mModelViewMatrices) - mModelViewMatrix *= m; - } - - void OpenGL::translate(float x, float y) - { - if (mModelViewMatrices.size() == 1) - return; - Matrix& m = mModelViewMatrices.back(); - m.translate(x, y); - mModelViewMatrix.translate(x, y); - } - - void OpenGL::scale(float sx, float sy) - { - if (mModelViewMatrices.size() == 1) - return; - Matrix& m = mModelViewMatrices.back(); - m.scale(sx, sy); - mModelViewMatrix.scale(sx, sy); - } - - void OpenGL::rotate(float r) - { - if (mModelViewMatrices.size() == 1) - return; - Matrix& m = mModelViewMatrices.back(); - m.rotate(r); - mModelViewMatrix.rotate(r); - } - - Matrix OpenGL::getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy) - { - Matrix m; - m.setTransformation(x, y, r, sx, sy, ox, oy); - return mModelViewMatrix*m; - } - - Math::Matrix OpenGL::getModelViewMatrix(const Math::Transform& tansform) - { - return mModelViewMatrix * tansform.getMatrix(); - } - - Matrix OpenGL::getModelViewMatrix() - { - return mModelViewMatrix; - } - - const Matrix& OpenGL::getProjectionMatrix() - { - return mProjectionMatrix; - } - - void OpenGL::setProjectionMatrix(float l, float r, float b, float t, float n, float f) - { - mProjectionMatrix.setOrtho(l, r, b, t, n, f); - } - - OpenGL::BlendMode OpenGL::getBlendMode() - { - return mBlendMode; - } - - void OpenGL::setBlendMode(BlendMode mode) - { - if (mBlendMode == mode) - return; - mBlendMode = mode; - - // result = src * srcFac FUNC dst * dstFac - - GLenum func = GL_FUNC_ADD; - GLenum srcRGB = GL_ONE; - GLenum srcA = GL_ONE; - GLenum dstRGB = GL_ZERO; - GLenum dstA = GL_ZERO; - - switch (mode) - { - case BlendMode::ADDITIVE: - srcRGB = GL_SRC_ALPHA; - srcA = GL_SRC_ALPHA; - dstRGB = GL_ONE; - dstA = GL_ONE; - break; - case BlendMode::PREMULTIPLIEDALPHA: - srcRGB = srcA = GL_ONE; - dstRGB = dstA = GL_ONE_MINUS_SRC_ALPHA; - break; - case BlendMode::ALPHA: - default: - srcRGB = GL_SRC_ALPHA; - srcA = GL_SRC_ALPHA; - dstRGB = GL_ONE_MINUS_SRC_ALPHA; - dstA = GL_ONE_MINUS_SRC_ALPHA; - - break; - } - - glBlendEquation(func); - glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA); - } - - void OpenGL::useShader(Shaders::Shader* shader) - { - if (mShader != shader && shader) - { - glUseProgram(shader->getGLProgramID()); - mShader = shader; - - ++mStats.shaderSwitches; - } - } - - void OpenGL::unuseShader() - { - if (mShader) - { - glUseProgram(0); - mShader = nullptr; - } - } - - Shaders::Shader* OpenGL::getShader() - { - return mShader; - } - - void OpenGL::bindCanvas(Canvas* canvas) - { - if (mCanvas != canvas && canvas) - { - GLuint fbo = canvas->getGLFrameBuffer(); - gl.bindFrameBuffer(fbo); - int w = canvas->getWidth(); - int h = canvas->getHeight(); - glViewport(0, 0, w, h); - gl.setProjectionMatrix(0, w, 0, h, -1, 1); - - mCanvas = canvas; - - gl.enable(GL_BLEND); - gl.enable(GL_TEXTURE_2D); - - gl.setBlendMode(OpenGL::BlendMode::ALPHA); - - ++mStats.canvasSwitches; - } - } - - /** - * bind to default screen render buffer. - * do some coordinates transform work - * https://blog.csdn.net/liji_digital/article/details/79370841 - * https://blog.csdn.net/lyx2007825/article/details/8792475 - */ - void OpenGL::unbindCanvas() - { - // Default bind to default canvas. - if (getCanvas() == SCREEN) - return; - // Get window size as viewport. - Window* wnd = Window::get(); - int w = wnd->getW(); - int h = wnd->getH(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, w, h); - gl.setProjectionMatrix(0, w, h, 0, -1, 1); - - mCanvas = SCREEN; - } - - Canvas* OpenGL::getCanvas() - { - return mCanvas; - } - - void OpenGL::setFont(Fonts::Font* font) - { - if (mFont != font && font) - { - mFont = font; - - ++mStats.fontSwitches; - } - } - - void OpenGL::unsetFont() - { - mFont = nullptr; - } - - Fonts::Font* OpenGL::getFont() - { - return mFont; - } - - void OpenGL::resetStats() - { - mStats.drawCalls = 0; - mStats.canvasSwitches = 0; - mStats.shaderSwitches = 0; - mStats.fontSwitches = 0; - } - - OpenGL::Stats& OpenGL::getStats() - { - return mStats; - } - - } // namespace Graphics -} // namespace JinEngine \ No newline at end of file diff --git a/src/libjin/graphics/gl.h b/src/libjin/graphics/gl.h deleted file mode 100644 index e97ebb6..0000000 --- a/src/libjin/graphics/gl.h +++ /dev/null @@ -1,270 +0,0 @@ -#ifndef __JE_OPENGL_H__ -#define __JE_OPENGL_H__ - -#include - -#include "../math/matrix.h" -#include "../math/transform.h" - -//#include "GLee/GLee.h" -#include "glad/glad.h" - -#include "color.h" - -namespace JinEngine -{ - namespace Graphics - { - // Wrap OpenGL API. - - namespace Shaders { class Shader; }; - namespace Fonts { class Font; }; - - class Texture; - - class Canvas; - - class OpenGL - { - public: - /// - /// Blend mode. - /// https://www.andersriggelsen.dk/glblendfunc.php - /// - enum class BlendMode - { - ALPHA = 1, - ADDITIVE = 2, - PREMULTIPLIEDALPHA = 3, - }; - - struct Stats - { - int drawCalls; - //int drawCallsBatched; - int canvasSwitches; - int shaderSwitches; - int fontSwitches; - int textures; - int canvases; - int fonts; - //int64 textureMemory; - }; - - static Canvas* const SCREEN; - - OpenGL(); - ~OpenGL(); - - bool loadGL(); - - void init(); - - void enable(GLenum cap); - - void disable(GLenum cap); - - void setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a); - - void pushColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a = 255); - - void popColor(); - - void flushError(); - - GLuint genTexture(); - - void deleteTexture(GLuint texture); - - void bindTexture2D(GLuint texture = 0); - - void setTexParameter(GLenum pname, GLint param); - - void texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels = NULL); - - void texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); - - void activeTextureUnit(unsigned int unit = 0); - - void drawArrays(GLenum mode, GLint first, GLsizei count); - - void drawBuffer(GLenum mode); - - void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); - - void enableClientState(GLenum arr); - - void disableClientState(GLenum arr); - - GLuint genFrameBuffer(); - - void bindFrameBuffer(GLuint fbo); - - void ortho(int w, float radio); - - void orthox(int w, int h); - - void setColor(Channel r, Channel g, Channel b, Channel a); - - void setColor(Color c); - - Color getColor(); - - void clearMatrix(); - - void pushMatrix(); - - void translate(float x, float y); - - void scale(float sx, float sy); - - void rotate(float r); - - void popMatrix(); - - /// - /// - /// - Math::Matrix getModelViewMatrix(const Math::Transform& tansform); - - /// - /// Get model view matrix. - /// - Math::Matrix getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy); - - /// - /// Get model view matrix. - /// - Math::Matrix getModelViewMatrix(); - - /// - /// Set orthogonal matrix. - /// - void setProjectionMatrix(float l, float r, float b, float t, float n, float f); - - /// - /// Get orthogonal matrix. - /// - const Math::Matrix& getProjectionMatrix(); - - /// - /// - /// - void useShader(Shaders::Shader* shader); - - /// - /// - /// - void unuseShader(); - - /// - /// - /// - Shaders::Shader* getShader(); - - /// - /// - /// - void setFont(Fonts::Font* font); - - /// - /// - /// - void unsetFont(); - - /// - /// - /// - Fonts::Font* getFont(); - - /// - /// - /// - void bindCanvas(Canvas* canvas); - - /// - /// - /// - void unbindCanvas(); - - /// - /// - /// - Canvas* getCanvas(); - - /// - /// - /// - void setBlendMode(BlendMode mode); - - /// - /// - /// - BlendMode getBlendMode(); - - /// - /// - /// - void resetStats(); - - /// - /// - /// - Stats& getStats(); - - private: - - /// - /// - /// - std::vector mModelViewMatrices; - - /// - /// - /// - Math::Matrix mModelViewMatrix; - - /// - /// - /// - Math::Matrix mProjectionMatrix; - - /// - /// - /// - BlendMode mBlendMode; - - /// - /// - /// - Color mColor; - - /// - /// - /// - Canvas* mCanvas; - - /// - /// - /// - Shaders::Shader* mShader; - - /// - /// - /// - Fonts::Font* mFont; - - /// - /// - /// - Stats mStats; - - }; - - // Singleton. - extern OpenGL gl; - - } // namespace Graphics -} // namespace JinEngine - -#endif // __JE_OPENGL_H__ \ No newline at end of file diff --git a/src/libjin/graphics/graphic.h b/src/libjin/graphics/graphic.h index ac2bc0e..857785d 100644 --- a/src/libjin/graphics/graphic.h +++ b/src/libjin/graphics/graphic.h @@ -9,7 +9,7 @@ #include "../math/transform.h" #include "renderable.h" -#include "gl.h" +#include "opengl.h" #include "bitmap.h" namespace JinEngine diff --git a/src/libjin/graphics/opengl.cpp b/src/libjin/graphics/opengl.cpp new file mode 100644 index 0000000..da3659d --- /dev/null +++ b/src/libjin/graphics/opengl.cpp @@ -0,0 +1,418 @@ +#define OGL2D_IMPLEMENT +#include "../utils/log.h" + +#include "opengl.h" +#include "color.h" +#include "canvas.h" +#include "texture.h" +#include "window.h" +#include "shaders/shader.h" +#include "fonts/font.h" + +using namespace JinEngine::Math; +using namespace JinEngine::Graphics; +using namespace JinEngine::Graphics::Shaders; + +namespace JinEngine +{ + namespace Graphics + { + + OpenGL gl; + + Canvas* const OpenGL::SCREEN = NULL; + + OpenGL::OpenGL() + { + memset(&mStats, 0, sizeof(mStats)); + memset(&mColor, 0xff, sizeof(mColor)); + // Set default modelview matrix. + mModelViewMatrices.push_back(Matrix()); + mModelViewMatrix.setIdentity(); + for (Matrix& m : mModelViewMatrices) + mModelViewMatrix *= m; + } + + OpenGL::~OpenGL() + { + } + + bool OpenGL::loadGL() + { + // Init glad library. + if (!gladLoadGLLoader(SDL_GL_GetProcAddress)) + { + jin_log_error("init opengl context failed"); + return false; + } + + return true; + } + + void OpenGL::init() + { + enable(GL_BLEND); + setClearColor(0, 0, 0, 0xff); + setColor(0xff, 0xff, 0xff, 0xff); + setBlendMode(OpenGL::BlendMode::ALPHA); + unbindCanvas(); + unuseShader(); + } + + void OpenGL::enable(GLenum cap) + { + glEnable(cap); + } + + void OpenGL::disable(GLenum cap) + { + glDisable(cap); + } + + void OpenGL::setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) + { + glClearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f); + } + + void OpenGL::popColor() + { + glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a); + } + + void OpenGL::flushError() + { + while (glGetError() != GL_NO_ERROR); + } + + GLuint OpenGL::genTexture() + { + GLuint t; + glGenTextures(1, &t); + return t; + } + + void OpenGL::bindTexture2D(GLuint texture) + { + glBindTexture(GL_TEXTURE_2D, texture); + } + + void OpenGL::deleteTexture(GLuint texture) + { + glDeleteTextures(1, &texture); + } + + void OpenGL::setTexParameter(GLenum pname, GLint param) + { + glTexParameteri(GL_TEXTURE_2D, pname, param); + } + + void OpenGL::texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) + { + glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, type, pixels); + } + + void OpenGL::texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) + { + glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, width, height, format, type, pixels); + } + + void OpenGL::activeTextureUnit(unsigned int unit) + { + // glActiveTexture selects which texture unit subsequent texture state calls will affect. + glActiveTexture(GL_TEXTURE0 + unit); + } + + void OpenGL::drawArrays(GLenum mode, GLint first, GLsizei count) + { + glDrawArrays(mode, first, count); + ++mStats.drawCalls; + } + + void OpenGL::drawBuffer(GLenum mode) + { + + } + + void OpenGL::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) + { + + } + + void OpenGL::enableClientState(GLenum arr) + { + glEnableClientState(arr); + } + + void OpenGL::disableClientState(GLenum arr) + { + glDisableClientState(arr); + } + + GLuint OpenGL::genFrameBuffer() + { + GLuint fbo; + glGenFramebuffers(1, &fbo); + return fbo; + } + + void OpenGL::bindFrameBuffer(GLuint fbo) + { + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + } + + void OpenGL::ortho(int w, float radio) + { + glOrtho(0, w, w*radio, 0, -1, 1); + } + + void OpenGL::orthox(int w, int h) + { + glOrtho(0, w, h, 0, -1, 1); + } + + void OpenGL::setColor(Channel r, Channel g, Channel b, Channel a) + { + setColor(Color(r, g, b, a)); + } + + void OpenGL::setColor(Color c) + { + mColor = c; + glColor4f(c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f); + } + + Color OpenGL::getColor() + { + return mColor; + } + + void OpenGL::clearMatrix() + { + mModelViewMatrices.clear(); + mModelViewMatrices.push_back(Matrix()); + mModelViewMatrix.setIdentity(); + } + + void OpenGL::pushMatrix() + { + mModelViewMatrices.push_back(Matrix()); + } + + void OpenGL::popMatrix() + { + if (mModelViewMatrices.size() == 1) + return; + mModelViewMatrices.pop_back(); + mModelViewMatrix.setIdentity(); + for (Matrix& m : mModelViewMatrices) + mModelViewMatrix *= m; + } + + void OpenGL::translate(float x, float y) + { + if (mModelViewMatrices.size() == 1) + return; + Matrix& m = mModelViewMatrices.back(); + m.translate(x, y); + mModelViewMatrix.translate(x, y); + } + + void OpenGL::scale(float sx, float sy) + { + if (mModelViewMatrices.size() == 1) + return; + Matrix& m = mModelViewMatrices.back(); + m.scale(sx, sy); + mModelViewMatrix.scale(sx, sy); + } + + void OpenGL::rotate(float r) + { + if (mModelViewMatrices.size() == 1) + return; + Matrix& m = mModelViewMatrices.back(); + m.rotate(r); + mModelViewMatrix.rotate(r); + } + + Matrix OpenGL::getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy) + { + Matrix m; + m.setTransformation(x, y, r, sx, sy, ox, oy); + return mModelViewMatrix*m; + } + + Math::Matrix OpenGL::getModelViewMatrix(const Math::Transform& tansform) + { + return mModelViewMatrix * tansform.getMatrix(); + } + + Matrix OpenGL::getModelViewMatrix() + { + return mModelViewMatrix; + } + + const Matrix& OpenGL::getProjectionMatrix() + { + return mProjectionMatrix; + } + + void OpenGL::setProjectionMatrix(float l, float r, float b, float t, float n, float f) + { + mProjectionMatrix.setOrtho(l, r, b, t, n, f); + } + + OpenGL::BlendMode OpenGL::getBlendMode() + { + return mBlendMode; + } + + void OpenGL::setBlendMode(BlendMode mode) + { + if (mBlendMode == mode) + return; + mBlendMode = mode; + + // result = src * srcFac FUNC dst * dstFac + + GLenum func = GL_FUNC_ADD; + GLenum srcRGB = GL_ONE; + GLenum srcA = GL_ONE; + GLenum dstRGB = GL_ZERO; + GLenum dstA = GL_ZERO; + + switch (mode) + { + case BlendMode::ADDITIVE: + srcRGB = GL_SRC_ALPHA; + srcA = GL_SRC_ALPHA; + dstRGB = GL_ONE; + dstA = GL_ONE; + break; + case BlendMode::PREMULTIPLIEDALPHA: + srcRGB = srcA = GL_ONE; + dstRGB = dstA = GL_ONE_MINUS_SRC_ALPHA; + break; + case BlendMode::ALPHA: + default: + srcRGB = GL_SRC_ALPHA; + srcA = GL_SRC_ALPHA; + dstRGB = GL_ONE_MINUS_SRC_ALPHA; + dstA = GL_ONE_MINUS_SRC_ALPHA; + + break; + } + + glBlendEquation(func); + glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA); + } + + void OpenGL::useShader(Shaders::Shader* shader) + { + if (mShader != shader && shader) + { + glUseProgram(shader->getGLProgramID()); + mShader = shader; + + ++mStats.shaderSwitches; + } + } + + void OpenGL::unuseShader() + { + if (mShader) + { + glUseProgram(0); + mShader = nullptr; + } + } + + Shaders::Shader* OpenGL::getShader() + { + return mShader; + } + + void OpenGL::bindCanvas(Canvas* canvas) + { + if (mCanvas != canvas && canvas) + { + GLuint fbo = canvas->getGLFrameBuffer(); + gl.bindFrameBuffer(fbo); + int w = canvas->getWidth(); + int h = canvas->getHeight(); + glViewport(0, 0, w, h); + gl.setProjectionMatrix(0, w, 0, h, -1, 1); + + mCanvas = canvas; + + gl.enable(GL_BLEND); + gl.enable(GL_TEXTURE_2D); + + gl.setBlendMode(OpenGL::BlendMode::ALPHA); + + ++mStats.canvasSwitches; + } + } + + /** + * bind to default screen render buffer. + * do some coordinates transform work + * https://blog.csdn.net/liji_digital/article/details/79370841 + * https://blog.csdn.net/lyx2007825/article/details/8792475 + */ + void OpenGL::unbindCanvas() + { + // Default bind to default canvas. + if (getCanvas() == SCREEN) + return; + // Get window size as viewport. + Window* wnd = Window::get(); + int w = wnd->getW(); + int h = wnd->getH(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, w, h); + gl.setProjectionMatrix(0, w, h, 0, -1, 1); + + mCanvas = SCREEN; + } + + Canvas* OpenGL::getCanvas() + { + return mCanvas; + } + + void OpenGL::setFont(Fonts::Font* font) + { + if (mFont != font && font) + { + mFont = font; + + ++mStats.fontSwitches; + } + } + + void OpenGL::unsetFont() + { + mFont = nullptr; + } + + Fonts::Font* OpenGL::getFont() + { + return mFont; + } + + void OpenGL::resetStats() + { + mStats.drawCalls = 0; + mStats.canvasSwitches = 0; + mStats.shaderSwitches = 0; + mStats.fontSwitches = 0; + } + + OpenGL::Stats& OpenGL::getStats() + { + return mStats; + } + + } // namespace Graphics +} // namespace JinEngine \ No newline at end of file diff --git a/src/libjin/graphics/opengl.h b/src/libjin/graphics/opengl.h new file mode 100644 index 0000000..e97ebb6 --- /dev/null +++ b/src/libjin/graphics/opengl.h @@ -0,0 +1,270 @@ +#ifndef __JE_OPENGL_H__ +#define __JE_OPENGL_H__ + +#include + +#include "../math/matrix.h" +#include "../math/transform.h" + +//#include "GLee/GLee.h" +#include "glad/glad.h" + +#include "color.h" + +namespace JinEngine +{ + namespace Graphics + { + // Wrap OpenGL API. + + namespace Shaders { class Shader; }; + namespace Fonts { class Font; }; + + class Texture; + + class Canvas; + + class OpenGL + { + public: + /// + /// Blend mode. + /// https://www.andersriggelsen.dk/glblendfunc.php + /// + enum class BlendMode + { + ALPHA = 1, + ADDITIVE = 2, + PREMULTIPLIEDALPHA = 3, + }; + + struct Stats + { + int drawCalls; + //int drawCallsBatched; + int canvasSwitches; + int shaderSwitches; + int fontSwitches; + int textures; + int canvases; + int fonts; + //int64 textureMemory; + }; + + static Canvas* const SCREEN; + + OpenGL(); + ~OpenGL(); + + bool loadGL(); + + void init(); + + void enable(GLenum cap); + + void disable(GLenum cap); + + void setClearColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a); + + void pushColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a = 255); + + void popColor(); + + void flushError(); + + GLuint genTexture(); + + void deleteTexture(GLuint texture); + + void bindTexture2D(GLuint texture = 0); + + void setTexParameter(GLenum pname, GLint param); + + void texImage(GLint internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels = NULL); + + void texSubImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); + + void activeTextureUnit(unsigned int unit = 0); + + void drawArrays(GLenum mode, GLint first, GLsizei count); + + void drawBuffer(GLenum mode); + + void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); + + void enableClientState(GLenum arr); + + void disableClientState(GLenum arr); + + GLuint genFrameBuffer(); + + void bindFrameBuffer(GLuint fbo); + + void ortho(int w, float radio); + + void orthox(int w, int h); + + void setColor(Channel r, Channel g, Channel b, Channel a); + + void setColor(Color c); + + Color getColor(); + + void clearMatrix(); + + void pushMatrix(); + + void translate(float x, float y); + + void scale(float sx, float sy); + + void rotate(float r); + + void popMatrix(); + + /// + /// + /// + Math::Matrix getModelViewMatrix(const Math::Transform& tansform); + + /// + /// Get model view matrix. + /// + Math::Matrix getModelViewMatrix(float x, float y, float sx, float sy, float r, float ox, float oy); + + /// + /// Get model view matrix. + /// + Math::Matrix getModelViewMatrix(); + + /// + /// Set orthogonal matrix. + /// + void setProjectionMatrix(float l, float r, float b, float t, float n, float f); + + /// + /// Get orthogonal matrix. + /// + const Math::Matrix& getProjectionMatrix(); + + /// + /// + /// + void useShader(Shaders::Shader* shader); + + /// + /// + /// + void unuseShader(); + + /// + /// + /// + Shaders::Shader* getShader(); + + /// + /// + /// + void setFont(Fonts::Font* font); + + /// + /// + /// + void unsetFont(); + + /// + /// + /// + Fonts::Font* getFont(); + + /// + /// + /// + void bindCanvas(Canvas* canvas); + + /// + /// + /// + void unbindCanvas(); + + /// + /// + /// + Canvas* getCanvas(); + + /// + /// + /// + void setBlendMode(BlendMode mode); + + /// + /// + /// + BlendMode getBlendMode(); + + /// + /// + /// + void resetStats(); + + /// + /// + /// + Stats& getStats(); + + private: + + /// + /// + /// + std::vector mModelViewMatrices; + + /// + /// + /// + Math::Matrix mModelViewMatrix; + + /// + /// + /// + Math::Matrix mProjectionMatrix; + + /// + /// + /// + BlendMode mBlendMode; + + /// + /// + /// + Color mColor; + + /// + /// + /// + Canvas* mCanvas; + + /// + /// + /// + Shaders::Shader* mShader; + + /// + /// + /// + Fonts::Font* mFont; + + /// + /// + /// + Stats mStats; + + }; + + // Singleton. + extern OpenGL gl; + + } // namespace Graphics +} // namespace JinEngine + +#endif // __JE_OPENGL_H__ \ No newline at end of file diff --git a/src/libjin/graphics/shaders/shader.cpp b/src/libjin/graphics/shaders/shader.cpp index c7f6f11..dce795d 100644 --- a/src/libjin/graphics/shaders/shader.cpp +++ b/src/libjin/graphics/shaders/shader.cpp @@ -8,7 +8,7 @@ #include "../../utils/log.h" #include "../../utils/macros.h" -#include "../gl.h" +#include "../opengl.h" #include "../window.h" #include "jsl_compiler.h" diff --git a/src/libjin/graphics/window.cpp b/src/libjin/graphics/window.cpp index 6171c9d..479961b 100644 --- a/src/libjin/graphics/window.cpp +++ b/src/libjin/graphics/window.cpp @@ -10,7 +10,7 @@ #include "shaders/shader.h" #include "window.h" -#include "gl.h" +#include "opengl.h" #include "canvas.h" using namespace JinEngine::Graphics::Shaders; -- cgit v1.1-26-g67d0