diff options
author | Andrei Karas <akaras@inbox.ru> | 2014-06-12 23:23:00 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2014-06-13 12:41:35 +0300 |
commit | be74509b31b26e714c6b380e17ed3935ec0b6cf0 (patch) | |
tree | 7f575c73694e0cb3673c5b648e7b5e48bc97100f /src/render/modernopenglgraphics.cpp | |
parent | bcb340f51ca2d69fd062d6548ef283303d43d9ac (diff) | |
download | manaplus-be74509b31b26e714c6b380e17ed3935ec0b6cf0.tar.gz manaplus-be74509b31b26e714c6b380e17ed3935ec0b6cf0.tar.bz2 manaplus-be74509b31b26e714c6b380e17ed3935ec0b6cf0.tar.xz manaplus-be74509b31b26e714c6b380e17ed3935ec0b6cf0.zip |
In modernopengl add support for buffered draw tile collection.
This is first cached function implemented in modernopengl.
Also add support for bind buffer attributes.
Add finalize method to convert any cached data into data for GPU.
Diffstat (limited to 'src/render/modernopenglgraphics.cpp')
-rw-r--r-- | src/render/modernopenglgraphics.cpp | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/src/render/modernopenglgraphics.cpp b/src/render/modernopenglgraphics.cpp index 11fda1b41..b2e33cbc9 100644 --- a/src/render/modernopenglgraphics.cpp +++ b/src/render/modernopenglgraphics.cpp @@ -99,6 +99,7 @@ ModernOpenGLGraphics::ModernOpenGLGraphics() : mVao(0U), mVbo(0U), mVboCached(0U), + mAttributesCached(0U), mColorAlpha(false), mTextureDraw(false), #ifdef DEBUG_BIND_TEXTURE @@ -168,6 +169,7 @@ void ModernOpenGLGraphics::postInit() mglBindVertexBuffer(0, mVbo, 0, 4 * sizeof(GLfloat)); mglVertexAttribBinding(mPosAttrib, 0); + mAttributesCached = mVbo; screenResized(); } @@ -323,6 +325,7 @@ bool ModernOpenGLGraphics::drawImageInline(const Image *const image, #endif bindTexture(GL_TEXTURE_2D, image->mGLImage); setTexturingAndBlending(true); + bindArrayBufferAndAttributes(mVbo); setColorAlpha(image->mAlpha); const ClipRect &clipArea = mClipStack.top(); @@ -369,6 +372,7 @@ bool ModernOpenGLGraphics::drawRescaledImage(const Image *const image, #endif bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage); setTexturingAndBlending(true); + bindArrayBufferAndAttributes(mVbo); const ClipRect &clipArea = mClipStack.top(); // Draw a textured quad. @@ -416,6 +420,7 @@ void ModernOpenGLGraphics::drawPatternInline(const Image *const image, bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage); setTexturingAndBlending(true); + bindArrayBufferAndAttributes(mVbo); setColorAlpha(image->mAlpha); unsigned int vp = 0; @@ -478,6 +483,7 @@ void ModernOpenGLGraphics::drawRescaledPattern(const Image *const image, bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage); setTexturingAndBlending(true); + bindArrayBufferAndAttributes(mVbo); setColorAlpha(image->mAlpha); unsigned int vp = 0; @@ -531,6 +537,26 @@ void ModernOpenGLGraphics::drawRescaledPattern(const Image *const image, inline void ModernOpenGLGraphics::drawVertexes(const OpenGLGraphicsVertexes &ogl) { + const std::vector<int> &vp = ogl.mVp; + const std::vector<GLuint> &vbos = ogl.mVbo; + std::vector<int>::const_iterator ivp; + std::vector<GLuint>::const_iterator ivbo; + const std::vector<int>::const_iterator ivp_end = vp.end(); + + logger->log("drawVertexes start"); + for (ivp = vp.begin(), ivbo = vbos.begin(); + ivp != ivp_end; + ++ ivp, ++ ivbo) + { + logger->log("bind vbo: %d", *ivbo); + logger->log("buf size in vetexes: %d", (*ivp) / 4); + bindArrayBufferAndAttributes(*ivbo); +#ifdef DEBUG_DRAW_CALLS + mDrawCalls ++; +#endif + glDrawArrays(GL_TRIANGLES, 0, *ivp / 4); + } + logger->log("drawVertexes end"); } void ModernOpenGLGraphics::calcPattern(ImageVertexes *const vert, @@ -546,7 +572,59 @@ void ModernOpenGLGraphics::calcPatternInline(ImageVertexes *const vert, const int x, const int y, const int w, const int h) const { + if (!image || !vert) + return; + + const SDL_Rect &imageRect = image->mBounds; + const int srcX = imageRect.x; + const int srcY = imageRect.y; + const int iw = imageRect.w; + const int ih = imageRect.h; + + if (iw == 0 || ih == 0) + return; + + const float tw = static_cast<float>(image->mTexWidth); + const float th = static_cast<float>(image->mTexHeight); + const ClipRect &clipArea = mClipStack.top(); + const int x2 = x + clipArea.xOffset; + const int y2 = y + clipArea.yOffset; + + const unsigned int vLimit = mMaxVertices * 4; + + OpenGLGraphicsVertexes &ogl = vert->ogl; + unsigned int vp = ogl.continueVp(); + const float texX1 = static_cast<float>(srcX) / tw; + const float texY1 = static_cast<float>(srcY) / th; + + GLfloat *floatArray = ogl.continueFloatTexArray(); + + for (int py = 0; py < h; py += ih) + { + const int height = (py + ih >= h) ? h - py : ih; + const int dstY = y2 + py; + const float texY2 = static_cast<float>(srcY + height) / th; + for (int px = 0; px < w; px += iw) + { + const int width = (px + iw >= w) ? w - px : iw; + const int dstX = x2 + px; + const float texX2 = static_cast<float>(srcX + width) / tw; + + vertFill2D(floatArray, + texX1, texY1, texX2, texY2, + dstX, dstY, width, height); + + vp += 24; + if (vp >= vLimit) + { + floatArray = ogl.switchFloatTexArray(); + ogl.switchVp(vp); + vp = 0; + } + } + } + ogl.switchVp(vp); } void ModernOpenGLGraphics::calcTileCollection(ImageCollection *const vertCol, @@ -571,6 +649,22 @@ void ModernOpenGLGraphics::calcTileCollection(ImageCollection *const vertCol, void ModernOpenGLGraphics::drawTileCollection(const ImageCollection *const vertCol) { + setTexturingAndBlending(true); +// bindArrayBuffer(vbo); + const ImageVertexesVector &draws = vertCol->draws; + const ImageCollectionCIter it_end = draws.end(); + for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it) + { + const ImageVertexes *const vert = *it; + const Image *const image = vert->image; + + setColorAlpha(image->mAlpha); +#ifdef DEBUG_BIND_TEXTURE + debugBindTexture(image); +#endif + bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage); + drawVertexes(vert->ogl); + } } void ModernOpenGLGraphics::calcPattern(ImageCollection* const vertCol, @@ -774,6 +868,7 @@ void ModernOpenGLGraphics::popClipArea() void ModernOpenGLGraphics::drawPoint(int x, int y) { setTexturingAndBlending(false); + bindArrayBufferAndAttributes(mVbo); const ClipRect &clipArea = mClipStack.top(); GLfloat vertices[] = { @@ -790,6 +885,7 @@ void ModernOpenGLGraphics::drawPoint(int x, int y) void ModernOpenGLGraphics::drawLine(int x1, int y1, int x2, int y2) { setTexturingAndBlending(false); + bindArrayBufferAndAttributes(mVbo); const ClipRect &clipArea = mClipStack.top(); GLfloat vertices[] = { @@ -807,6 +903,7 @@ void ModernOpenGLGraphics::drawLine(int x1, int y1, int x2, int y2) void ModernOpenGLGraphics::drawRectangle(const Rect& rect) { setTexturingAndBlending(false); + bindArrayBufferAndAttributes(mVbo); const ClipRect &clipArea = mClipStack.top(); const int x1 = rect.x + clipArea.xOffset; const int y1 = rect.y + clipArea.yOffset; @@ -831,6 +928,7 @@ void ModernOpenGLGraphics::drawRectangle(const Rect& rect) void ModernOpenGLGraphics::fillRectangle(const Rect& rect) { setTexturingAndBlending(false); + bindArrayBufferAndAttributes(mVbo); const ClipRect &clipArea = mClipStack.top(); const int x1 = rect.x + clipArea.xOffset; const int y1 = rect.y + clipArea.yOffset; @@ -900,6 +998,7 @@ bool ModernOpenGLGraphics::drawNet(const int x1, const int y1, const unsigned int vLimit = mMaxVertices * 4; setTexturingAndBlending(false); + bindArrayBufferAndAttributes(mVbo); const ClipRect &clipArea = mClipStack.top(); const GLfloat dx = clipArea.xOffset; const GLfloat dy = clipArea.yOffset; @@ -971,6 +1070,36 @@ void ModernOpenGLGraphics::bindArrayBuffer(const GLuint vbo) { mVboCached = vbo; mglBindBuffer(GL_ARRAY_BUFFER, vbo); + mAttributesCached = 0U; + } +} + +void ModernOpenGLGraphics::bindArrayBufferAndAttributes(const GLuint vbo) +{ + if (mVboCached != vbo) + { + mVboCached = vbo; + mglBindBuffer(GL_ARRAY_BUFFER, vbo); + + mAttributesCached = mVboCached; + mglBindVertexBuffer(0, mVboCached, 0, 4 * sizeof(GLfloat)); +// mglVertexAttribBinding(mPosAttrib, 0); + } + else if (mAttributesCached != mVboCached) + { + mAttributesCached = mVboCached; + mglBindVertexBuffer(0, mVboCached, 0, 4 * sizeof(GLfloat)); +// mglVertexAttribBinding(mPosAttrib, 0); + } +} + +void ModernOpenGLGraphics::bindAttributes() +{ + if (mAttributesCached != mVboCached) + { + mAttributesCached = mVboCached; + mglBindVertexBuffer(0, mVboCached, 0, 4 * sizeof(GLfloat)); +// mglVertexAttribBinding(mPosAttrib, 0); } } @@ -1013,6 +1142,51 @@ void ModernOpenGLGraphics::clearScreen() const glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } +void ModernOpenGLGraphics::finalize(ImageCollection *const col) +{ + FOR_EACH (ImageCollectionIter, it, col->draws) + finalize(*it); +} + +void ModernOpenGLGraphics::finalize(ImageVertexes *const vert) +{ + // in future need convert in each switchVp/continueVp + + OpenGLGraphicsVertexes &ogl = vert->ogl; + const std::vector<int> &vp = ogl.mVp; + std::vector<int>::const_iterator ivp; + const std::vector<int>::const_iterator ivp_end = vp.end(); + std::vector<GLfloat*> &floatTexPool = ogl.mFloatTexPool; + std::vector<GLfloat*>::const_iterator ft; + const std::vector<GLfloat*>::const_iterator ft_end = floatTexPool.end(); + std::vector<GLuint> &vbos = ogl.mVbo; + std::vector<GLuint>::const_iterator ivbo; + + const int sz = floatTexPool.size(); + vbos.resize(sz); + mglGenBuffers(sz, &vbos[0]); + + logger->log("finalize start"); + for (ft = floatTexPool.begin(), ivp = vp.begin(), ivbo = vbos.begin(); + ft != ft_end && ivp != ivp_end; + ++ ft, ++ ivp, ++ ivbo) + { + logger->log("bind vbo: %d", *ivbo); + logger->log("buf size in vetexes: %d", *ivp / 4); + bindArrayBuffer(*ivbo); + mglBufferData(GL_ARRAY_BUFFER, (*ivp) * sizeof(GLfloat), + *ft, GL_DYNAMIC_DRAW); + } + + for (std::vector<GLfloat*>::iterator it = floatTexPool.begin(); + it != floatTexPool.end(); ++ it) + { + delete [] (*it); + } + floatTexPool.clear(); + logger->log("finalize end"); +} + void ModernOpenGLGraphics::drawTriangleArray(const int size) { mglBufferData(GL_ARRAY_BUFFER, size * sizeof(GLfloat), @@ -1023,6 +1197,17 @@ void ModernOpenGLGraphics::drawTriangleArray(const int size) glDrawArrays(GL_TRIANGLES, 0, size / 4); } +void ModernOpenGLGraphics::drawTriangleArray(const GLfloat *const array, + const int size) +{ + mglBufferData(GL_ARRAY_BUFFER, size * sizeof(GLfloat), + array, GL_DYNAMIC_DRAW); +#ifdef DEBUG_DRAW_CALLS + mDrawCalls ++; +#endif + glDrawArrays(GL_TRIANGLES, 0, size / 4); +} + void ModernOpenGLGraphics::drawLineArrays(const int size) { mglBufferData(GL_ARRAY_BUFFER, size * sizeof(GLfloat), |