aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/graphics/opengl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/graphics/opengl.cpp')
-rw-r--r--src/libjin/graphics/opengl.cpp784
1 files changed, 392 insertions, 392 deletions
diff --git a/src/libjin/graphics/opengl.cpp b/src/libjin/graphics/opengl.cpp
index c1696f4..c00e206 100644
--- a/src/libjin/graphics/opengl.cpp
+++ b/src/libjin/graphics/opengl.cpp
@@ -15,403 +15,403 @@ 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);
+ 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);
unbindCanvas();
unuseShader();
- setClearColor(0, 0, 0, 0xff);
- setColor(0xff, 0xff, 0xff, 0xff);
- setBlendMode(OpenGL::BlendMode::ALPHA);
- }
-
- 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();
- bindFrameBuffer(fbo);
- int w = canvas->getWidth();
- int h = canvas->getHeight();
- glViewport(0, 0, w, h);
- setProjectionMatrix(0, w, 0, h, -1, 1);
-
- mCanvas = canvas;
-
- 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();
+ setClearColor(0, 0, 0, 0xff);
+ setColor(0xff, 0xff, 0xff, 0xff);
+ setBlendMode(OpenGL::BlendMode::ALPHA);
+ }
+
+ 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();
+ bindFrameBuffer(fbo);
+ int w = canvas->getWidth();
+ int h = canvas->getHeight();
+ glViewport(0, 0, w, h);
+ setProjectionMatrix(0, w, 0, h, -1, 1);
+
+ mCanvas = canvas;
+
+ 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();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
- int w = wnd->getW(), h = wnd->getH();
- glViewport(0, 0, w, h);
- setProjectionMatrix(0, w, h, 0, -1, 1);
+ int w = wnd->getW(), h = wnd->getH();
+ glViewport(0, 0, w, h);
+ setProjectionMatrix(0, w, h, 0, -1, 1);
setBlendMode(OpenGL::BlendMode::ALPHA);
- 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
+ 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