View Full Version : Picking a Specific Texture and Getting its "Name"

01-11-2012, 04:19 PM

I am trying to build a card game. It's called "14 Out." 52 playing cards are displayed on the screen. There are 12 columns, and in the last 8 columns there are 4 cards. The first 4 columns have 5 cards in them. The user must click on 2 cards whose "values" add to 14, as in 8 and 6,etc...

The user is only able to click on the last card in each column. Once 2 cards whose sum of values is 14 have been selected, they disappear from the screen. I have successfully texture mapped 52 bitmap files to 52 textures.

However, I am unable to get picking to work. I don't know how to pick the individual cards and I also don't know how to assign a value to each bitmap file.

I have run picking tutorials, but I need a way to figure out which bitmap image is mapped to the texture the user has clicked on. I can then find the "value" of the card. However, I am completely lost on how to do this. I have looked at virtually every picking tutorial on the web, and I don't know how to do it. All of the tutorials return the mouse coordinates of where the user has clicked. I want to select the individual card and determine its value. Also, I can't even get picking itself to work. Which would be the easiest method to pick and how do I figure out the value for each texture? What makes this harder is that the cards are randomized for every run. I do this by randomly selecting a bitmap image out of a char array of 52 bitmap images. This bitmap is then mapped to a quad. This happens in a for loop.

I was thinking of having a switch statement. Once I've figured out which card has ben selected, I can, from its name, determine its value. But I don't know how to do that. I'm sure there's a way, but I just don't know of one. I am also using SDL with OpenGl, if that helps.

This is my list of cards:

redacted at uploader's request

This is my texture loading function:

redacted at uploader's request

Finally, this is my quad drawing function:

redacted at uploader's request

carsten neumann
01-11-2012, 04:59 PM
I have successfully texture mapped 52 bitmap files to 52 textures.

Just a nitpick regarding terminology: One loads the contents of bitmap files into textures and then applies those to primitives (triangles, etc.), or short: texture maps a primitive.

For something with such a regular output you probably don't need picking in the usual sense. Just from knowing the mouse coordinates and the number of rows and columns of cards on the screen (as well as their size) you can determine which "place for a card" the user has clicked on.
You then need a datastructure that keeps track which card you placed where on the screen:

redacted at OP's request

When you want to place a card on the screen you assign the value and color to the corresponding slot. Your render function should then only have to look at the visibleCards array to figure out which texture to use for the card at the position it's rendering.

Similarly for figuring out the card the user clicked on: from the mouse coordinates you calculate the which row and column of the cards the user clicked. Then look into visibleCards[col][row] to find the card at that position.

In general, I think you need to restructure your code a bit. For example: why does the function called LoadTextures render quads? Just from the name that is a very surprising side effect and hints that something is wrong here.
Also consider this: you only load the textures once when the program starts. You will draw quads with the textures applied many times during the runtime of your program. So you'll have to store the texture id's for the different cards somewhere (probably in some array) so you can access them outside of LoadTextures().

01-11-2012, 05:29 PM
Thanks for replying.

I somewhat understand what you mean. I apologize for this as I have only been programming in C++ for a few months and just recently began OpenGl, about 2 weeks ago.

Would I have to change the code for my list of cards? In the code you posted, there is struct CardSlot. I don't understand how I can use that with my cards list. I also don't understand what you mean by my render function figuring out which texture to use, since I randomly pick a card from my list of cards. Since I randomly pick a card from the card list (my pseudo shuffling method), will I have to change my randomized picking to another method? I am not sure if my way to shuffle is correct. Also, will I have to declare CardSlot for every single card 52 times, and then declare the color and values another 52 times each? I am probably getting confused with my relatively low experience, and I apologize for that again.

Currently, I am using a for loop and translating every quad a few units to the left. Would your method work better if I used a tile map?

Thanks for the advice. I'll be sure to edit my code.

carsten neumann
01-12-2012, 08:28 AM
Ok, it seems to me you need to keep track of two things in your program: the deck of cards you draw from when you need to fill a "slot" on screen and the cards that are currently visible. Renaming struct CardSlot to struct Card, you can model this with these variables:

redacted at OP's request

You can introduce an additional CardValue (e.g. CV_None) to mark empty visible slots.
- Initialize deck such that it contains one card of each value and color and deckSize to 52.
- Write a function that can swap two cards in the deck (void swapDeck(unsigned int i, unsigned int j)).
- Write a function that loops a couple hundred times, computing two random numbers in [0, deckSize-1] and calling swapDeck() -> you get a shuffled deck.
- Taking cards from the back of the deck, assign them to visible.
- Your render function can now look something like this:

