Menu

OpenGl and Windows stuff

Anubis208
2007-07-04
2012-09-26
  • Anubis208

    Anubis208 - 2007-07-04

    I am fairly new to windows programming, and I have noticed that there are several different syntaxes for making a window. I have just started to learn opengl and I can't figure out where to put the code in the window's code that is generated when you make a windows project. I have looked at the opengl example that comes with devcpp and it has a different syntax than the windows project generates it. How do you get opengl into a 'real' window, not just a popup?

     
    • Nobody/Anonymous

      Look closer at an excerpt from that code I posted earlier.
      I have added more comments to help you out a little more.
      If you add the new function and it's call within "drawWithGL()" to the code I posted earlier, it will work.

      void drawWithGL() {
      //Must have a current and valid glContext before making gl function calls
      wglMakeCurrent(hDC, hRC);

      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

      //We should only be using the modelview matrix at this point, and the identity should be it's value.
      //With this call, we are saving the current matrice's(modelview) current value(identity).
      //This is the fastest way to effectually load the identity matrix, you will understand in a sec...
      glPushMatrix();

      //Now, we can just play around with the matrix, and the 'world' moves around in relation to the POV
      theta += 1.0f;
      glRotatef(theta, xrot, yrot, zrot);

      //There are only a few gl calls that can be used within glBegin() and glEnd().
      glBegin(GL_TRIANGLES);
      glColor3f(1.0f, 0.0f, 0.0f);
      glVertex2f(0.0f, 1.0f);
      glColor3f(0.0f, 1.0f, 0.0f);
      glVertex2f(0.87f, -0.5f);
      glColor3f(0.0f, 0.0f, 1.0f);
      glVertex2f(-0.87f, -0.5f);
      glEnd();

      //We have finished moving this/these objects with the modelview modifications we have done so far,
      //Now just pop the mods away, and we are back to the indentity modelview matrix.
      //Pushing & popping the identity matrix is faster then calling glLoadIdentity().
      glPopMatrix();

      //Add the new stuff you wanted to draw, but failed to see on the screen
      drawWithGL_2();

      //IMPORTANT: Do you remember the following line? -
      //pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
      //PFD_DOUBLEBUFFER means that you have a 'front' and a 'back' buffer. The contents of the front buffer are
      //sent to the moniter and you can see it. All your gl calls modify the back buffer! If you want to see the
      //new stuff, and the code is correct, you swap the back buffer to the front.
      //Each call to SwapBuffers() == one frame. 30 successful calls per second == 30 frames per second.
      //A THOUGHT: This function should be called "refresh(HDC hDC)" instead of "drawWithGL()".
      SwapBuffers(hDC);
      }

      //My version of what you tried to do.
      //Try this - change the values of the vert's position realtime - make some whacky, warping triangles or quads.
      void drawWithGL_2() {
      static float rtri = 0.0f;
      static float rquad = 0.0f;

      glPushMatrix();
      glTranslatef(-1.5f, 0.0f, -6.0f);
      glRotatef(rtri, 0.0f, 1.0f, 0.0f);
      glBegin(GL_TRIANGLES);
      glColor3f(1.0f, 0.0f, 0.0f);
      glVertex3f(0.0f, 1.0f, 0.0f);
      glVertex3f(-1.0f, -1.0f, 0.0f);
      glVertex3f(1.0f, -1.0f, 0.0f);
      glEnd();
      glPopMatrix();

      glPushMatrix();
      glTranslatef(1.5f, 0.0f, 0.0f);
      glRotatef(rquad,1.0f, 0.0f, 0.0f);
      glBegin(GL_QUADS);
      glColor3f(0.5f, 0.5f, 1.0f);
      glVertex3f(-1.0f, 1.0f, 0.0f);
      glVertex3f(1.0f, 1.0f, 0.0f);
      glVertex3f(1.0f, -1.0f, 0.0f);
      glVertex3f(-1.0f, -1.0f, 0.0f);
      glEnd();
      glPopMatrix();

      rtri += 0.2f;
      rquad -= 0.15f;
      }

      I recommend that you stop by Borders and get the best GL book out there - "OpenGL Superbible".
      This is a book that beginners can easily understand, and yet pros can also find useful.
      And while you are there, check out "Beginning OpenGL Game Programming" and it's sequel,
      "More OpenGL Game Programming". I own these, and most gl books currently in print.
      Take some advice - Superbible is the best, start with it!!! All the gl tutorials on
      the internet combined cannot teach you what this one book can.

      M.B.

       
    • Ultim

      Ultim - 2007-07-04
       
    • Anubis208

      Anubis208 - 2007-07-04

      I have tried this and many other tutorials like it. None of them work on devcpp. By the way, I'm using version 4.9.9.2 on windows XP professional. Here is the code of a thing I did with the example and tried to put it into a regular window.

      include <windows.h>

      include <gl/gl.h>

      / Declare Windows procedure /
      LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
      void EnableOpenGL(HWND hwnd, HDC hDC, HGLRC hRC);
      void DisableOpenGL(HWND hwnd, HDC hDC, HGLRC hRC);
      float xrot = 0.0f;
      float yrot = 0.0f;
      float zrot = 0.0f;
      / Make the class name into a global variable /
      char szClassName[ ] = "WindowsApp";

      int WINAPI WinMain (HINSTANCE hThisInstance,
      HINSTANCE hPrevInstance,
      LPSTR lpszArgument,
      int nFunsterStil)

      {
      HWND hwnd; / This is the handle for our window /
      MSG messages; / Here messages to the application are saved /
      WNDCLASSEX wincl; / Data structure for the windowclass /
      BOOL bQuit = FALSE;
      float theta = 0.0f;
      / The Window structure /
      wincl.hInstance = hThisInstance;
      wincl.lpszClassName = szClassName;
      wincl.lpfnWndProc = WindowProcedure; / This function is called by windows /
      wincl.style = CS_DBLCLKS; / Catch double-clicks /
      wincl.cbSize = sizeof (WNDCLASSEX);

      /* Use default icon and mouse-pointer */
      wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
      wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
      wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
      wincl.lpszMenuName = NULL;                 /* No menu */
      wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
      wincl.cbWndExtra = 0;                      /* structure or the window instance */
      /* Use Windows's default color as the background of the window */
      wincl.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
      
      /* Register the window class, and if it fails quit the program */
      if (!RegisterClassEx (&amp;wincl))
          return 0;
      
      /* The class is registered, let's create the program*/
      hwnd = CreateWindowEx (
             0,                   /* Extended possibilites for variation */
             szClassName,         /* Classname */
             &quot;OpenGl Triangle&quot;,       /* Title Text */
             WS_OVERLAPPEDWINDOW, /* default window */
             CW_USEDEFAULT,       /* Windows decides the position */
             CW_USEDEFAULT,       /* where the window ends up on the screen */
             256,                 /* The programs width */
             256,                 /* and height in pixels */
             HWND_DESKTOP,        /* The window is a child-window to desktop */
             NULL,                /* No menu */
             hThisInstance,       /* Program Instance handler */
             NULL                 /* No Window Creation data */
             );
      
      /* Make the window visible on the screen */
      ShowWindow (hwnd, nFunsterStil);
      

      EnableOpenGL (hwnd, &hDC, &hRC);

      /* program main loop */
      while (!bQuit)
      {
          /* check for messages */
          if (PeekMessage (&amp;msg, NULL, 0, 0, PM_REMOVE))
          {
              /* handle or dispatch messages */
              if (msg.message == WM_QUIT)
              {
                  bQuit = TRUE;
              }
              else
              {
                  TranslateMessage (&amp;msg);
                  DispatchMessage (&amp;msg);
              }
          }
          else
          {
              /* OpenGL animation code goes here */
      
              glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
              glClear (GL_COLOR_BUFFER_BIT);
      
              glPushMatrix ();
              glRotatef (theta, xrot, yrot, zrot);
              glBegin (GL_TRIANGLES);
              glColor3f (1.0f, 0.0f, 0.0f);   glVertex2f (0.0f, 1.0f);
              glColor3f (0.0f, 1.0f, 0.0f);   glVertex2f (0.87f, -0.5f);
              glColor3f (0.0f, 0.0f, 1.0f);   glVertex2f (-0.87f, -0.5f);
              glEnd ();
              glPopMatrix ();
      
              SwapBuffers (hDC);
      
              theta += 1.0f;
      
          }
      }
      
      /* shutdown OpenGL */
      DisableOpenGL (hwnd, hDC, hRC);
      
      /* destroy the window explicitly */
      DestroyWindow (hwnd);
      
      return msg.wParam;
      

      }
      / Run the message loop. It will run until GetMessage() returns 0 /
      while (GetMessage (&messages, NULL, 0, 0))
      {
      / Translate virtual-key messages into character messages /
      TranslateMessage(&messages);
      / Send message to WindowProcedure /
      DispatchMessage(&messages);
      }

      /* The program return-value is 0 - The value that PostQuitMessage() gave */
      return messages.wParam;
      

      }

      / This function is called by the Windows function DispatchMessage() /

      LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
      {
      switch (message) / handle the messages /
      {
      case WM_DESTROY:
      PostQuitMessage (0); / send a WM_QUIT to the message queue /
      break;
      case WM_KEYDOWN:
      switch (wParam)
      {
      case VK_UP:
      xrot = 1.0f;
      break;
      case VK_RIGHT:
      yrot = 1.0f;
      break;
      case VK_SHIFT:
      zrot = 1.0f;
      break;
      case VK_ESCAPE:
      PostQuitMessage(0);
      break;
      return 0;
      }
      case WM_KEYUP:
      switch (wParam)
      {
      case VK_UP:
      xrot = 0.0f;
      break;
      case VK_RIGHT:
      yrot = 0.0f;
      break;
      case VK_SHIFT:
      zrot = 0.0f;
      break;
      return 0;
      }
      default: / for messages that we don't deal with /
      return DefWindowProc (hwnd, message, wParam, lParam);
      }

      return 0;
      

      }

      Here's the compile log.

      Compiler: Default compiler
      Building Makefile: "C:\Dev-Cpp\Gl\Makefile.win"
      Executing make...
      make.exe -f "C:\Dev-Cpp\Gl\Makefile.win" main.o
      g++ -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" -c -o main.o main.cpp

      main.cpp: In function int WinMain(HINSTANCE__*, HINSTANCE__*, CHAR*, int)': main.cpp:63: error:hDC' undeclared (first use this function)
      main.cpp:63: error: (Each undeclared identifier is reported only once for each function it appears in.)
      main.cpp:63: error: hRC' undeclared (first use this function) main.cpp:69: error:msg' undeclared (first use this function)

      main.cpp: At global scope:
      main.cpp:114: error: expected unqualified-id before "while"
      main.cpp:114: error: expected ,' or;' before "while"
      main.cpp:123: error: expected unqualified-id before "return"

      main.cpp:123: error: expected ,' or;' before "return"
      main.cpp:124: error: expected declaration before '}' token
      make.exe: *** [main.o] Error 1

      Execution terminated

      Is there anything wrong with the code above?

       
    • S. Thomas Bradley

      Hello Everyone:

      Your code doesnt work because it is incomplete. It has the prototypes for the functions void EnableOpenGL() and DisableOpenGL() but doesnt actually contain those functions. In addition it doesnt define hDC or hRC, and it defines the variable 'messages' but uses 'msg'.

      I don't know where you got this code, but whoever wrote it did not test it, it looks to me like they just copied and pasted a bunch of code together from different sources.

      All is not lost however :o)

      Here is what I want you to do. In Dev, create a new project like this:
      1) Select File > New > Project.
      2) Click on the tab labeled 'Multimedia', there you will see an OpenGL project.
      3) Click on the OpenGL icon and save the project. When you do this you will have a main.cpp (or main.c) source code which is an OpenGL program in Windows, just as you are looking for. You will notice that it has a lot in common with the bad source code you were working on with the exception that it works.

      Compile it to see the result.

      Also, look in the thread PLEASE READ BEFORE POSTING A QUESTION, you will find a section near the top called GETTING STARTED WITH: there you will find a thread Getting started with OpenGL/GLUT. You will find it very helpful, you may also want to look at other threads there when you have other problems.

      See Ya
      Butch

       
    • Nobody/Anonymous

      At a minimum, this is what you have to do...

      During window creation:
      1) Initialize a WNDCLASSEX with the CS_OWNDC flags. Note - do not set a background brush for gl windows.
      2) Get a valid HWND with win32's CreateWindow() - be sure to set the WS_CLIPCHILDREN | WS_CLIPSIBLINGS flags.
      3) Get a HDC with win32's GetDC().
      4) Get a PIXELFORMATDESCRIPTOR with ChoosePixelFormat() & SetPixelFormat() - be sure to set the dwFlags to at least
      PFD_DRAW_TO_WINDOW | PFD_SUPPORT_GL | PFD_DOUBLEBUFFER.
      5) Create a HGLRC with wglCreateContext().
      6) Use glClearColor() to set the window's background color.

      To draw one frame at any time:
      1) Use wglMakeCurrent() to activate openGL for the window.
      2) Clear the previous drawing with glClear() - be sure to set the appropriate flags.
      3) Call your gl drawing code.
      4) Call SwapBuffers() to show your drawing.

      When you are done with the window:
      1) Call wglMakeCurrent(NULL, NULL), then use wglDeleteContext() to free the HGLRC.
      2) Use ReleaseContext() to free the HDC.
      3) Use DestroyWindow() to free the window.
      4) Use UnregisterClass(), if no other windows are also using it, to unregister the window's class.

      You must have a good understanding of all these functions. Download the win32 API' help file or go to MSDN and study up on them as you add each to you project, as I have left a ton for you to figure out on your own.

      M.B.

       
    • Anubis208

      Anubis208 - 2007-07-05

      when I try your method, butch, I get the same code as the opengl tutorial. I will have to read up more on windows to get this stuff right. Thanks for the help.

       
    • Nobody/Anonymous

      Here is a working example of what I posted earlier. Just start with DEV's openGL project and replace that code with this, and link to glu32.lib.

      define WIN32_LEAN_AND_MEAN //no MFC

      define WIN32_EXTRA_LEAN

      include <windows.h>

      include <gl/gl.h>

      include <gl/glu.h>

      HWND hwnd = NULL;
      HDC hDC = NULL;
      HGLRC hRC = NULL;
      PIXELFORMATDESCRIPTOR pfd;
      float xrot = 0.0f;
      float yrot = 0.0f;
      float zrot = 0.0f;
      float theta = 0.0f;

      LRESULT CALLBACK mainProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
      switch (msg) {
      case WM_KEYDOWN:
      switch (wParam) {
      case VK_UP: xrot = 1.0f; return 0;
      case VK_RIGHT: yrot = 1.0f; return 0;
      case VK_SHIFT: zrot = 1.0f; return 0;
      case VK_ESCAPE: PostQuitMessage(0); break;
      }
      break;

        case WM_KEYUP: 
           switch (wParam) { 
              case VK_UP: xrot = 0.0f; return 0; 
              case VK_RIGHT: yrot = 0.0f; return 0; 
              case VK_SHIFT: zrot = 0.0f; return 0;  
           }
           break;
      

      }

      return DefWindowProc(hwnd, msg, wParam, lParam);
      }

      void drawWithGL() {
      wglMakeCurrent(hDC, hRC);

      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

      glPushMatrix();
      theta += 1.0f;
      glRotatef(theta, xrot, yrot, zrot);
      glBegin(GL_TRIANGLES);
      glColor3f(1.0f, 0.0f, 0.0f);
      glVertex2f(0.0f, 1.0f);
      glColor3f(0.0f, 1.0f, 0.0f);
      glVertex2f(0.87f, -0.5f);
      glColor3f(0.0f, 0.0f, 1.0f);
      glVertex2f(-0.87f, -0.5f);
      glEnd();
      glPopMatrix();

      SwapBuffers(hDC);
      }

      void initGL(HWND hwnd, HDC &hDC, HGLRC &hRC) {
      //Set the pix format
      memset(&pfd, 0, sizeof(pfd));
      pfd.nSize = sizeof(pfd);
      pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
      pfd.iLayerType = PFD_MAIN_PLANE;
      pfd.nVersion = 1;
      pfd.iPixelType = PFD_TYPE_RGBA;
      pfd.cColorBits = 32;
      pfd.cDepthBits = 8;
      pfd.cStencilBits = 8;
      int pixFormat = ChoosePixelFormat(hDC, &pfd);
      SetPixelFormat(hDC, pixFormat, &pfd);

      //Create a gl context and make it current, then set its background color
      hRC = wglCreateContext(hDC);
      wglMakeCurrent(hDC, hRC);
      glClearColor(1.0f, 0.5f, 0.5f, 0.0f);

      //Set the viewport
      RECT rect;
      GetClientRect(hwnd, &rect);
      glViewport((GLint)0, (GLint)0, (GLint)rect.right, (GLint)rect.bottom);

      //Set up a perspecive projection.
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      double aspect = (double)rect.right / (double)rect.bottom;
      gluPerspective(90.0, aspect, 1.0, 8192);

      //Use the modelview matrix to move the camera from now on
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      //We cannot see the triangle if it sits on the near clip
      glTranslatef(0.0f, 0.0f, -4.0f);
      }

      int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prev, LPSTR pArgs, int cmdShow) {
      UNREFERENCED_PARAMETER(prev);

      WNDCLASS wc;
      wc.hInstance = hInst;
      wc.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
      wc.lpfnWndProc = mainProc;
      wc.cbClsExtra = 0;
      wc.cbWndExtra = 0;
      wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
      wc.hCursor = LoadCursor (NULL, IDC_ARROW);
      wc.hbrBackground = NULL;
      wc.lpszMenuName = NULL;
      wc.lpszClassName = "WindowsApp";
      RegisterClass(&wc);

      //Use WS_POPUP window style for quick and dirty fullscreen gl....
      //using ChangeDisplaySettings() is the best way
      hwnd = CreateWindow(wc.lpszClassName, NULL, WS_POPUP | WS_VISIBLE,
      0, 0, GetSystemMetrics(SM_CXMAXIMIZED),
      GetSystemMetrics(SM_CYMAXIMIZED),
      NULL, NULL, hInst, NULL);

      hDC = GetDC(hwnd);
      initGL(hwnd, hDC, hRC);

      MSG msg;
      while (GetMessage(&msg, NULL, 0, 0)) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);

        drawWithGL();
      

      }

      wglMakeCurrent(NULL, NULL);
      wglDeleteContext(hRC);
      ReleaseDC(hwnd, hDC);
      DestroyWindow(hwnd);
      UnregisterClass(wc.lpszClassName, hInst);

      return msg.wParam;
      }

      Enjoy,
      M.B.

       
    • Anubis208

      Anubis208 - 2007-07-09

      Thanks M.B.!!! It worked and by looking it over I can figure out what things are wrong with some other attempts I've made! Thanks for the help everyone!

       
    • Anubis208

      Anubis208 - 2007-07-10

      Okay, I've been following the NeHe tutorials (nehe.gamedev.net). I got to the one about rotating. It compiles fine, but does not draw the quad.
      int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
      {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
      glLoadIdentity(); // Reset The Current Modelview Matrix
      glTranslatef(-1.5f,0.0f,-6.0f);
      glRotatef(rtri,0.0f,1.0f,0.0f);
      glBegin(GL_TRIANGLES);
      glColor3f(1.0f,0.0f,0.0f);
      glVertex3f(0.0f,1.0f,0.0f);
      glColor3f(0.0f,1.0f,0.0f);
      glVertex3f(-1.0f,-1.0f,0.0f);
      glColor3f(0.0f,0.0f,1.0f);
      glVertex3f(1.0f,-1.0f,0.0f);
      glEnd();
      glLoadIdentity();
      glTranslatef(1.5f,0.0f,0.0f);
      glRotatef(rquad,1.0f,0.0f,0.0f);
      glColor3f(0.5f,0.5f,1.0f);
      glBegin(GL_QUADS);
      glVertex3f(-1.0f,1.0f,0.0f);
      glVertex3f(1.0f,1.0f,0.0f);
      glVertex3f(1.0f,-1.0f,0.0f);
      glVertex3f(-1.0f,-1.0f,0.0f);
      glEnd();
      rtri+=0.2f;
      rquad-=0.15f;
      return TRUE; // Everything Went OK
      }

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.