2D and Ortho Problems

Started by mstevano, June 23, 2005, 07:32:03

Previous topic - Next topic

mstevano

Hi,

I desperately need help with 2D issues in OpenGL. I am currently developing a kind of trading card game and i have problems handling the graphical part. At the beginning i want to draw the hand with all it's cards and a playing field were i can deploy cards. I looked into different possibilities like using Ortho , or pespective mode or even a mix of both, but i don't know how to handle them correctly. Here are my problems:

1) The hand should be positioned in the lower left corner of the window and the cards should never change in size. I thought about using ortho mode with this, but i can't use scalef to scale the cards to the size i need (because of Ortho), and the texture size is either to big or to small. Do i have to change the vertex2f values to reduce the images in size? And how does it effect the possibility of selecting the card with the mouse?

The other thing is, later i want to be able to display a bigger version of the card, when the player chooses a display details option. So how can i do this in ortho mode?

2) The playing field on the other hand should be able  can become crowded with cards, so the player should be able to zoom in and out to see the whole playing field or to have a more close up look at a specific point on the field. What can i do, and how do i do it, to achieve this? I think ortho mode is the wrong choice for this. How would i draw the cards? With a z-value like -20 or more, and when i want to zoom, move the camera closer to that value?

3) Selecting cards on the hand and playing field with the mouse to play, select and discard the cards. How can i calculate their position to be able to pick them.  I even have problems drawing the cursor, it is to big, that's why i have to scale it. It is fine in perspective mode, but Ortho is a problem. What is the best solution to doing all this?

Do i really need the ortho mode, or is there a better way to everything in perspective mode? How would i go about doing this?
Has anybody had some experience with card games or a problem like this.

I remember princec saying in a topic that was posted long ago, that it is easy handling 2D stuff in OpenGL. Currently, i have the feeling it is the opposite, but that's because i have some undestanding problems. I hope you guys can help me out with this.

thanks
Mike

Fool Running

1) I would have thought that scalef would have worked. What is the problem with it?

2) I would sugesst a 3D table with the cards on them and move the camera closer to the table to zoom.

3) In the 2D world you can calculate based on the current mouse coordinates and the rectangle bounds of the cards.  In the 3D world there is a render mode called "select" (I'm not entirely sure how to use it, but it will let you tell if the user has clicked on a 3D card on the table). You should be able to find information about it on the internet or in a book.

I've never made a card game, but my game uses 3D with a 2D overlay which sounds like what you need and it works fine. :D
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

napier

This post shows how to use glFrustum() to create a perspective view that is "2D" at Z=0.  It's like ortho, but you can zoom in and out:

http://lwjgl.org/forum/viewtopic.php?t=872&highlight=frustum

As for scaling the cards, if you're drawing the cards onto quads, you can scale the quad size easily enough to display cards larger.   Here's a snip from some code I use to do this:

float zoom = .5f;                         // how much to scale image
drawImageQuad(overlayTextureHandle,       // image will be texture on a square
              (int)100,                   // draw image at 100,100 screen pos
              (int)100,
              (overlayImage.w*zoom),      // scale width and height
              (overlayImage.h*zoom) );


public static void drawImageQuad(int textureHandle, int x, int y, float w, float h) {
        // activate the specified texture
        GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureHandle);
        // prepare to render in 2D
        setOrthoOn();
        // draw the image textured onto a quad
        GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(0f, 0f);
        GL11.glVertex3f( (float)x, (float)y, (float)0);
        GL11.glTexCoord2f(1f, 0f);
        GL11.glVertex3f( (float)x+w, (float)y, (float)0);
        GL11.glTexCoord2f(1f, 1f);
        GL11.glVertex3f( (float)x+w, (float)y+h, (float)0);
        GL11.glTexCoord2f(0f, 1f);
        GL11.glVertex3f( (float)x, (float)y+h, (float)0);
        GL11.glEnd();
        // restore the previous perspective and model views
        setOrthoOff();
}


public static void setOrthoOn()
{
        // prepare to render in 2D
        GL11.glDisable(GL11.GL_DEPTH_TEST);             // so 2D stuff stays on top of 3D scene
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glPushMatrix();                            // preserve perspective view
        GL11.glLoadIdentity();                          // clear the perspective matrix
        GL11.glOrtho(viewportX,viewportX+viewportW,viewportY,viewportY+viewportH,-1,1);  // turn on 2D
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glPushMatrix();				// Preserve the Modelview Matrix
        GL11.glLoadIdentity();				// clear the Modelview Matrix
}

public static void setOrthoOff()
{
        // restore the original positions and views
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glPopMatrix();
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glPopMatrix();
        GL11.glEnable(GL11.GL_DEPTH_TEST);		// turn Depth Testing back on
}


Full code for an Ortho demo is here:  http://potatoland.org/code/gl

You mention that "texture size is either to big or to small".  Not sure what you mean exactly, but if you're drawing the cards as textured quads, and the image distorts when you zoom in, then try using mipmaps.

As for detecting a mouse click on a card, in Ortho mode all you need to do is check the mouse xy and see if it's inside your card rectangle.  It's all pixel coordinates so the coordinates are easy to manage.  In 3D you can use glUnproject() to figure out how a mouse xy translates into your model space.
penGL/Java/LWJGL demos and code: http://potatoland.org/code/gl

mstevano

Thanks Fool Running for your reply. The scaling problem was actually an error on my account. I can scale now, so that's not a problem anymore. Concerning  the 3D Table, that may sound like good idea, but i want a view from above and just zoom in and out of it.

Thank you Napier for the code, i'll try that out. I am still new to using 2D with OpenGL. I am used to either using java2D or only 3D with OpenGL without any Overlays and stuff like that. Thinking about creating the GUI for my game already makes me crazy.

I still have a problem understanding how to texture map the cards correctly and how to specify the right vertices for the quad i map the card texture on so that i can calculate the proper rectangle for mouse selection. The problem is, not like Java2D, that i have to use Textures with the power of two. So a part of the card texture will be just white/transparent. How do i calculate the
rectangle, so that the method that tests if the card is selected, doesn't return true, if the coordinates intersect the transparent part of the quad?

The texture coordinates i use when mapping the card texture, is it better to map the whole texture? Or do i need to calculate the texture coordinates for only the card part without the transparent part?
How would the vertices of the card would look like. Let's say the card is 365x512 big. Would i use those dimensions to define the quad vertices? And the texture coordinates would be 0,0  .71,0  0.71,1  0,1   .
But how can i calculate the right card rectangle?

Is there maybe a better or easier way to do all this? I just need to map a card texture to a quad and be able to only select the card and not it's transparent part aswell.  

Oh, another small thing. I am currently trying to use a cursor texture with the mouse and so on. I can move the texture with the mouse, but i need to map the top-left corner of the quad to the x/y mouse coordinates. Right now the mouse coordinates are at the bottom-left corner. I can't quite get it to the right position when scaling the cursor and so on. Does anybody have a code snippet for using a texture as a cursor and how to best use the mouse with it?

Any help would be appreciated

thanks again,
Mike

Fool Running

QuoteThe problem is, not like Java2D, that i have to use Textures with the power of two. So a part of the card texture will be just white/transparent
I would sugesst stretching your texture to the nearest power-of-two to make the texture coords easier and all of your other calculations easier (i.e. if your texture is 365x512 then stretch it to 512x512 or 256x512). The cards should still look right if the quad your putting the texture on is the right aspect ratio. :wink:
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D