PDA

View Full Version : Simple drawing Issue



ekelly30
02-17-2011, 12:36 PM
I am having an issue trying to draw a simple 3D box on screen. it is not a cube, so I am trying to draw it using quads. So far I have tried to draw two sides, but only one of them is displaying.

The code I am using is as follows:

#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <vector.h>

#define GLUT_DISABLE_ATEXIT_HACK
#include "GL/glee.h"
#include "GL/glut.h"
#include "GL/glu.h"
#include "GL/gltools.h" // OpenGL toolkit
#include "GL/gl.h"

using namespace std;

// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Reset the modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Translate the whole scene out and into view
// This is the initial viewing transformation
glTranslatef(0.0f, 0.0f, -35.0f);

glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-12.0f, -12.0f, 0.0f);
glVertex3f(-12.0f, -12.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, 0.0f);

glVertex3f(-12.0f, -12.0f, 0.0f);
glVertex3f(-12.0f, -11.0f, 0.0f);
glVertex3f(12.0f, -11.0f, 0.0f);
glVertex3f(12.0f, -12.0f, 0.0f);

glEnd();

glutSwapBuffers();

}

// This function does any needed initialization on the rendering
// context.

void SetupRC()
{
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
glEnable(GL_CULL_FACE); // Do not calculate inside of jet

// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
}



void TimerFunc(int value)
{
glutPostRedisplay();
glutTimerFunc(100, TimerFunc, 1);
}

void ChangeSize(int w, int h)
{
GLfloat nRange = 100.0f;
static float ratio = 1.0f * w / h;

// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);

// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,ratio,1,1000);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
}



int main(int argc, char* argv[])
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL Atom");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutTimerFunc(500, TimerFunc, 1);

SetupRC();

glutMainLoop();

return 0;
}


Only the first set of quads displays. But as far as I can tell the second set are within the bounds of the viewport?

Another question I am curious about, does glVertex(); translate the position or does it always return to the position you were at?

Any help with this would be greatly appreciated, thank you.

Rosario Leonardi
02-17-2011, 03:06 PM
After the vertex transformation openGL discard all polygon that are not visible.
In particular discard the vertexes that are outside the clip space cause they are outside from the "camera" view and also (by default) discard the polygon that are not facing the camera.
This is way you usually render solid and the backface of a solid is always covered by the front face.

Polygon direction is given by polygon implicit normal. If the vector product of the normal and the camera direction is below zero the polygon is discarted.
The polygon normal is not given by the vertex normal attribute (this is used only for lighting) but by vertexes winding order. Take your right hand and close your palm following the vertex order, your thumb will point the normal direction.

Now, to solve your problem instead of sending the vertex in A B C D order send them in reverse order (D C B A).

Read this (ignore the deprecated warning):
http://www.opengl.org/wiki/Vertex_Transformation
this
http://www.schorsch.com/en/kbase/glossary/right-hand-rule.html
and this
http://www.opengl.org/resources/faq/technical/clipping.htm (10.090)

Question two:
glVertex don't make any translation, it simply specify the vertex position. All the transformation are done in the vertex shader or in your case in the vertex fixed pipeline.

edit: to learn transformation immediate mode (glBegin glEnd) it's OK but I suggest you to switch to vertex buffer object as soon as possible.

Alfonse Reinheart
02-17-2011, 04:37 PM
also (by default) discard the polygon that are not facing the camera.

GL_CULL_FACE is by default disabled.

ekelly30
02-18-2011, 11:17 AM
Thank you for the help, I've got it working now :)

However I am now having issues with my lighting. Would you be able to assist me with it? It's not behaving as I expect.


void init()
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
glEnable(GL_CULL_FACE); // Do not calculate inside of jet

// Create light components
GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 0.7f };
GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7, 1.0f };
GLfloat specularLight[] = { 0.0f, 1.0f, 3.0f, 1.0f };
GLfloat position[] = {0.0f, 10.0f, -10.0f};

// Assign created components to GL_LIGHT0
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glLightfv(GL_LIGHT1, GL_AMBIENT, ambientLight);

// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
}

This is the settings for the lighting, and below is the code for the object.




void DrawBase()
{
float mcolor[] = { 1.0f, 0.0f, 0.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mcolor);
float specReflection[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_SPECULAR, specReflection);
glMateriali(GL_FRONT, GL_SHININESS, 96);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Translate the whole scene out and into view
// This is the initial viewing transformation
glTranslatef(0.0f, 0.0f, -35.0f);

glBegin(GL_QUADS);

//Left side
glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(-12.0f, -12.0f, 0.0f);
glVertex3f(-12.0f, -12.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, 0.0f);

//Front
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f(-12.0f, -11.0f, 0.0f);
glVertex3f(-12.0f, -12.0f, 0.0f);
glVertex3f(12.0f, -12.0f, 0.0f);
glVertex3f(12.0f, -11.0f, 0.0f);

//Right side
glNormal3f(1.0f, 0.0f, 0.0f);
glVertex3f(12.0f, -11.0f, 0.0f);
glVertex3f(12.0f, -11.0f, -7.0f);
glVertex3f(12.0f, -12.0f, -7.0f);
glVertex3f(12.0f, -12.0f, 0.0f);

//Back
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f(12.0f, -12.0f, -7.0f);
glVertex3f(12.0f, -11.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, -7.0f);
glVertex3f(-12.0f, -12.0f, -7.0f);

//Top
glNormal3f(0.0f, 1.0f, 0.0f);
glVertex3f(12.0f, -11.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, 0.0f);
glVertex3f(12.0f, -11.0f, 0.0f);

//Bottom
glNormal3f(0.0f, -1.0f, 0.0f);
glVertex3f(12.0f, -12.0f, -7.0f);
glVertex3f(-12.0f, -12.0f, -7.0f);
glVertex3f(-12.0f, -12.0f, 0.0f);
glVertex3f(12.0f, -12.0f, 0.0f);

glEnd();

}

