   Tic-Tac-Toe OpenGL
  I started to learn OpenGL about 3 weeks ago just same tuts. from NeHe and i decided i would be a good practise to code a tic tac toe game and here comes the problem first i wanted to write an function for drawing XO and then if the user selects for example the second box in the first row it just moves the x position that plan didnt work because it just moves the sprite and it doesnt get drawn and i couldnt figure out how to do that...My second plan was to make user press from 1-9 and if he hits 3 it draws it in the right position but now im having problem with making drawing x then 0 then x etc....I tried making a variable turn 1 for x 2 for 0 but i cant make it work...Anyway heres the code:#include &lt;stdio.h&gt;#include &lt;windows.h&gt;// Header File For Windows#include &lt;gl\gl.h&gt;// Header File For The OpenGL32 Library#include &lt;gl\glu.h&gt;// Header File For The GLu32 Library#include &lt;gl\glaux.h&gt;// Header File For The Glaux LibraryHDChDC=NULL;// Private GDI Device ContextHGLRChRC=NULL;// Permanent Rendering ContextHWNDhWnd=NULL;// Holds Our Window HandleHINSTANCEhInstance;// Holds The Instance Of The Applicationbool    rp=false;bool    lp=false;intturn   = 1;intpolje = 1;int x = 100;int y = 50;boolkeys[256];// Array Used For The Keyboard Routineboolactive=TRUE;// Window Active Flag Set To TRUE By Defaultboolfullscreen=TRUE;// Fullscreen Flag Set To Fullscreen Mode By Defaultint loop1;bool pp,dp,tp,cp,ptp,sp,sdp,op,dtp;GLuinttexture[1];GLuintbase;AUX_RGBImageRec *LoadBMP(char *Filename)// Loads A Bitmap Image{FILE *File=NULL;if (!Filename)// Make Sure A Filename Was Given{return NULL;// If Not Return NULL}File=fopen(Filename,"r");if (File)// Does The File Exist?{fclose(File);// Close The Handlereturn auxDIBImageLoad(Filename);// Load The Bitmap And Return A Pointer}return NULL;// If Load Failed Return NULL}int LoadGLTextures()// Load Bitmaps And Convert To Textures{   int Status=false;   AUX_RGBImageRec *TextureImage[1];   memset(TextureImage,0,sizeof(void *)*1);   if (TextureImage[0]=LoadBMP("Data/Font.bmp")){Status=TRUE;glGenTextures(1, &texture[0]);// Create The Texture// Typical Texture Generation Using Data From The BitmapglBindTexture(GL_TEXTURE_2D, texture[0]);glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]-&gt;sizeX, TextureImage[0]-&gt;sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]-&gt;data);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);// Linear FilteringglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);// Linear Filtering}if (TextureImage[0])// If Texture Exists{if (TextureImage[0]-&gt;data)// If Texture Image Exists{free(TextureImage[0]-&gt;data);// Free The Texture Image Memory}free(TextureImage[0]);// Free The Image Structure}return Status;// Return The Status}LRESULTCALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);// Declaration For WndProcGLvoid ReSizeGLScene(GLsizei width, GLsizei height)// Resize And Initialize The GL Window{if (height==0)// Prevent A Divide By Zero By{height=1;// Making Height Equal One}glViewport(0,0,width,height);// Reset The Current ViewportglMatrixMode(GL_PROJECTION);// Select The Projection MatrixglLoadIdentity();// Reset The Projection MatrixglOrtho(0.0f,width,height,0.0f,-1.0f,1.0f);// Create Ortho 640x480 View (0,0 At Top Left)glMatrixMode(GL_MODELVIEW);// Select The Modelview MatrixglLoadIdentity();// Reset The Modelview Matrix}GLvoid BuildFont(GLvoid)// Build Our Font Display List{base=glGenLists(256);// Creating 256 Display ListsglBindTexture(GL_TEXTURE_2D, texture[0]);// Select Our Font Texturefor (loop1=0; loop1&lt;256; loop1++)// Loop Through All 256 Lists{float cx=float(loop1%16)/16.0f;// X Position Of Current Characterfloat cy=float(loop1/16)/16.0f;// Y Position Of Current CharacterglNewList(base+loop1,GL_COMPILE);// Start Building A ListglBegin(GL_QUADS);// Use A Quad For Each CharacterglTexCoord2f(cx,1.0f-cy-0.0625f);// Texture Coord (Bottom Left)glVertex2d(0,16);// Vertex Coord (Bottom Left)glTexCoord2f(cx+0.0625f,1.0f-cy-0.0625f);// Texture Coord (Bottom Right)glVertex2i(16,16);// Vertex Coord (Bottom Right)glTexCoord2f(cx+0.0625f,1.0f-cy);// Texture Coord (Top Right)glVertex2i(16,0);// Vertex Coord (Top Right)glTexCoord2f(cx,1.0f-cy);// Texture Coord (Top Left)glVertex2i(0,0);// Vertex Coord (Top Left)glEnd();// Done Building Our Quad (Character)glTranslated(15,0,0);// Move To The Right Of The CharacterglEndList();// Done Building The Display List}// Loop Until All 256 Are Built}GLvoid glPrint(GLint x, GLint y, int set, const char *fmt, ...)// Where The Printing Happens{chartext[256];// Holds Our Stringva_listap;// Pointer To List Of Argumentsif (fmt == NULL)// If There's No Textreturn;// Do Nothingva_start(ap, fmt);// Parses The String For Variables    vsprintf(text, fmt, ap);// And Converts Symbols To Actual Numbersva_end(ap);// Results Are Stored In TextglEnable(GL_TEXTURE_2D);// Enable Texture MappingglLoadIdentity();// Reset The Modelview MatrixglTranslated(x,y,0);// Position The Text (0,0 - Bottom Left)glListBase(base-32+(128*set));// Choose The Font Set (0 or 1)    //mod    if (set==1)    {    glScalef (5.5f,6.0f,5.5f);    //da povecamo font za iks i oks   }if (set==0)// If Set 0 Is Being Used Enlarge Font{glScalef(1.5f,2.0f,1.0f);// Enlarge Font Width And Height}   glCallLists(strlen(text),GL_UNSIGNED_BYTE, text);// Write The Text To The ScreenglDisable(GL_TEXTURE_2D);// Disable Texture Mapping}GLvoid KillFont(GLvoid)// Delete The Font From Memory{glDeleteLists(base,256);// Delete All 256 Display Lists}    int InitGL(GLvoid)// All Setup For OpenGL Goes Here{if (!LoadGLTextures())// Jump To Texture Loading Routine{return FALSE;// If Texture Didn't Load Return FALSE}BuildFont();// Build The FontglShadeModel(GL_SMOOTH);// Enable Smooth ShadingglClearColor(0.0f, 0.0f, 0.0f, 0.5f);// Black BackgroundglClearDepth(1.0f);// Depth Buffer SetupglHint(GL_LINE_SMOOTH_HINT, GL_NICEST);// Set Line AntialiasingglEnable(GL_BLEND);// Enable BlendingglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);// Type Of Blending To Usereturn TRUE;// Initialization Went OK}void glYouWon(){glPrint(200,200,0,"Congratulations you won");}void glDrawXO(){    if (turn==1)    {  glPrint(x,y,1,"X");}else{    glPrint(x,y,1,"0");    --turn;}}void glDrawGrid(){ glColor3f(1.0f,0.5f,0.5f);glLineWidth(3.0f);   glBegin(GL_LINES);glVertex2d(120,180);//vodorabne linijeglVertex2d( 490, 180);  glVertex2d(120,300);  glVertex2d(490,300);    glVertex2d(250,50);   //horizonztalne  glVertex2d(250,420);    glVertex2d(365,50);  glVertex2d(365,420);  glEnd();}int DrawGLScene(GLvoid)// Here's Where We Do All The Drawing{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();//resetovati da bih nam se promene zabelezile    glDrawGrid();//---------nacrtamo tableu    glColor3f(0.0f,0.5f,0.5f);   if(turn==1)   {    if(pp)glPrint(150,50,1,"X");turn++;}    else if    (turn==2){if(pp)glPrint(120,50,1,"0");turn--;} glBindTexture(GL_TEXTURE_2D, texture[0]);//Textura(font)    glPrint(207,15,0,"OKI-POKI");    return TRUE;}GLvoid KillGLWindow(GLvoid)// Properly Kill The Window{  KillFont();if (fullscreen)// Are We In Fullscreen Mode?{ChangeDisplaySettings(NULL,0);// If So Switch Back To The DesktopShowCursor(TRUE);// Show Mouse Pointer}if (hRC)// Do We Have A Rendering Context?{if (!wglMakeCurrent(NULL,NULL))// Are We Able To Release The DC And RC Contexts?{MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);}if (!wglDeleteContext(hRC))// Are We Able To Delete The RC?{MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);}hRC=NULL;// Set RC To NULL}if (hDC && !ReleaseDC(hWnd,hDC))// Are We Able To Release The DC{MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hDC=NULL;// Set DC To NULL}if (hWnd && !DestroyWindow(hWnd))// Are We Able To Destroy The Window?{MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hWnd=NULL;// Set hWnd To NULL}if (!UnregisterClass("OpenGL",hInstance))// Are We Able To Unregister Class{MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hInstance=NULL;// Set hInstance To NULL}}/*This Code Creates Our OpenGL Window.  Parameters Are:* *title- Title To Appear At The Top Of The Window* *width- Width Of The GL Window Or Fullscreen Mode* *height- Height Of The GL Window Or Fullscreen Mode* *bits- Number Of Bits To Use For Color (8/16/24/32)* *fullscreenflag- Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE)*/ BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag){GLuintPixelFormat;// Holds The Results After Searching For A MatchWNDCLASSwc;// Windows Class StructureDWORDdwExstyle;// Window Extended styleDWORDdwstyle;// Window styleRECTWindowRect;// Grabs Rectangle Upper Left / Lower Right ValuesWindowRect.left=(long)0;// Set Left Value To 0WindowRect.right=(long)width;// Set Right Value To Requested WidthWindowRect.top=(long)0;// Set Top Value To 0WindowRect.bottom=(long)height;// Set Bottom Value To Requested Heightfullscreen=fullscreenflag;// Set The Global Fullscreen FlaghInstance= GetModuleHandle(NULL);// Grab An Instance For Our Windowwc.style= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;// Redraw On Size, And Own DC For Window.wc.lpfnWndProc= (WNDPROC) WndProc;// WndProc Handles Messageswc.cbClsExtra= 0;// No Extra Window Datawc.cbWndExtra= 0;// No Extra Window Datawc.hInstance= hInstance;// Set The Instancewc.hIcon= LoadIcon(NULL, IDI_WINLOGO);// Load The Default Iconwc.hCursor= LoadCursor(NULL, IDC_ARROW);// Load The Arrow Pointerwc.hbrBackground= NULL;// No Background Required For GLwc.lpszMenuName= NULL;// We Don't Want A Menuwc.lpszClassName= "OpenGL";// Set The Class Nameif (!RegisterClass(&wc))// Attempt To Register The Window Class{MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if (fullscreen)// Attempt Fullscreen Mode?{DEVMODE dmScreenSettings;// Device Modememset(&dmScreenSettings,0,sizeof(dmScreenSettings));// Makes Sure Memory's CleareddmScreenSettings.dmSize=sizeof(dmScreenSettings);// Size Of The Devmode StructuredmScreenSettings.dmPelsWidth= width;// Selected Screen WidthdmScreenSettings.dmPelsHeight= height;// Selected Screen HeightdmScreenSettings.dmBitsPerPel= bits;// Selected Bits Per PixeldmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;// Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL){// If The Mode Fails, Offer Two Options.  Quit Or Use Windowed Mode.if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES){fullscreen=FALSE;// Windowed Mode Selected.  Fullscreen = FALSE}else{// Pop Up A Message Box Letting User Know The Program Is Closing.MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);return FALSE;// Return FALSE}}}if (fullscreen)// Are We Still In Fullscreen Mode?{dwExstyle=WS_EX_APPWINDOW;// Window Extended styledwstyle=WS_POPUP;// Windows styleShowCursor(FALSE);// Hide Mouse Pointer}else{dwExstyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;// Window Extended styledwstyle=WS_OVERLAPPEDWINDOW;// Windows style}AdjustWindowRectEx(&WindowRect, dwstyle, FALSE, dwExstyle);// Adjust Window To True Requested Size// Create The Windowif (!(hWnd=CreateWindowEx(dwExstyle,// Extended style For The Window"OpenGL",// Class Nametitle,// Window Titledwstyle |// Defined Window styleWS_CLIPSIBLINGS |// Required Window styleWS_CLIPCHILDREN,// Required Window style0, 0,// Window PositionWindowRect.right-WindowRect.left,// Calculate Window WidthWindowRect.bottom-WindowRect.top,// Calculate Window HeightNULL,// No Parent WindowNULL,// No MenuhInstance,// InstanceNULL)))// Dont Pass Anything To WM_CREATE{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}staticPIXELFORMATDESCRIPTOR pfd=// pfd Tells Windows How We Want Things To Be{sizeof(PIXELFORMATDESCRIPTOR),// Size Of This Pixel Format Descriptor1,// Version NumberPFD_DRAW_TO_WINDOW |// Format Must Support WindowPFD_SUPPORT_OPENGL |// Format Must Support OpenGLPFD_DOUBLEBUFFER,// Must Support Double BufferingPFD_TYPE_RGBA,// Request An RGBA Formatbits,// Select Our Color Depth0, 0, 0, 0, 0, 0,// Color Bits Ignored0,// No Alpha Buffer0,// Shift Bit Ignored0,// No Accumulation Buffer0, 0, 0, 0,// Accumulation Bits Ignored16,// 16Bit Z-Buffer (Depth Buffer)  0,// No Stencil Buffer0,// No Auxiliary BufferPFD_MAIN_PLANE,// Main Drawing Layer0,// Reserved0, 0, 0// Layer Masks Ignored};if (!(hDC=GetDC(hWnd)))// Did We Get A Device Context?{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))// Did Windows Find A Matching Pixel Format?{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if(!SetPixelFormat(hDC,PixelFormat,&pfd))// Are We Able To Set The Pixel Format?{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if (!(hRC=wglCreateContext(hDC)))// Are We Able To Get A Rendering Context?{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if(!wglMakeCurrent(hDC,hRC))// Try To Activate The Rendering Context{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}ShowWindow(hWnd,SW_SHOW);// Show The WindowSetForegroundWindow(hWnd);// Slightly Higher PrioritySetFocus(hWnd);// Sets Keyboard Focus To The WindowReSizeGLScene(width, height);// Set Up Our Perspective GL Screenif (!InitGL())// Initialize Our Newly Created GL Window{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}return TRUE;// Success}LRESULT CALLBACK WndProc(HWNDhWnd,// Handle For This WindowUINTuMsg,// Message For This WindowWPARAMwParam,// Additional Message InformationLPARAMlParam)// Additional Message Information{switch (uMsg)// Check For Windows Messages{case WM_ACTIVATE:// Watch For Window Activate Message{if (!HIWORD(wParam))// Check Minimization State{active=TRUE;// Program Is Active}else{active=FALSE;// Program Is No Longer Active}return 0;// Return To The Message Loop}case WM_SYSCOMMAND:{switch (wParam){case SC_SCREENSAVE:case SC_MONITORPOWER:return 0;}break;}case WM_CLOSE:// Did We Receive A Close Message?{PostQuitMessage(0);// Send A Quit Messagereturn 0;// Jump Back}case WM_KEYDOWN:// Is A Key Being Held Down?{keys[wParam] = TRUE;// If So, Mark It As TRUEreturn 0;// Jump Back}case WM_KEYUP:// Has A Key Been Released?{keys[wParam] = FALSE;// If So, Mark It As FALSEreturn 0;// Jump Back}case WM_SIZE:// Resize The OpenGL Window{ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  // LoWord=Width, HiWord=Heightreturn 0;// Jump Back}}// Pass All Unhandled Messages To DefWindowProcreturn DefWindowProc(hWnd,uMsg,wParam,lParam);}int WINAPI WinMain(HINSTANCEhInstance,// InstanceHINSTANCEhPrevInstance,// Previous InstanceLPSTRlpCmdLine,// Command Line ParametersintnCmdShow)// Window Show State{MSGmsg;// Windows Message StructureBOOLdone=FALSE;// Bool Variable To Exit Loop// Ask The User Which Screen Mode They Preferif (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO){fullscreen=FALSE;// Windowed Mode}// Create Our OpenGL Windowif (!CreateGLWindow("NeHe's First Polygon Tutorial",640,480,16,fullscreen)){return 0;// Quit If Window Was Not Created}while(!done)// Loop That Runs While done=FALSE{if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))// Is There A Message Waiting?{if (msg.message==WM_QUIT)// Have We Received A Quit Message?{done=TRUE;// If So done=TRUE}else// If Not, Deal With Window Messages{TranslateMessage(&msg);// Translate The MessageDispatchMessage(&msg);// Dispatch The Message}}else// If There Are No Messages{// Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()if ((active && !DrawGLScene()) || keys[VK_ESCAPE])// Active?  Was There A Quit Received?{done=TRUE;// ESC or DrawGLScene Signalled A Quit}else// Not Time To Quit, Update Screen{SwapBuffers(hDC);   if(keys['1']) {pp=true;    }if(keys['2']) {dp=true;    }  if(keys['3']) {tp=true;    }if(keys['4']) {cp=true;    }   if(keys['5']) {ptp=true;    }if(keys['6']) {sp=true;    }  if(keys['7']) {sdp=true;    }if(keys['8']) {op=true;    }  if(keys['9']) {dtp=true;    } }if (keys[VK_F1])// Is F1 Being Pressed?{keys[VK_F1]=FALSE;// If So Make Key FALSEKillGLWindow();// Kill Our Current Windowfullscreen=!fullscreen;// Toggle Fullscreen / Windowed Mode// Recreate Our OpenGL Windowif (!CreateGLWindow("NeHe's First Polygon Tutorial",640,480,16,fullscreen)){return 0;// Quit If Window Was Not Created}}}}// ShutdownKillGLWindow();// Kill The Windowreturn (msg.wParam);// Exit The Program} [Edited by - bequick on June 3, 2010 2:50:18 PM]
  Two things:Repost with [source] [/source].Other thing: may I comment your commenting style?What's the point of this: #include <windows.h> // Header File For Windowsor this: return Status; // Return The Statusreturn FALSE; // Return FALSEglEnable(GL_BLEND); // Enable Blendingkeys[wParam] = TRUE; // If So, Mark It As TRUESorry, I can't read code without indentation, that's why I commented only on your comments. And those totally needless comments make the whole stuff overwhelming, but [source] [/source] tags ad syntax highlight too.So repost from the original source file, so the indentation will be okay.Some questions: does the program draw anything at all?The font part looks fishy. Can you display text or just a letter anywhere in the window?   ;  I see you attempted to put  tags but this forum doesn't use BBCodes ;] You'll have to use [ source ] tagsGLvoid glPrint(GLint x, GLint y, int set, const char *fmt, ...)Did you really put ... as one of the arguments or is that to depict there are more of them?;Quote:Original post by boogyman19946Did you really put ... as one of the arguments or is that to depict there are more of them?He uses a variable number of arguments, as you can see in the function itself (va_ functions). You can pass N arguments at the dots, and in the function retrieve their values.Furthermore, this code is horrible to read. Using SDL will fix it up a lot. For the rest, indent, comment LESS as mentioned above. If you write good code you don't need comments, sometimes you can't write good code and need performance / trickery. That's where the comments get in for example :)Btw, you can use  tags, just not  tags:this is codewicked! I'm a mono font!this is CODEI am ugly;  Thanks for the replies...yes ther is drawing like glDrawGrid function for the grid and for glPrint that 1 means bigger letters..I used NeHe ramework for setig up the window and loading bitmaps so theres a lot of code i hope u can figure out what im trying to do   ;  So, can you display text or not?Anyways, there's have to be a glPushAttrib(GL_LIST_BIT); at the beginning of glPrint and a glPopAttrib(); at the end of it. But that's not the issue.Could you clarify what's wrong? Maybe you could post some screenshots too.The text isn't drawn, drawn in wrong position, or you have a black screen?I strongly recommend you to read this: FAQEspecially this part.The indentation is very screwed in your post. Do you use spaces instead of tabs in your code? Or did you just replace the  with [source]? If the latter, I suggest to copy it from the original source file again.;  I can draw everything alright the problem is that i do not know how to implement my X and O changing like you draw x then o then x then 0 etc..Because when user presses a number from 1-9 i drow the x/o in the right positionSomething like this:TheDrawingCodebool firstSquere,secondSquare;if(firstSquare)glPrint(the X position,the Y position,bigFont,"X");if(secondSqure)glPrint(the X position,diffrent Y position,bigFont,"X");keyboard inputif(key 1 pressed)firstSquere=true;if(key 2 pressed)seconSquere=true;And all this works but now i want to draw 0 and X(firs X,then 0,X,0,..etc)i tried something like this:int   turn=1;if(turn==1){if(firstSquare)glPrint(the X position,the Y position,bigFont,"X");turn++;}else if(turn==2){if(firstSquare)glPrint(the X position,the Y position,bigFont,"0");turn--;}But when i do somethin like this for all the other squeres it doesnt work it prints x and o in the same place or x twice or something like this So my question is how do i switch X and O like i explained earlier?Ihope you understand now!   ;  Your code has lots of issues.At first, you should place the keyboard handling code in WM_KEYDOWN. Because stuff happens when the keyboard is pushed. The keys[wParam] = TRUE; stuff if not for this kind of problem.You see, the keys[] thing is useful for continuous key presses, for example car games, plat formers etc. But n your situation, you only need to handle keys when you press the button, and only that case.An other thing: you should store the game-field as an array, to indicate what is on a cell: nothing/cross/circle.So when you receive a WM_KEYDOWN: (pseudocode)get_the_pressed_keyif(pressed_key is between '1' and '9')    convert_the_key_to_coordinates_xy    if(current_player == 0)   array[x][y] = 'X'    else   array[x][y] = 'O'    current_player = (current_player+1)%2 // or: current_player ^= 1break //from WM_KEYDOWNThan the display code:int DrawGLScene(GLvoid){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();    glDrawGrid();   glBindTexture(GL_TEXTURE_2D, texture[0]);//Textura(font)   for(int i = 0; i < 3; i++)   {    for(int k = 0; k < 3; k++)   {   glPrint(100+i*20,100+k*20,0,"%c",array[k]);   }    }glPrint(207,15,0,"OKI-POKI");return TRUE;Sorry, I'm a bit sleepy now so just threw the code together. The problem is that you miss some very basic things. (for example you draw the 'X' 'O' always in the same position, you don't understand the message stuff, you try do draw only the currently added 'X' or 'O', but you have cleared the buffer: obviously your previous 'X:s' and 'O:s' will be cleared). These problems would require to rewrite the whole stuff for you (and I won't do that)How long have you been programming? (you use space/tabs inconsistently) Maybe you should begin with more basic things before jumping into openGL.   ;  First of all thanks for the replie it was very usefull and as you may predicted im not into proggraming very long but i read some tuts and books so i know the basic stuff for c++ but i havent really pratice a lot and i figured that an x-0 game wouldnt be to dificult (it turns out its easier to make pong) but im lacking Opengl knowledge and some game logic maybe i shold make a dos X-0 game first(no graphics)but definately need more pratice on the oder hand if you considerd that abouth a month ago i tried to make a 3d racing game X-0 isnt that bad:D.Do you thing that the book "crating games in cpp a step by step guide" would be a good start?;Quote:Original post by bequickDo you thing that the book "crating games in cpp a step by step guide" would be a good start?Read the reviews on Amazon, it seems like there are some serious problems with that book.It might be a good idea to step back from OpenGL and learn more about C++ and fundamental programming concepts. If you're willing to do that, try this free book, or the ones at the bottom of this post.Another option would be to switch to another language, like Python or C#.   