PDA

View Full Version : Triangle won't render



Aaron Prescott
08-25-2006, 06:38 PM
I have a program that is supposed to draw a triangle, but it won't render. It's fine when it's in 2D, but when I add the 3D variables in everything, even when the camera is looking straight at it (it should look like I didn't change anything) the triangle won't render. I'm not sure of the code to set up the projection (the SetProjection() function.) I can never remember how to do it, and I don't have the book that tells me how to do it.

Here's code:


/*main.cpp*/

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

#include "OpenGL.h"

/**************************
* Function Declarations
*
**************************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);

OpenGL *gl = NULL;


/**************************
* WinMain
*
**************************/

int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int iCmdShow)
{
WNDCLASS wc;
MSG msg;
BOOL bQuit = FALSE;

gl = new OpenGL;

/* 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 */
gl->hWnd = CreateWindow (
"GLSample", "OpenGL Sample",
WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE | WS_THICKFRAME,
100, 100, 400, 400,
NULL, NULL, hInstance, NULL);

//ShowWindow(gl->hWnd, SW_SHOW);

/* enable OpenGL for the window */
gl->EnableOpenGL ();

/* 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
{
gl->Draw();

glFinish();

SwapBuffers (gl->hDC);

Sleep (1);
}
}

/* shutdown OpenGL */
gl->DisableOpenGL ();

/* destroy the window explicitly */
DestroyWindow (gl->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;

case VK_NUMPAD8:
gl->eTheta += .1;
break;

case VK_NUMPAD2:
gl->eTheta -= .1;
break;

case VK_NUMPAD4:
gl->aTheta -= .1;
break;

case VK_NUMPAD6:
gl->aTheta += .1;
break;

case VK_NUMPAD5:
gl->aTheta = 0.0f;
gl->eTheta = 0.0f;
gl->dTheta = 0.0f;
break;
}
return 0;

default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
}



/*OpenGL.h*/

#include <math.h>
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>

#define PI 3.141592654
#define DEG2RAD(x) x * (PI / 180)

typedef struct POINT3D {
float x;
float y;
float z;
};

class OpenGL {
public:
HWND hWnd;
HDC hDC;
HGLRC hRC;

float theta;

float FoV_angle;
float FoV;

float e, a, d, n;
float eTheta, aTheta, dTheta;

POINT3D eye;
POINT3D up;

RECT wndSize;

void Draw();
void SetProjection();
void EnableOpenGL();
void DisableOpenGL();
void SetupProgram();
};

void OpenGL::SetupProgram() {
theta = 0.0f;

d = 1.5f;
e = DEG2RAD(45.0f);
a = DEG2RAD(135.0f);

eTheta = 0.0f;
aTheta = 0.0f;
dTheta = 0.0f;
}

void OpenGL::SetProjection() {
GetWindowRect(hWnd, &amp;wndSize);
FoV_angle = 45.0f;

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, wndSize.right - wndSize.left, wndSize.bottom - wndSize.top);
gluPerspective(FoV, (wndSize.right - wndSize.left) / (wndSize.bottom - wndSize.top), .5f, 200.0f);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
}

/*******************
* Enable OpenGL
*
*******************/

void OpenGL::EnableOpenGL() {
SetProjection();

PIXELFORMATDESCRIPTOR pfd;
int iFormat;

/* get the device context (DC) */
hDC = GetDC (hWnd);

/* set the pixel format for the DC */
ZeroMemory(&amp;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, &amp;pfd);
SetPixelFormat(hDC, iFormat, &amp;pfd);

/* create and enable the render context (RC) */
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);

SetupProgram();
}


/******************
* Disable OpenGL
*
******************/

void OpenGL::DisableOpenGL() {
wglMakeCurrent (NULL, NULL);
wglDeleteContext (hRC);
ReleaseDC (hWnd, hDC);
}

void OpenGL::Draw() {
glLoadIdentity();
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
glClear (GL_COLOR_BUFFER_BIT);

eye.x = (d * cos(e)) * cos(a);
eye.y = d * sin(e);
eye.z = (d * cos(e)) * sin(a);

n = sqrt(pow(d, 2) + 1) * cos(asin(e + (1 / (sqrt(pow(d, 2) + 1)))));

up.x = n * cos(a);
up.y = sqrt(pow(d, 2) + 1) * sin(asin(e + (1 / (sqrt(pow(d, 2) + 1)))));
up.z = n * sin(a);

gluLookAt(eye.x, eye.y, eye.z, 0.0f, 0.0f, 0.0f, up.x, up.y, up.z);

glPushMatrix ();
//glRotatef (theta, 0.0f, 0.0f, 1.0f);
//glTranslatef (0.0f, 0.0f, -d);
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 (0.87f, -0.5f, 0.0f);
glColor3f (0.0f, 0.0f, 1.0f); glVertex3f (-0.87f, -0.5f, 0.0f);
glEnd ();
glPopMatrix ();

theta += 1.0f;

a += aTheta;
e += eTheta;
d += dTheta;
}I'm using Dev C++ v 4.9.9.2 running on Windows XP. I'd just like to know what isn't right here because I have a couple programs that have a similar problem, and it's driving me nuts.

08-25-2006, 10:44 PM
have u create a opengl context?

songho
08-25-2006, 11:31 PM
Aaron Prescott,
Your eye position and up vector calculation might be wrong. Try to use a simple view point first before moving onto a complex one;
gluLookAt(0,0,1, 0,0,0, 0,1,0);

And I found several mistakes in your OpenGL class;
1. Any GL command must be called after the rendering context is opened. Therefore, SetProjection() must be called after wglMakeCurrent(hDC, hRC) in EnableOpenGL() block.

2. The order of glMatrixMode() is incorrect. You must load projection matrix in order to set Frustum, not model-view matrix.

glViewport(0, 0, wndSize.right - wndSize.left, wndSize.bottom - wndSize.top);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(FoV, (wndSize.right - wndSize.left) / (wndSize.bottom - wndSize.top), .5f, 200.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();3. The default winding rule for front face is counter clockwise, but you use opposite direction. You may be looking at the backface of the polygon. By default, OpenGL culls all backfaces and renders frontfaces only. To see both front and back faces, disable culling by using glDisable(GL_CULL_FACE).

Aaron Prescott
08-26-2006, 08:40 AM
Thanks for the help, songho. I tried all that you had there, and I got it. Thanks, again.