A problem about Win32 window

How can i create a new Win32 window in a console program?
i mean i want the program begin with “main” and then create a new window to display the image, just like glut library.
i have created one, but the window is always inactive. What’s the problem?
Thanx!

If you want to do the way GLUT does, I suggest you grab the GLUT sources and check them out.

Grab them right here: http://www.xmission.com/~nate/glut.html

Crazy

Glut is much easier, I hear. But, here´s an example I worked out from examples on Microsoft´s Website using WIN32 code with OpenGL.
I think WIN32 when used to handle the windowing routine of OpenGL is also much faster than glut.
But, I could be wrong.

Like Microsofts apps, this example´s window can be resized into any shape with the mouse. But, like OpenGL, it displays 3D Stuff. However, this is a WIN32GUI OpenGL app and not a console app.

Actually, don´t know too much about Win32 Api yet. Just started Open GL, C++ and Win32 Api last week. But, the following example should compile on any C++ compiler, given the right linker libraries and includes, ect…

Well, Hope that helps…and I hope no characters get whacked due to the paste operation, because then, it might not compile.

BeginOpenGl

PS I almost forgot, but, rotate the object with the arrow keys.

/*
*A P P L I C A T I O N I D E N T I F I C A T I O N
*

  •                       OPEN GL 
    
  •                 CYLINDER VER 0.00001 
    
  •                   BeginOpenGL
    

*/

/I N C L U D E S/
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>

/* W I N D O W S G L O B A L S, D E F I N E S A N D P R O T O T Y P E S */
/Windows Globals/
/Make the class name into a global variable/
CHAR szAppName[]=“Win OpenGL”;

HWND ghWnd; /* handle for our window /
HDC ghDC; /
handle for device context /
HGLRC ghRC; /
handle for render context */

/Defines/
#define SWAPBUFFERS SwapBuffers(ghDC) /makes scene visible under current device context/
#define BLACK_INDEX 0 /black for background/
#define RED_INDEX 13 /green for wireframe cylinder object/
#define WIDTH 640 /starting window pixel width/
#define HEIGHT 480 /starting window pixel height/

/Prototypes or procedures for window and pixel format/
LONG WINAPI MainWndProc (HWND, UINT, WPARAM, LPARAM);
BOOL bSetupPixelFormat(HDC);

/* O P E N GL G L O B A L S, D E F I N E S A N D P R O T O T Y P E S */
/OpenGL globals/
GLfloat cylinderDiam, cylinderHeight, diaminc, heightinc;
GLdouble radius;

/OpenGL defines/
#define CYLINDER 1 /The object to be rendered/

/OpenGL prototypes or functions/
GLvoid resize(GLsizei, GLsizei);
GLvoid initializeGL(GLsizei, GLsizei);
GLvoid drawScene(GLvoid);
void endCylinderView( GLdouble, GLdouble, GLdouble, GLdouble);

/* R E G I S T E R F R A M E C L A S S A N D C R E A T E A S W I N D O W */

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
WNDCLASS wndclass;

/* Register the frame class */ 
wndclass.style         = 0; 
wndclass.lpfnWndProc   = (WNDPROC)MainWndProc; 
wndclass.cbClsExtra    = 0; 
wndclass.cbWndExtra    = 0; 
wndclass.hInstance     = hInstance; 
wndclass.hIcon         = LoadIcon (hInstance, szAppName); 
wndclass.hCursor       = LoadCursor (NULL,IDC_ARROW); 
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
wndclass.lpszMenuName  = szAppName; 
wndclass.lpszClassName = szAppName; 

if (!RegisterClass (&wndclass) ) 
    return FALSE; 

/* Create the frame */ 
ghWnd = CreateWindow (szAppName, 
         "CYLINDER VER 0.0001", 
     WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 
         CW_USEDEFAULT, 
         CW_USEDEFAULT, 
         WIDTH, 
         HEIGHT, 
         NULL, 
         NULL, 
         hInstance, 
         NULL); 

/* make sure window was created */ 
if (!ghWnd) 
    return FALSE; 

/* show and update main window */ 
ShowWindow (ghWnd, nCmdShow); 

UpdateWindow (ghWnd); 

/* animation loop */ 
while (1) { 
    /* 
     *  Process all pending messages 
     */ 

    while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE) 
    { 
        if (GetMessage(&msg, NULL, 0, 0) ) 
        { 
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        } else { 
            return TRUE; 
        } 
    } 
    drawScene(); 
} 

}

