Hello Guest

Mirror image drawn when using VBO's

  • 12 Replies
  • 11583 Views
*

Offline Cornix

  • *****
  • 488
Mirror image drawn when using VBO's
« on: August 04, 2013, 17:15:12 »
Hi.

I am using VBO's for drawing right now, the classical:
Code: [Select]
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ibo);

GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);

GL11.glVertexPointer(3, GL11.GL_FLOAT, stride, v_pointer);
GL11.glTexCoordPointer(2, GL11.GL_FLOAT, stride, t_pointer);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 3);
With a VBO with positions and texture coordinates and another buffer with indices.

Now my question is, is there a simple and efficient way to flip the image horizontally / vertically without having to create another VBO?
I know I could just flip the texture coordinates inside the vbo but I would like not to since the same VBO might be used by several other sprites in my application.
So if there is some magic function call I dont remember or never saw please enlighten me.

Thank you very much.

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Mirror image drawn when using VBO's
« Reply #1 on: August 04, 2013, 20:57:08 »
No magic functions I'm afraid (at least that I know of). The solution is to manipulate the texture coords.

If you're using shaders, it is a very simple solution. (1 - s, 1 - t) instead of (s, t).

If you aren't using shaders, then you'll have to employ the texture matrix. I'm sure you'll manage to work out the correct matrix to use since you've git this far. (BTW manipulate the texture matrix exactly the same as modelview or projection, just call glMatrixMode(GL_TEXTURE) first.

*

Offline Cornix

  • *****
  • 488
Re: Mirror image drawn when using VBO's
« Reply #2 on: August 04, 2013, 21:20:48 »
Thank you alot. Texture-Matrix, that might work.
Also read you could call
Code: [Select]
glScalef(-1, 1, 1)for horizontal mirroring, but you would have to cull the other face and translate too since it will move out of place.
I dont exactly know which is the better solution but I guess I will go with the texture matrix for now since it will be less work on the CPU.

*

Offline Cornix

  • *****
  • 488
Re: Mirror image drawn when using VBO's
« Reply #3 on: August 06, 2013, 08:33:43 »
Manipulating the texture matrix doesnt seem to work. I am sorry, but is there something I need to enable first or have to do before changes to the texture matrix take place?
Whatever I do, translate, rotate, scale, etc, nothing shows any effect on rendering.

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Mirror image drawn when using VBO's
« Reply #4 on: August 06, 2013, 10:55:47 »
No, there's nothing else you need to enable. I can't envisage any situation where it has no effect whatsoever. Following a quick google search, my advise (this is weak stuff) is make sure you are calling glMatrixMode(GL_TEXTURE), and not with GL_TEXTURE_2D or GL_TEXTURE_MATRIX or anything like that. But you would have seen the GL_INVALID_ENUM error anyway, right?

Last bit of advise, just before you render try getting the texture matrix and taking a look see what it contains. glGetFloatv(GL_TEXTURE_MATRIX); or something like that

*

Offline Cornix

  • *****
  • 488
Re: Mirror image drawn when using VBO's
« Reply #5 on: August 06, 2013, 11:18:42 »
Code looks like this right now:
Code: [Select]
GL11.glMatrixMode(GL11.GL_TEXTURE);
GL11.glPushMatrix();
GL11.glRotatef(32, 1, 1, 1);
GL11.glTranslatef(50, 0, 0);
GL11.glScalef(0.5f, 1, 1);

GL11.glMatrixMode(GL11.GL_MODELVIEW);

FloatBuffer buf = ByteBuffer.allocateDirect(16 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
GL11.glGetFloat(GL11.GL_TEXTURE, buf);
float[] texMat = new float[16];
buf.get(texMat);
System.out.println(Arrays.toString(texMat));

// Render logic

GL11.glMatrixMode(GL11.GL_TEXTURE);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);

The output says the texture matrix is 0 in all columns and rows.

In the specification it says to use GL_TEXTURE for the matrix mode:
http://www.opengl.org/sdk/docs/man2/xhtml/glMatrixMode.xml