The object lights up, but it does not appear to be coming from any direction, the ambient light appears to be the only thing that affects it. What am I doing wrong?

I'll post the full code here below just in case you want to look at that:


#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <vector.h>

#define GLUT_DISABLE_ATEXIT_HACK
#include "GL/glee.h"
#include "GL/glut.h"
#include "GL/glu.h"
#include "GL/gltools.h" // OpenGL toolkit
#include "GL/gl.h"

using namespace std;

void DrawBase()
{
float mcolor[] = { 1.0f, 0.0f, 0.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mcolor);
float specReflection[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_SPECULAR, specReflection);
glMateriali(GL_FRONT, GL_SHININESS, 96);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Translate the whole scene out and into view
// This is the initial viewing transformation
glTranslatef(0.0f, 0.0f, -35.0f);

glBegin(GL_QUADS);

//Left side
glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(-12.0f, -12.0f, 0.0f);
glVertex3f(-12.0f, -12.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, 0.0f);

//Front
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f(-12.0f, -11.0f, 0.0f);
glVertex3f(-12.0f, -12.0f, 0.0f);
glVertex3f(12.0f, -12.0f, 0.0f);
glVertex3f(12.0f, -11.0f, 0.0f);

//Right side
glNormal3f(1.0f, 0.0f, 0.0f);
glVertex3f(12.0f, -11.0f, 0.0f);
glVertex3f(12.0f, -11.0f, -7.0f);
glVertex3f(12.0f, -12.0f, -7.0f);
glVertex3f(12.0f, -12.0f, 0.0f);

//Back
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f(12.0f, -12.0f, -7.0f);
glVertex3f(12.0f, -11.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, -7.0f);
glVertex3f(-12.0f, -12.0f, -7.0f);

//Top
glNormal3f(0.0f, 1.0f, 0.0f);
glVertex3f(12.0f, -11.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, -7.0f);
glVertex3f(-12.0f, -11.0f, 0.0f);
glVertex3f(12.0f, -11.0f, 0.0f);

//Bottom
glNormal3f(0.0f, -1.0f, 0.0f);
glVertex3f(12.0f, -12.0f, -7.0f);
glVertex3f(-12.0f, -12.0f, -7.0f);
glVertex3f(-12.0f, -12.0f, 0.0f);
glVertex3f(12.0f, -12.0f, 0.0f);

glEnd();

}

// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

DrawBase();

glutSwapBuffers();

}

void init()
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
glEnable(GL_CULL_FACE); // Do not calculate inside of jet

// Create light components
GLfloat ambientLight[] = { 0.4f, 0.4f, 0.4f, 0.7f };
GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7, 1.0f };
GLfloat specularLight[] = { 0.0f, 1.0f, 3.0f, 1.0f };
GLfloat position[] = {0.0f, 10.0f, -10.0f};

// Assign created components to GL_LIGHT0
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glLightfv(GL_LIGHT1, GL_AMBIENT, ambientLight);

// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
}

void TimerFunc(int value)

{
glutPostRedisplay();
glutTimerFunc(100, TimerFunc, 1);
}

void ChangeSize(int w, int h)
{
GLfloat nRange = 100.0f;
static float ratio = 1.0f * w / h;

// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);

// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,ratio,1,1000);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
}



int main(int argc, char* argv[])

{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_ACCUM | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL Atom");
init();
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutTimerFunc(500, TimerFunc, 1);

glutMainLoop();

return 0;
}

Rosario Leonardi
02-18-2011, 02:40 PM
The object lights up, but it does not appear to be coming from any direction, the ambient light appears to be the only thing that affects it. What am I doing wrong?
What do you expect from your application?
Did you try to remove the ambient light and check if the object light up? I did, the diffuse component light up the up face of your box. Is this the expected behavior?
Also, the lighting is computed only at per vertex and then interpolated along the polygon, so your specular will not very effective. To have per pixel lighting you need a shader.

Note: When you ask help on a forum remember:
"I have tried this but it don't work, help!" is not a good way to expose your problem. Help us to understand what you want to do, what you expect from your program, what have to tried. Otherwise is quite difficult to answer.

ekelly30
02-18-2011, 11:06 PM
Ah, my apologies.

I expected there to be some shading at least. If I positioned the light source above the box, or to the rear I expected the front face to be in shadow somewhat. Or at least a different shade to the top of the box. Could it be down to my ambient light being too bright perhaps? Or do I need to use something like GLSL to get it shading properly?

bcthund
02-18-2011, 11:57 PM
I was doing a lot a research into doing lighting in OpenGL and I eventually concluded that I needed to use shaders if I wanted to get any enhanced lighting effects.

If you want to do any decent kinds of shading you will have to use GLSL. You can also do per-fragment shading which is tremendously better than the default per-vertex method.