redacted at OP's request

The function drawCard() simply renders a quad at the given position with the correct texture for the kind of card (or does nothing if the card value is CV_None). To figure out the correct texture you need a way to map from a CardValue, CardColor pair to a GLuint (the texture id):

redacted at OP's request

01-12-2012, 05:27 PM
I've coded almost everything you told me to code, but I am getting an error message, stating that "my program.exe has stopped working."

I think I know why this is happening. I haven't coded how to assign each bitmap file to each card, and I am not using the posx and posy variables, because I don't know what to do with them. Do I use glTranslate and use those x and y values? Also, do I have to manually assign a value to them in the render function you posted or do I use the mouse coordinates where the user clicked on? I am very close to getting this finished, but its just those two final problems that I have.

Thanks for helping me, I appreciate it very much!

01-13-2012, 12:35 AM
What happens when you run through a debugger ?
Be sure to compile with all the warnings possible too.

01-13-2012, 06:22 AM
Ok, I was previously using chars, instead of enums as Carsten had told me. I did this because I could not assign values to each char. I have now changed back to enums. However, when I try and compile, I get the following errors in lines 6 and 7:
error: expected primary-expression before '[' token|
error: expected primary-expression before '[' token|

In the function to create my deck:

redacted at OP's request

Also, I don't get any warnings. I think it was not compiling before because there is a problem with my texIDs.

carsten neumann
01-13-2012, 08:26 AM
redacted at OP's request

this is not valid C, because CardValue is a type name, not the name of a variable of array type, and it is not valid to use the "[ ]" operator on a type.

redacted at OP's request

If you are programming in C (instead of C++) replace the "static_cast<Type>" with "(Type)".

- the posX, posY variables can either be used with glTranslate() or directly to calculate the vertex positions for your quads. Keep in mind that calls to glTranslate() multiply a translation matrix on top of the matrix stack, so repeated calls accumulate.

01-13-2012, 09:49 AM
Thnaks, to both of you. I changed those lines of code. My program would still crash, but using the debuger was a good idea,a s it told me where the problem was ocurring. I had never used one before, but it was fairly easy to understand, so thanks ZbuffeR. However, when I run my program, the windows loads, but no cards are actually drawn. I think I am not binding the textures right.

I am declaring the texId, as Carsten told me:

redacted at OP's request

I am binding the textures like this:

redacted at OP's request

Also, I am loading the bmp files like this:

redacted at OP's request

carsten neumann
01-13-2012, 10:52 AM
The idea is that cardTexIds[CC_Queen][CV_Spades] gives you the texture id of the texture for the queen of spades card, so that you can pass that directly to glBindTexture(GL_TEXTURE_2D, cardTexIds[??][??]).
To make that work you will have to adjust the code where you load the image files and create the texture objects accordingly.

01-14-2012, 10:38 AM
I am trying to get it to work, but my program just displays a see-through SDL window. I am using SDL to load my .bmp files. When I move my mouse to inside the window, the windows closes and in cmd, it says:
Fatal signal: Segmentation Fault (SDL Parachute Deployed)

I have tried running it through the debugger, but it says some weird things,relating to SDL. It doesn't specify which lines, only pointing to the some DLLs in the Windows folder.
I am sure that something is wrong in my textureLoad function:

redacted at uploader's request

My draw function simply renders a quad.

This is what the debugger says:
#0 766108F5 strncpy() (C:\Windows\syswow64\msvcrt.dll:??)
#1 00000000 0x0028fe0c in ??() (??:??)
#2 00000000 0x1003c108 in ??() (??:??)
#3 00000000 0x0028fe10 in ??() (??:??)
#4 100191B9 SDL_SetError() (C:\Windows\SysWOW64\SDL.dll:??)
#5 00000000 0x00000000 in ??() (??:??)

01-25-2012, 07:27 PM
afan101, you can edit your own posts this is a permission every poster has, but as you say perhaps there is a time limit.

The code you uploaded is trivial and not worth "protecting" please do not upload code you do not want to share again as others copy it in replies and it is a pain to redact.

P.S. it is also extremely bad form to redact your code after others have posted code to assist you. Don't do it again, I won't edit posts for you again. Trading code seeking a solution then wanting it deleted after the discussion is over is also very bad etiquette.

If you intend to post code again seeking solutions with the intent of later deleting the code DO NOT DO IT. Do not post, that kind of request is NOT WELCOME.

Again you have a strange idea on the merits of the code you are posting, this is trivial code, with bugs drawing playing cards with quads. It's not going to rock anyone's world and has been done a hundred times.