When I use GL_TEXTURE_MATRIX in the glGetFloat method I get the following result:
Quote
[0.44934937, 0.17829983, -0.1276492, 0.0, -0.2552984, 0.89869875, 0.35659966, 0.0, 0.35659966, -0.2552984, 0.89869875, 0.0, 44.934937, 17.829983, -12.76492, 1.0]
Looks promising, but still there is no effect on the image being drawn. I dont use any custom shaders by the way.
« Last Edit: August 06, 2013, 11:24:59 by Cornix »

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Mirror image drawn when using VBO's
« Reply #6 on: August 06, 2013, 11:28:18 »
That should be glGetFloat(GL_TEXTURE_MATRIX, buf); (Someone isn't checking their OpenGL errors).

Also, what's up with the pushing and popping of matrices? The setup as you have it there prints the contents of the matrix after those transforms but then discards them just before you are about to render.

*

Offline Cornix

  • *****
  • 488
Re: Mirror image drawn when using VBO's
« Reply #7 on: August 06, 2013, 11:31:53 »
I pop the texture matrix after the render logic. The rendering comes directly after the print and before the popMatrix call. Its very complicated and big thats why I left it out intentionally and inserted a comment instead.

*

Offline Cornix

  • *****
  • 488
Re: Mirror image drawn when using VBO's
« Reply #8 on: August 06, 2013, 11:38:51 »
I noticed something fishy. I deleted all manipulations to the texture matrix in my code and just left the printing there to get the contents of the texture matrix.
In the first frame (before anything was ever rendered) the texture matrix was this:
[1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
The identity matrix.

But after the first rendering of an image it was:
[0.0078125, 0.0, 0.0, 0.0, 0.0, 0.015625, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
at every other frame.
I dont know how this comes since I never do any changes to the texture matrix anywhere else in my program.

Edit: Nevermind, I do make a change to the texture matrix somewhere, now I think I am just stupid...
Ok manipulating the texture matrix works now.
But I found out it doesnt help me with my problem. Yes, the texture is mirrored, but not the image. The image only uses a small portion of the texture (its a spritesheet) so the result is not what I was looking for.
It still is good to have eliminated this small bug though.
« Last Edit: August 06, 2013, 11:43:47 by Cornix »

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Mirror image drawn when using VBO's
« Reply #9 on: August 06, 2013, 11:45:49 »
Oh, sorry, completely misinterpreted - no wonder you can't fix this when I'm the one helping you.

Now that is fishy. During by very brief Google search, I found a topic on StackOverflow with something similar. http://stackoverflow.com/questions/11996529/what-could-globally-affect-texture-coordinate-values-in-opengl. (Just under the first picture he adds an edit with this problem). Unfortunately his solution  is to reset the texture matrix to the identity after rendering. Which I find somewhat unsatisfying, but if it works and in lieu of a better solution...

*

Offline Cornix

  • *****
  • 488
Re: Mirror image drawn when using VBO's
« Reply #10 on: August 06, 2013, 12:01:53 »
I edited my post and already figured out that I am stupid.
At another point in my program, something I wrote quite a while ago, I was already manipulating the texture matrix without remembering.

But as I said, this is unfortunately not a solution to my original problem. I now go with calling glScalef(-1, 1, 1) on the ModelViewMatrix to mirror my image.
Then I have to call glTranslatef(-image_width, 0, 0) to put the image back in place.
But I also have to reverse the culling to render this image...

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Mirror image drawn when using VBO's
« Reply #11 on: August 06, 2013, 12:13:17 »
If you're going to go with that, change the front face (with glFrontFace(GL_CW);) rather than reversing the culling. Makes more sense to keep the front face as the front face rather than just pretend the back is.

*

Offline Cornix

  • *****
  • 488
Re: Mirror image drawn when using VBO's
« Reply #12 on: August 06, 2013, 12:16:25 »
Thats a great idea. I didnt even know that was possible.
Thank you.

Edit: Just tested it, works GREAT.
« Last Edit: August 06, 2013, 12:19:21 by Cornix »