From 61e9fc59323157bbd3ea024e816981b975d5b2c8 Mon Sep 17 00:00:00 2001 From: Andrei Karas <akaras@inbox.ru> Date: Mon, 9 Jun 2014 22:11:31 +0300 Subject: Add basic texture drawing in modernopengl. --- src/render/modernopenglgraphics.cpp | 154 ++++++++++++++++++++++++++++------ src/render/modernopenglgraphics.h | 19 ++++- src/render/shaders/shadersmanager.cpp | 7 ++ src/render/shaders/shadersmanager.h | 2 + 4 files changed, 154 insertions(+), 28 deletions(-) (limited to 'src/render') diff --git a/src/render/modernopenglgraphics.cpp b/src/render/modernopenglgraphics.cpp index 141b6ccc7..98e125170 100644 --- a/src/render/modernopenglgraphics.cpp +++ b/src/render/modernopenglgraphics.cpp @@ -56,6 +56,7 @@ ModernOpenGLGraphics::ModernOpenGLGraphics() : mFloatTexArrayCached(nullptr), mShortVertArrayCached(nullptr), mSimpleProgram(nullptr), + mTextureProgram(nullptr), mAlphaCached(1.0F), mVpCached(0), mTexture(false), @@ -64,11 +65,16 @@ ModernOpenGLGraphics::ModernOpenGLGraphics() : mImageCached(0), mFloatColor(1.0F), mMaxVertices(500), - mSimpleId(0U), - mSimpleColor(0U), - mSimplePos(0), - mScreenUniform(0U), + mSimpleProgramId(0U), + mTextureProgramId(0U), + mSimpleColorUniform(0U), + mSimplePosAttrib(0), + mTexturePosAttrib(0), + mTexAttrib(0), + mSimpleScreenUniform(0U), + mTextureScreenUniform(0U), mColorAlpha(false), + mTextureDraw(false), #ifdef DEBUG_BIND_TEXTURE mOldTexture(), mOldTextureId(0), @@ -111,15 +117,22 @@ void ModernOpenGLGraphics::postInit() { logger->log("Compiling shaders"); mSimpleProgram = shaders.getSimpleProgram(); - mSimpleId = mSimpleProgram->getProgramId(); - if (mSimpleProgram) + mSimpleProgramId = mSimpleProgram->getProgramId(); + mTextureProgram = shaders.getTextureProgram(); + mTextureProgramId = mTextureProgram->getProgramId(); + if (mSimpleProgram && mTextureProgram) { logger->log("Shaders compilation done."); - mglUseProgram(mSimpleId); - mSimplePos = mglGetAttribLocation(mSimpleId, "simplePos"); - mglEnableVertexAttribArray(mSimplePos); - mSimpleColor = mglGetUniformLocation(mSimpleId, "simpleColor"); - mScreenUniform = mglGetUniformLocation(mSimpleId, "screen"); + mglUseProgram(mSimpleProgramId); + mSimplePosAttrib = mglGetAttribLocation(mSimpleProgramId, "simplePos"); + mglEnableVertexAttribArray(mSimplePosAttrib); + mSimpleColorUniform = mglGetUniformLocation(mSimpleProgramId, "simpleColor"); + mSimpleScreenUniform = mglGetUniformLocation(mSimpleProgramId, "screen"); + + mTexturePosAttrib = mglGetAttribLocation(mTextureProgramId, "texturePos"); + mTexAttrib = mglGetAttribLocation(mTextureProgramId, "texcoord"); + mTextureScreenUniform = mglGetUniformLocation(mTextureProgramId, "screen"); + screenResized(); } else @@ -130,7 +143,10 @@ void ModernOpenGLGraphics::postInit() void ModernOpenGLGraphics::screenResized() { - mglUniform2f(mScreenUniform, + mglUniform2f(mSimpleScreenUniform, + static_cast<float>(mWidth) / 2.0f, + static_cast<float>(mHeight) / 2.0f); + mglUniform2f(mTextureScreenUniform, static_cast<float>(mWidth) / 2.0f, static_cast<float>(mHeight) / 2.0f); } @@ -178,7 +194,7 @@ void ModernOpenGLGraphics::setColorAll(const Color &color, mColorAlpha = (color.a != 255); if (mColorAlpha) { - mglUniform4f(mSimpleColor, + mglUniform4f(mSimpleColorUniform, static_cast<float>(color.r) / 255.0F, static_cast<float>(color.g) / 255.0F, static_cast<float>(color.b) / 255.0F, @@ -186,7 +202,7 @@ void ModernOpenGLGraphics::setColorAll(const Color &color, } else { - mglUniform4f(mSimpleColor, + mglUniform4f(mSimpleColorUniform, static_cast<float>(color.r) / 255.0F, static_cast<float>(color.g) / 255.0F, static_cast<float>(color.b) / 255.0F, @@ -194,11 +210,62 @@ void ModernOpenGLGraphics::setColorAll(const Color &color, } } -static inline void drawQuad(const Image *const image, - const int srcX, const int srcY, - const int dstX, const int dstY, - const int width, const int height) +void ModernOpenGLGraphics::setColorAlpha(const float alpha) { + // here need set alpha uniform for textures only +/* + if (!mIsByteColor && mFloatColor == alpha) + return; + + glColor4f(1.0F, 1.0F, 1.0F, alpha); + mIsByteColor = false; + mFloatColor = alpha; +*/ +} + +void ModernOpenGLGraphics::drawQuad(const Image *const image, + const int srcX, const int srcY, + const int dstX, const int dstY, + const int width, const int height) +{ + + const float tw = static_cast<float>(image->mTexWidth); + const float th = static_cast<float>(image->mTexHeight); + // Find OpenGL normalized texture coordinates. + const float texX1 = static_cast<float>(srcX) / tw; + const float texY1 = static_cast<float>(srcY) / th; + const float texX2 = static_cast<float>(srcX + width) / tw; + const float texY2 = static_cast<float>(srcY + height) / th; + const float x1 = static_cast<GLfloat>(dstX); + const float y1 = static_cast<GLfloat>(dstY); + const float x2 = x1 + static_cast<GLfloat>(width); + const float y2 = y1 + static_cast<GLfloat>(height); + + GLfloat vertices[] = + { + x1, y1, texX1, texY1, + x2, y1, texX2, texY1, + x1, y2, texX1, texY2, + x2, y2, texX2, texY2 + }; + + GLuint vbo; + mglGenBuffers(1, &vbo); + mglBindBuffer(GL_ARRAY_BUFFER, vbo); + mglBufferData(GL_ARRAY_BUFFER, sizeof(vertices), + vertices, GL_DYNAMIC_DRAW); + +// mglEnableVertexAttribArray(mTexturePosAttrib); + mglVertexAttribPointer(mTexturePosAttrib, 2, GL_FLOAT, GL_FALSE, + 4 * sizeof(GLfloat), 0); +// mglEnableVertexAttribArray(mTexAttrib); + mglVertexAttribPointer(mTexAttrib, 2, GL_FLOAT, GL_FALSE, + 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat))); + +#ifdef DEBUG_DRAW_CALLS + MobileOpenGLGraphics::mDrawCalls ++; +#endif + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } static inline void drawRescaledQuad(const Image *const image, @@ -219,6 +286,20 @@ bool ModernOpenGLGraphics::drawImage(const Image *const image, bool ModernOpenGLGraphics::drawImageInline(const Image *const image, int dstX, int dstY) { + FUNC_BLOCK("Graphics::drawImage", 1) + if (!image) + return false; + + setColorAlpha(image->mAlpha); +#ifdef DEBUG_BIND_TEXTURE + debugBindTexture(image); +#endif + bindTexture(GL_TEXTURE_2D, image->mGLImage); + setTexturingAndBlending(true); + + const SDL_Rect &imageRect = image->mBounds; + drawQuad(image, imageRect.x, imageRect.y, + dstX, dstY, imageRect.w, imageRect.h); return true; } @@ -542,11 +623,10 @@ void ModernOpenGLGraphics::drawRectangle(const Rect& rect) mglBindBuffer(GL_ARRAY_BUFFER, vbo); mglBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW); -// mglEnableVertexAttribArray(mSimplePos); - mglVertexAttribPointer(mSimplePos, 2, GL_FLOAT, GL_FALSE, 0, 0); +// mglEnableVertexAttribArray(mSimplePosAttrib); + mglVertexAttribPointer(mSimplePosAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_LINE_LOOP, 0, 4); - updateScreen(); mglDeleteBuffers(1, &vbo); } @@ -571,11 +651,10 @@ void ModernOpenGLGraphics::fillRectangle(const Rect& rect) mglBindBuffer(GL_ARRAY_BUFFER, vbo); mglBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW); -// mglEnableVertexAttribArray(mSimplePos); - mglVertexAttribPointer(mSimplePos, 2, GL_FLOAT, GL_FALSE, 0, 0); +// mglEnableVertexAttribArray(mSimplePosAttrib); + mglVertexAttribPointer(mSimplePosAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - updateScreen(); mglDeleteBuffers(1, &vbo); } @@ -584,6 +663,17 @@ void ModernOpenGLGraphics::setTexturingAndBlending(const bool enable) { if (enable) { + if (!mTextureDraw) + { + mTextureDraw = true; + mglDisableVertexAttribArray(mSimplePosAttrib); + mglUseProgram(mTextureProgramId); + mglEnableVertexAttribArray(mTexturePosAttrib); + mglEnableVertexAttribArray(mTexAttrib); + mglUniform2f(mTextureScreenUniform, + static_cast<float>(mWidth) / 2.0f, + static_cast<float>(mHeight) / 2.0f); + } if (!mAlpha) { glEnable(GL_BLEND); @@ -592,6 +682,22 @@ void ModernOpenGLGraphics::setTexturingAndBlending(const bool enable) } else { + if (mTextureDraw) + { + mTextureDraw = false; + mglDisableVertexAttribArray(mTexturePosAttrib); + mglDisableVertexAttribArray(mTexAttrib); + mglUseProgram(mSimpleProgramId); + mglEnableVertexAttribArray(mSimplePosAttrib); + mglUniform2f(mSimpleScreenUniform, + static_cast<float>(mWidth) / 2.0f, + static_cast<float>(mHeight) / 2.0f); + mglUniform4f(mSimpleColorUniform, + static_cast<float>(mColor.r) / 255.0F, + static_cast<float>(mColor.g) / 255.0F, + static_cast<float>(mColor.b) / 255.0F, + static_cast<float>(mColor.a) / 255.0F); + } if (mAlpha && !mColorAlpha) { glDisable(GL_BLEND); diff --git a/src/render/modernopenglgraphics.h b/src/render/modernopenglgraphics.h index 2e80fb56a..8e60c5b5f 100644 --- a/src/render/modernopenglgraphics.h +++ b/src/render/modernopenglgraphics.h @@ -73,11 +73,17 @@ class ModernOpenGLGraphics final : public Graphics #include "render/openglgraphicsdefadvanced.hpp" private: + void drawQuad(const Image *const image, + const int srcX, const int srcY, + const int dstX, const int dstY, + const int width, const int height); + GLfloat *mFloatTexArray; GLshort *mShortVertArray; GLfloat *mFloatTexArrayCached; GLshort *mShortVertArrayCached; ShaderProgram *mSimpleProgram; + ShaderProgram *mTextureProgram; float mAlphaCached; int mVpCached; bool mTexture; @@ -87,11 +93,16 @@ class ModernOpenGLGraphics final : public Graphics GLuint mImageCached; float mFloatColor; int mMaxVertices; - GLuint mSimpleId; - GLuint mSimpleColor; - GLint mSimplePos; - GLuint mScreenUniform; + GLuint mSimpleProgramId; + GLuint mTextureProgramId; + GLuint mSimpleColorUniform; + GLint mSimplePosAttrib; + GLint mTexturePosAttrib; + GLint mTexAttrib; + GLuint mSimpleScreenUniform; + GLuint mTextureScreenUniform; bool mColorAlpha; + bool mTextureDraw; #ifdef DEBUG_BIND_TEXTURE std::string mOldTexture; unsigned mOldTextureId; diff --git a/src/render/shaders/shadersmanager.cpp b/src/render/shaders/shadersmanager.cpp index f9c305d79..8a1072deb 100644 --- a/src/render/shaders/shadersmanager.cpp +++ b/src/render/shaders/shadersmanager.cpp @@ -118,4 +118,11 @@ ShaderProgram *ShadersManager::getSimpleProgram() return createProgram(dir + paths.getStringValue("simpleVertexShader"), dir + paths.getStringValue("simpleFragmentShader")); } + +ShaderProgram *ShadersManager::getTextureProgram() +{ + const std::string dir = paths.getStringValue("shaders"); + return createProgram(dir + paths.getStringValue("textureVertexShader"), + dir + paths.getStringValue("textureFragmentShader")); +} #endif diff --git a/src/render/shaders/shadersmanager.h b/src/render/shaders/shadersmanager.h index 50e714aba..b525d18e1 100644 --- a/src/render/shaders/shadersmanager.h +++ b/src/render/shaders/shadersmanager.h @@ -41,6 +41,8 @@ class ShadersManager final A_WARN_UNUSED; ShaderProgram *getSimpleProgram(); + + ShaderProgram *getTextureProgram(); }; extern ShadersManager shaders; -- cgit v1.2.3-70-g09d2