summaryrefslogtreecommitdiff
path: root/src/render/modernopenglgraphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/modernopenglgraphics.cpp')
-rw-r--r--src/render/modernopenglgraphics.cpp185
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),