Note that there are some explanatory texts on larger screens.

plurals
  1. POBuffers getting corrupted?
    primarykey
    data
    text
    <p>I'm trying to write a UI in OpenGL and have run into a problem when I resize a control.</p> <p><img src="https://i.stack.imgur.com/EE57g.png" alt="Texture errors"></p> <p>As I shrink the panel, the text texture seems to shrink or get corrupted and eventually the buttons do the same. The buttons are not tied to the size of the window, so the problem isn't with calculating the sizes. I printed the size of the text texture and the button sizes and they stayed consistent during the test.</p> <p>So every time I resize the window, here is what is happening:</p> <pre><code>onResize Delete TexturedRectangle object | Delete 9 sprites (including vertex data) used for the TexturedRectangle | Delete the RenderTexture New TexturedRectangle Object | Create 9 sprites (new vertex data) for the textured rectangle | Render the rectangle using the 9 sprites to a new RenderTexture the size of the window </code></pre> <p>I went through the code and made sure I am deleting the old data off the gpu before creating new buffers. Are my buffers getting corrupted or is the way I'm rendering to the RenderTextures incorrect? I checked glGetError() and get no errors during run time. Could the problem be with the OpenGL stack? I can't tell where the problem is because the buttons aren't changed at all when I resize the window.</p> <pre><code>Sprite::Sprite() : ISprite(), mVbo(0) { mDiffuse = ResourceCache::getSingleton().getTexture("Texture_NOTFOUND"); createVbo(); } Sprite::Sprite(ITexture *diffuse, FloatRect textureBounds) : ISprite(), mVbo(0) { mDiffuse = diffuse; if(textureBounds.x == 0 &amp;&amp; textureBounds.y == 0) { mTextureBounds = diffuse-&gt;getBounds(); } else { mTextureBounds = textureBounds; } createVbo(); } Sprite::~Sprite() { glDeleteBuffers(1, &amp;mVbo); } void Sprite::draw(IRenderTarget *target, RenderState *state) const { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, mVbo); switch(state-&gt;getRenderMode()) { default: case RenderState::DIFFUSE: mDiffuse-&gt;bindTexture(); break; case RenderState::NORMAL_MAP: mNormalMap-&gt;bindTexture(); break; case RenderState::HEIGHT_MAP: mHeightMap-&gt;bindTexture(); break; }; glPushMatrix(); glTranslatef(mPosition.x, mPosition.y, mPosition.z); glColor4f(mColor.r, mColor.g, mColor.b, mColor.a); glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, x)); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, tx)); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glPopMatrix(); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); } void Sprite::createVbo() { if(mVbo != 0) { glDeleteBuffers(1, &amp;mVbo); } // Generate the VBO glGenBuffers(1, &amp;mVbo); Vector2f size = getSize(); float texW = mDiffuse-&gt;getWidth(); float texH = mDiffuse-&gt;getHeight(); float srcW = size.x / texW; float srcH = size.y / texH; // Calculate the vertices Vertex verts[] = {{0.f, 0.f, 0.f, mTextureBounds.x / texW, mTextureBounds.y / texH}, {size.x, 0.f, 0.f, (mTextureBounds.x / texW) + srcW, mTextureBounds.y / texH}, {0.f, size.y, 0.f, mTextureBounds.x / texW, (mTextureBounds.y / texH ) + srcH}, {size.x, size.y, 0.f, (mTextureBounds.x / texW) + srcW, (mTextureBounds.y / texH) + srcH}}; int vertSize = sizeof(verts); // Bind the VBO glBindBuffer(GL_ARRAY_BUFFER, mVbo); // Submit the vertex data to the GPU glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * 4, &amp;verts[0].x, GL_STATIC_DRAW_ARB); // Unbind the VBO glBindBuffer(GL_ARRAY_BUFFER, 0); } </code></pre> <p>Repeating Sprite</p> <pre><code>RepeatingSprite::RepeatingSprite(Texture *diffuseTexture, FloatRect spriteBounds, int xRepeat, int yRepeat) : ISprite(), mXRepeat(xRepeat), mYRepeat(yRepeat) { mVbo = 0; mDiffuse = diffuseTexture; mTextureBounds = spriteBounds; createVbo(); } RepeatingSprite::~RepeatingSprite() { glDeleteBuffers(1, &amp;mVbo); } void RepeatingSprite::draw(IRenderTarget *target, RenderState *state) const { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, mVbo); switch(state-&gt;getRenderMode()) { default: case RenderState::DIFFUSE: mDiffuse-&gt;bindTexture(); break; case RenderState::NORMAL_MAP: mNormalMap-&gt;bindTexture(); break; case RenderState::HEIGHT_MAP: mHeightMap-&gt;bindTexture(); break; }; glPushMatrix(); glTranslatef(mPosition.x, mPosition.y, mPosition.z); glColor4f(mColor.r, mColor.g, mColor.b, mColor.a); glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, x)); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, tx)); glDrawArrays(GL_QUADS, 0, (mXRepeat * mYRepeat) * 4); glPopMatrix(); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); } void RepeatingSprite::createVbo() { int totalRepeats = mXRepeat * mYRepeat; float textureWidth = mDiffuse-&gt;getWidth(); float textureHeight = mDiffuse-&gt;getHeight(); Vertex *vertices = new Vertex[totalRepeats*4]; int counter = 0; // For each sprite count, create a quad for(float y = 0; y &lt; mYRepeat; y++) { for(float x = 0; x &lt; mXRepeat; x++) { Vertex v1 = {x * mTextureBounds.w, y * mTextureBounds.h, 0.f, mTextureBounds.x / textureWidth, mTextureBounds.y / textureHeight}; Vertex v2 = {x * mTextureBounds.w + mTextureBounds.w, y * mTextureBounds.h, 0.f, (mTextureBounds.x / textureWidth) + (mTextureBounds.w / textureWidth), mTextureBounds.y / textureHeight}; Vertex v3 = {x * mTextureBounds.w, y * mTextureBounds.h + mTextureBounds.h, 0.f, mTextureBounds.x / textureWidth, (mTextureBounds.y / textureHeight) + (mTextureBounds.h / textureHeight)}; Vertex v4 = {x * mTextureBounds.w + mTextureBounds.w, y * mTextureBounds.h + mTextureBounds.h, 0.f, (mTextureBounds.x / textureWidth) + (mTextureBounds.w / textureWidth), (mTextureBounds.y / textureHeight) + (mTextureBounds.h / textureHeight)}; vertices[counter] = v1; counter++; vertices[counter] = v2; counter++; vertices[counter] = v4; counter++; vertices[counter] = v3; counter++; } } glGenBuffers(1, &amp;mVbo); glBindBuffer(GL_ARRAY_BUFFER, mVbo); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * (totalRepeats*4), &amp;vertices[0].x, GL_STATIC_DRAW_ARB); glBindBuffer(GL_ARRAY_BUFFER, 0); delete[] vertices; } </code></pre> <p>Render Texture</p> <pre><code>RenderTexture::RenderTexture(float width, float height) { mWidth = width; mHeight = height; // Create the color buffer glGenTextures(1, &amp;mId); glBindTexture(GL_TEXTURE_2D, mId); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)mWidth, (int)mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, 0); // Create the framebuffer glGenFramebuffers(1, &amp;mFbo); glBindFramebuffer(GL_FRAMEBUFFER, mFbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mId, 0); GLenum err = glCheckFramebufferStatus(GL_FRAMEBUFFER); assert(err == GL_FRAMEBUFFER_COMPLETE); // Make sure texture is valid glBindFramebuffer(GL_FRAMEBUFFER, 0); } RenderTexture::~RenderTexture() { glDeleteBuffers(1, &amp;mFbo); glDeleteTextures(1, &amp;mId); mFbo = 0; } void RenderTexture::preDraw() { // store the glViewport and glEnable states glPushAttrib(GL_VIEWPORT_BIT); // Bind the frame buffer //glBindTexture(GL_TEXTURE_2D, 0); glBindFramebuffer(GL_FRAMEBUFFER, mFbo); // Save the current matrix glPushMatrix(); glLoadIdentity(); // Setup the projection matrix for the render target glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glViewport(0, 0, (int)mWidth, (int)mHeight); glOrtho(0, mWidth, 0.f, mHeight, 0.f, 100.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glDrawBuffer(GL_COLOR_ATTACHMENT0); } void RenderTexture::postDraw() { // Pop the render target's projection matrix off the stack glPopMatrix(); // Restore previouse projection matrix glPopMatrix(); glBindFramebuffer(GL_FRAMEBUFFER, 0); // Restore the previous viewport settings glPopAttrib(); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload