Quads

Started by
8 comments, last by JohnHurt 18 years, 10 months ago
I am trying to render a hallway, with walls, a roof, and a floor. Here is the graphic related part of my code:

/**************************
 * Includes
 *
 **************************/

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
 
struct Point3f
{
	float x, y, z;
};
 
void DrawPoint(Point3f p)
{
    glVertex3f(p.x, p.y, p.z);
}


 void DrawQuad(Point3f tl, Point3f br)
{
    Point3f tr;
    Point3f bl;
    
    tr.x = br.x;
    tr.y = tl.y;
    tr.z = br.z;
    
    bl.x = tl.x;
    bl.y = br.y;
    bl.z = tl.z;
    
    glBegin(GL_QUADS);
        /*DrawPoint(tl);
        DrawPoint(bl);
        DrawPoint(br);
        
        DrawPoint(tl);
        DrawPoint(tr);
        DrawPoint(br);
		*/

		DrawPoint(tl);
		DrawPoint(tr);
		DrawPoint(br);
		DrawPoint(bl);
    glEnd();
}

void DrawQuad(float x1, float y1, float z1, float x2, float y2, float z2)
{
    Point3f p1 = {x1, y1, z1};
    Point3f p2 = {x2, y2, z2};
    
    DrawQuad(p1, p2);
}

void Render()
{

            glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
            glClear (GL_COLOR_BUFFER_BIT);
            
            glColor3f(0.0f, 0.0f, 1.0f);

	    DrawQuad( 0.5f, 0.5f, -4.0f, -0.5f, 0.5f, -0.0f);
            DrawQuad(0.5f, -0.5f, -4.0f, 0.5f, 0.5f, -0.0f);
            DrawQuad(-0.5f, 0.5f, -0.0f, -0.5f, -0.5f, -4.0f);
            DrawQuad( 0.5f, -0.5f, -4.0f, -0.5f, -0.5f, -0.0f);
}

void Init()
{

    gluPerspective(45.0f, 640/480, 0.1f, 1000.0f);
}


But when I execute it, I only get the walls rendered. What am I doing wrong? Help would be appreciated.
Advertisement
Are you sure you are actually drawing the floor / ceiling ? I don't mean to sound smart but I can only see four calls to your 'drawQuad()' method.. For the described scene you will need a total of six quads, four walls and the floor / ceiling quads. Or are you only drawing the two side walls of the hallway, and not the two end walls ?

Are you using depth testing also? I see you are clearing the screen but you will need to enable depth testing if you want the quads to be drawn in the correct manner on top of each other. You can enable depth testing by using:

glEnable(GL.GL_DEPTH_TEST);

Once you enable depth testing you must also select a correct depth function. Normally you will want objects that are closer to be drawn over objects that are further away, so you would use the following depth function:

glDepthFunc(GL.GL_LESS);

You must also clear the depth buffer for each frame you draw- just like you done with clearing the screen:

glClear(GL.GL_DEPTH_BUFFER_BIT);

All this stuff is in the OpenGL Red Book. If you don't already have it then I would advise you download it- as its available free off the OpenGL website.

Regards,
Darragh

thanks for your suggestion, but i still only see the walls, even by enabling
depth testing. By the way, I am not putting in the two end walls.
This is strange...

in case you want to know what the quads represent...
            DrawQuad( 0.5f, 0.5f, -4.0f, -0.5f, 0.5f, -0.0f);   // Roof            DrawQuad(0.5f, -0.5f, -4.0f, 0.5f, 0.5f, -0.0f);    // Wall            DrawQuad(-0.5f, 0.5f, -0.0f, -0.5f, -0.5f, -4.0f);  // Wall            DrawQuad( 0.5f, -0.5f, -4.0f, -0.5f, -0.5f, -0.0f); // Floor
Did you turn on face culling. The function you use appears to have the points drawn clockwise where most culling that I know of does culling on the clockwise faces, so you wouldn't see them. Did you glEnable(GL_CULL_FACE), that would do the problem. If so, a solution is to not enable that or to wrap the faces the other way. I didn't see any other errors, though I think it is kind of a strange way to draw quads.


After I enable face culling, the left wall disappears too and all that I can
see is the right wall.