/* W I N 32 A P I W I N D O W´ s G E T D E V I C E C O N T E X T /
/
I T´ S R E N D E R I N G C O N T E X T /
/
A N D U S E R K E Y B O A R D R O U T I N E S /
/
main window procedure */
LONG WINAPI MainWndProc (
HWND hWnd, /*handle for our window */
UINT uMsg, /messages/
WPARAM wParam,
LPARAM lParam)
{
LONG lRet = 1;
PAINTSTRUCT ps;
RECT rect;

switch (uMsg) { 

/Win procedural call to get device context with window´s handle/
/Win procedural call to get render context concurrent with device context/
case WM_CREATE:
ghDC = GetDC(hWnd);
if (!bSetupPixelFormat(ghDC))
PostQuitMessage (0);

    ghRC = wglCreateContext(ghDC); 
    wglMakeCurrent(ghDC, ghRC); 
    GetClientRect(hWnd, &rect); 
    initializeGL(rect.right, rect.bottom); 
    break; 

/Win32 Api Paint/
case WM_PAINT:
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
/Win32 Api window´s size/
case WM_SIZE:
GetClientRect(hWnd, &rect);
resize(rect.right, rect.bottom);
break;

/Win32 Api to close window and reset render and device context to zero/
case WM_CLOSE:
if (ghRC)
wglDeleteContext(ghRC);
if (ghDC)
ReleaseDC(hWnd, ghDC);
ghRC = 0;
ghDC = 0;

    DestroyWindow (hWnd); 
    break;

/Win32 Api to destroy window and delete render and device context/
case WM_DESTROY:
if (ghRC)
wglDeleteContext(ghRC);
if (ghDC)
ReleaseDC(hWnd, ghDC);
PostQuitMessage (0);
break;

/User controlled Kyboard routines/
case WM_KEYDOWN:
switch (wParam) {
case VK_LEFT:
diaminc += 0.2F;
break;
case VK_RIGHT:
diaminc -= 0.2F;
break;
case VK_UP:
heightinc += 0.2F;
break;
case VK_DOWN:
heightinc -= 0.2F;
break;
}
/* Windows procedure for messages*/
default:
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
break;
}

return lRet; 

}

/* D E T E R M I N A T I O N O F D E P T H A N D P I X E L F O R M A T*/

BOOL bSetupPixelFormat(HDC hdc)
{
PIXELFORMATDESCRIPTOR pfd, *ppfd;
int pixelformat;

ppfd = &pfd; 

ppfd-&gt;nSize = sizeof(PIXELFORMATDESCRIPTOR); 
ppfd-&gt;nVersion = 1; 
ppfd-&gt;dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |   
                    PFD_DOUBLEBUFFER; 
ppfd-&gt;dwLayerMask = PFD_MAIN_PLANE; 
ppfd-&gt;iPixelType = PFD_TYPE_COLORINDEX; 
ppfd-&gt;cColorBits = 8; 
ppfd-&gt;cDepthBits = 16; 
ppfd-&gt;cAccumBits = 0; 
ppfd-&gt;cStencilBits = 0; 

pixelformat = ChoosePixelFormat(hdc, ppfd); 

if ( (pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0 ) 
{ 
    MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK); 
    return FALSE; 
} 

if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) 
{ 
    MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK); 
    return FALSE; 
} 

return TRUE; 

}

/* O P E N GL R E S I Z E A N D P R O J E C T I O N T R A N S F O R M S*/
GLvoid resize( GLsizei width, GLsizei height )
{
GLfloat aspect;

glViewport( 0, 0, width, height ); 

aspect = (GLfloat) width / height; 

glMatrixMode( GL_PROJECTION ); 
glLoadIdentity(); 
gluPerspective( 45.0, aspect, 3.0, 7.0 ); 
glMatrixMode( GL_MODELVIEW ); 

}

/* O P E N GL R E F R E S H */

/* Object Set Up */
GLvoid createObjects()
{
GLUquadricObj *quadObj;

glNewList(CYLINDER, GL_COMPILE);             
    quadObj = gluNewQuadric (); 
    gluQuadricDrawStyle (quadObj, GLU_FILL); 
    gluQuadricNormals (quadObj, GLU_SMOOTH); 
    gluCylinder (quadObj, 0.6, 0.6, 1.2, 24, 4);      
glEndList();     

}

/* Function Initialize Scene objects */
GLvoid initializeGL(GLsizei width, GLsizei height)
{
GLfloat maxObjectSize, aspect;
GLdouble near_plane, far_plane;

/* Initial depth and background */
glClearIndex( (GLfloat)BLACK_INDEX);
glClearDepth( 1.0 );

/* Initial depth test */
glEnable(GL_DEPTH_TEST);

glMatrixMode( GL_PROJECTION ); 
aspect = (GLfloat) width / height; 
gluPerspective( 45.0, aspect, 3.0, 7.0 ); 
glMatrixMode( GL_MODELVIEW ); 

near_plane = 3.0; 
far_plane = 12.0; 
maxObjectSize = 3.0F; 
radius = near_plane + maxObjectSize/2.0; 

cylinderDiam = 0.0F; 
cylinderHeight = 0.0F; 
diaminc = 3.0F; 
heightinc = 3.0F; 

createObjects(); 

}

/Set model transform for object (i) using glTranslatef, glScalef, glRotatef, and/or equivalent./
void endCylinderView(GLdouble radius, GLdouble twist, GLdouble cylinderDiam,
GLdouble cylinderHeight)
{
glTranslated(0.0, 0.0, -radius);
glRotated(-twist, 0.0, 0.0, 1.0);
glRotated(-cylinderHeight, 1.0, 0.0, 0.0);
glRotated(cylinderDiam, 0.0, 0.0, 1.0);

}

/* Final Function to Draw current scene objects, ect */

GLvoid drawScene(GLvoid)
{
/Clear previous frame depth and color buffer enabling next frame/
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

/access OpenGl´s matrix stack to save transformations/
glPushMatrix();

 /*User´s Kayboard values*/
    cylinderDiam += diaminc*.5; 
    cylinderHeight += heightinc*.5;
     
 /*Call to object´s function with current values*/
    endCylinderView(radius, 0, cylinderDiam, cylinderHeight);         
     
/* Final Call for Objects to be rendered*/
    glIndexi(RED_INDEX); 
    glCallList(CYLINDER);     

/restore OpenGl´s matrix stack transformations to continue to translatef/
glPopMatrix();

/* Make scene visible */
SWAPBUFFERS;
}

Originally posted by BeginOpenGL:
I think WIN32 when used to handle the windowing routine of OpenGL is also much faster than glut.
Maybe it is. I really never tried that since it does not make a difference at all.
The point is that no one will resize your window all the time. Resizing the window is not a performance path. Thinking about optimizing it is a bad idea which gains you nothing.

Really, go for GLUT if you are a starter.
Good reasons to use pure win32:

  • Access win32-specific features (and sometimes you can do that even when using GLUT).

Didn’t look at the source code at all.

Yeah. I think the way to go for a game or something like that, and then again for a begginer, would probably be the way Nehe set´s up the windows routines. Giving the user an option at partial resize or full screen. I like the way NeHe accomplishes it.

But, since I´m just starting out, I wanted to work out the windowing routine in another different manner from the general way windowing is handeled, at least in the few examples I´ve had a chance to see out on the net.

The above way, might be a better way to handle a GUI app that may need menus, dialog boxes, ect. But, one that might need to include 3D stuff as well. Like, 3d editors, basic 3d simulations. Or 3D apps that might serve as learning platforms. But, apps that are´nt necessarily games, either.

However, I really do´nt know much about it yet. Ít just seems to me to be a different windowing routine from the ones I´ve seen out on the net for OpenGL. That, might make it interesting to some,…maybe. Which is why I posted it.

BeginOpenGL

Generally, when you’re new to something, doing it “a new way” should be the LAST thing on your mind. You need to know how it’s usually done, first, to be able to evaluate the pros and cons of another way.

The NeHe base code (at nehe.gamedev.net) is a pretty decent start for anyone wanting to start on OpenGL in a Win32 specific way. It’s reasonably easy to slap in more windows, menus, buttons, etc within the NeHe code (although it’s certainly no MFC – you have to use pure Win32 calls).

Yeah, like I said above, Nehe´s windowing routines are nice. Just need some more time to look at the examples.

In the meantime, if anybody else finds the code useful, then, so be it.

BeginOpenGL

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.