Maybe there are some errors in the way im setting up gl or something.
Here is all my source merged into one file.
/************************** * Includes * **************************/#include <windows.h>#include <gl/gl.h>#include <gl/glu.h>/************************** * Function Declarations * **************************/LRESULT CALLBACK WndProc (HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam);void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);/************************** * WinMain * **************************/ struct Point3f{	float x, y, z;}; void DrawPoint(Point3f p){    glVertex3f(p.x, p.y, p.z);} void DrawQuad(Point3f tl, Point3f br){    Point3f tr;    Point3f bl;        tr.x = br.x;    tr.y = tl.y;    tr.z = br.z;        bl.x = tl.x;    bl.y = br.y;    bl.z = tl.z;        glBegin(GL_QUADS);        /*DrawPoint(tl);        DrawPoint(bl);        DrawPoint(br);                DrawPoint(tl);        DrawPoint(tr);        DrawPoint(br);		*/		DrawPoint(tl);		DrawPoint(tr);		DrawPoint(br);		DrawPoint(bl);    glEnd();}void DrawQuad(float x1, float y1, float z1, float x2, float y2, float z2){    Point3f p1 = {x1, y1, z1};    Point3f p2 = {x2, y2, z2};        DrawQuad(p1, p2);} int WINAPI WinMain (HINSTANCE hInstance,                    HINSTANCE hPrevInstance,                    LPSTR lpCmdLine,                    int iCmdShow){    WNDCLASS wc;    HWND hWnd;    HDC hDC;    HGLRC hRC;            MSG msg;    BOOL bQuit = FALSE;    float theta = 0.0f;    /* register window class */    wc.style = CS_OWNDC;    wc.lpfnWndProc = WndProc;    wc.cbClsExtra = 0;    wc.cbWndExtra = 0;    wc.hInstance = hInstance;    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);    wc.hCursor = LoadCursor (NULL, IDC_ARROW);    wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);    wc.lpszMenuName = NULL;    wc.lpszClassName = "GLSample";    RegisterClass (&wc);    /* create main window */    hWnd = CreateWindow (      "GLSample", "OpenGL Sample",       WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,      0, 0, 640, 480,      NULL, NULL, hInstance, NULL);    /* enable OpenGL for the window */    EnableOpenGL (hWnd, &hDC, &hRC);    /* program main loop */    while (!bQuit)    {        /* check for messages */        if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))        {            /* handle or dispatch messages */            if (msg.message == WM_QUIT)            {                bQuit = TRUE;            }            else            {                TranslateMessage (&msg);                DispatchMessage (&msg);            }        }        else        {            /* OpenGL animation code goes here */            glClearColor (0.0f, 0.0f, 0.0f, 0.0f);            glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);            glColor3f(0.0f, 0.0f, 1.0f);            /*DrawQuad( 0.5f, 0.5f, -4.0f, -0.5f, 0.5f, -0.0f);            DrawQuad(0.5f, -0.5f, -4.0f, 0.5f, 0.5f, -0.0f);            DrawQuad(-0.5f, 0.5f, -0.0f, -0.5f, -0.5f, -4.0f);            DrawQuad( 0.5f, -0.5f, -4.0f, -0.5f, -0.5f, -0.0f);			*/			DrawQuad( 0.5f, 0.5f, -4.0f, -0.5f, 0.5f, -0.0f);            DrawQuad(0.5f, -0.5f, -4.0f, 0.5f, 0.5f, -0.0f);            DrawQuad(-0.5f, 0.5f, -0.0f, -0.5f, -0.5f, -4.0f);            DrawQuad( 0.5f, -0.5f, -4.0f, -0.5f, -0.5f, -0.0f);            SwapBuffers (hDC);        }    }    /* shutdown OpenGL */    DisableOpenGL (hWnd, hDC, hRC);    /* destroy the window explicitly */    DestroyWindow (hWnd);    return msg.wParam;}/******************** * Window Procedure * ********************/LRESULT CALLBACK WndProc (HWND hWnd, UINT message,                          WPARAM wParam, LPARAM lParam){    switch (message)    {    case WM_CREATE:        return 0;    case WM_CLOSE:        PostQuitMessage (0);        return 0;    case WM_DESTROY:        return 0;    case WM_KEYDOWN:        switch (wParam)        {        case VK_ESCAPE:            PostQuitMessage(0);            return 0;        }        return 0;    default:        return DefWindowProc (hWnd, message, wParam, lParam);    }}/******************* * Enable OpenGL * *******************/void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC){    PIXELFORMATDESCRIPTOR pfd;    int iFormat;    /* get the device context (DC) */    *hDC = GetDC (hWnd);    /* set the pixel format for the DC */    ZeroMemory (&pfd, sizeof (pfd));    pfd.nSize = sizeof (pfd);    pfd.nVersion = 1;    pfd.dwFlags = PFD_DRAW_TO_WINDOW |       PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;    pfd.iPixelType = PFD_TYPE_RGBA;    pfd.cColorBits = 24;    pfd.cDepthBits = 16;    pfd.iLayerType = PFD_MAIN_PLANE;    iFormat = ChoosePixelFormat (*hDC, &pfd);    SetPixelFormat (*hDC, iFormat, &pfd);    /* create and enable the render context (RC) */    *hRC = wglCreateContext( *hDC );    wglMakeCurrent( *hDC, *hRC );    gluPerspective(45.0f, 640/480, 0.1f, 1000.0f);	//gluLookAt(0, 0, -5, 0, 0, 0, 0, 1, 0);	glEnable(GL_DEPTH_TEST);	glDepthFunc(GL_LESS);	glEnable(GL_CULL_FACE);}/****************** * Disable OpenGL * ******************/void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC){    wglMakeCurrent (NULL, NULL);    wglDeleteContext (hRC);    ReleaseDC (hWnd, hDC);}
Try disabling culling completely and run it again [glDisable(GL_CULL_FACE);].
disabling face culling just gives me the same result as usual.. only two walls
I think the problem is that you can't define a quad with only the topleft and bottom right vertices. It leaves the orientation of the quad ambigous. Think about it, if you hold a piece of paper by two corners, you can rotate it while those two corners remain in the same position.

If you replace you roof with this:
glBegin(GL_QUADS);
glVertex3f(0.5f, 0.5f, -4.0f);
glVertex3f(0.5f, 0.5f, 0.0f);
glVertex3f(-0.5f, 0.5f, 0.0f);
glVertex3f(-0.5f, 0.5f, -4.0f);
glEnd();

it works.

I would suggest defining a your DrawQuad function with 4 arguments instead of two:

void DrawQuad(Point3f top_left, Point3f top_right, Point3f bottom_right, Point3f bottom_left)
{
glBegin(GL_QUADS);
DrawPoint(top_left);
DrawPoint(top_right);
DrawPoint(bottom_right);
DrawPoint(bottom_left);
glEnd();
}
Thanks a LOT. it works. (Cant believe i wasted 5 days trying to find a solution to such a simple problem... now i can start working on my Four Elements IV game [smile])
S'Alright. I once spent a week trying to figure out a PHP error, then realised I'd spelt a variable wrong (grrrr, what's wrong with that? That SHOULD work!)

This topic is closed to new replies.

Advertisement