PDA

View Full Version : Lighting Problem



aanthonyz
05-16-2012, 02:06 PM
Hello, I have a problem, I can't properly view my model that I have loaded, I dont know if it is the lighting or what the problem may be. I have attached the .OBJ file that im using

#include <allegro.h>
#include <alleggl.h>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <cmath>

/************************************************** *************************
OBJ Loading
************************************************** *************************/

class Model_OBJ
{
public:
Model_OBJ();
float* Model_OBJ::calculateNormal(float* coord1,float* coord2,float* coord3 );
int Model_OBJ::Load(char *filename); // Loads the model
void Model_OBJ::Draw(); // Draws the model on the screen
void Model_OBJ::Release(); // Release the model

float* normals; // Stores the normals
float* Faces_Triangles; // Stores the triangles
float* vertexBuffer; // Stores the points which make the object
long TotalConnectedPoints; // Stores the total number of connected verteces
long TotalConnectedTriangles; // Stores the total number of connected triangles

};


#define POINTS_PER_VERTEX 3
#define TOTAL_FLOATS_IN_TRIANGLE 9
using namespace std;

Model_OBJ::Model_OBJ()
{
this->TotalConnectedTriangles = 0;
this->TotalConnectedPoints = 0;
}

float* Model_OBJ::calculateNormal( float *coord1, float *coord2, float *coord3 )
{
/* calculate Vector1 and Vector2 */
float va[3], vb[3], vr[3], val;
va[0] = coord1[0] - coord2[0];
va[1] = coord1[1] - coord2[1];
va[2] = coord1[2] - coord2[2];

vb[0] = coord1[0] - coord3[0];
vb[1] = coord1[1] - coord3[1];
vb[2] = coord1[2] - coord3[2];

/* cross product */
vr[0] = va[1] * vb[2] - vb[1] * va[2];
vr[1] = vb[0] * va[2] - va[0] * vb[2];
vr[2] = va[0] * vb[1] - vb[0] * va[1];

/* normalization factor */
val = sqrt( vr[0]*vr[0] + vr[1]*vr[1] + vr[2]*vr[2] );

float norm[3];
norm[0] = vr[0]/val;
norm[1] = vr[1]/val;
norm[2] = vr[2]/val;


return norm;
}


int Model_OBJ::Load(char* filename)
{
string line;
ifstream objFile (filename);
if (objFile.is_open()) // If obj file is open, continue
{
objFile.seekg (0, ios::end); // Go to end of the file,
long fileSize = objFile.tellg(); // get file size
objFile.seekg (0, ios::beg); // we'll use this to register memory for our 3d model

vertexBuffer = (float*) malloc (fileSize); // Allocate memory for the verteces
Faces_Triangles = (float*) malloc(fileSize*sizeof(float)); // Allocate memory for the triangles
normals = (float*) malloc(fileSize*sizeof(float)); // Allocate memory for the normals

int triangle_index = 0; // Set triangle index to zero
int normal_index = 0; // Set normal index to zero

while (! objFile.eof() ) // Start reading file data
{
getline (objFile,line); // Get line from file

if (line.c_str()[0] == 'v') // The first character is a v: on this line is a vertex stored.
{
line[0] = ' '; // Set first character to 0. This will allow us to use sscanf

sscanf(line.c_str(),"%f %f %f ", // Read floats from the line: v X Y Z
&vertexBuffer[TotalConnectedPoints],
&vertexBuffer[TotalConnectedPoints+1],
&vertexBuffer[TotalConnectedPoints+2]);

TotalConnectedPoints += POINTS_PER_VERTEX; // Add 3 to the total connected points
}
if (line.c_str()[0] == 'f') // The first character is an 'f': on this line is a point stored
{
line[0] = ' '; // Set first character to 0. This will allow us to use sscanf

int vertexNumber[4] = { 0, 0, 0 };
sscanf(line.c_str(),"%i%i%i", // Read integers from the line: f 1 2 3
&vertexNumber[0], // First point of our triangle. This is an
&vertexNumber[1], // pointer to our vertexBuffer list
&vertexNumber[2] ); // each point represents an X,Y,Z.

vertexNumber[0] -= 1; // OBJ file starts counting from 1
vertexNumber[1] -= 1; // OBJ file starts counting from 1
vertexNumber[2] -= 1; // OBJ file starts counting from 1


/************************************************** ******************
* Create triangles (f 1 2 3) from points: (v X Y Z) (v X Y Z) (v X Y Z).
* The vertexBuffer contains all verteces
* The triangles will be created using the verteces we read previously
*/

int tCounter = 0;
for (int i = 0; i < POINTS_PER_VERTEX; i++)
{
Faces_Triangles[triangle_index + tCounter ] = vertexBuffer[3*vertexNumber[i] ];
Faces_Triangles[triangle_index + tCounter +1 ] = vertexBuffer[3*vertexNumber[i]+1 ];
Faces_Triangles[triangle_index + tCounter +2 ] = vertexBuffer[3*vertexNumber[i]+2 ];
tCounter += POINTS_PER_VERTEX;
}

/************************************************** *******************
* Calculate all normals, used for lighting
*/
float coord1[3] = { Faces_Triangles[triangle_index], Faces_Triangles[triangle_index+1],Faces_Triangles[triangle_index+2]};
float coord2[3] = {Faces_Triangles[triangle_index+3],Faces_Triangles[triangle_index+4],Faces_Triangles[triangle_index+5]};
float coord3[3] = {Faces_Triangles[triangle_index+6],Faces_Triangles[triangle_index+7],Faces_Triangles[triangle_index+8]};
float *norm = this->calculateNormal( coord1, coord2, coord3 );

tCounter = 0;
for (int i = 0; i < POINTS_PER_VERTEX; i++)
{
normals[normal_index + tCounter ] = norm[0];
normals[normal_index + tCounter +1] = norm[1];
normals[normal_index + tCounter +2] = norm[2];
tCounter += POINTS_PER_VERTEX;
}

triangle_index += TOTAL_FLOATS_IN_TRIANGLE;
normal_index += TOTAL_FLOATS_IN_TRIANGLE;
TotalConnectedTriangles += TOTAL_FLOATS_IN_TRIANGLE;
}
}
objFile.close(); // Close OBJ file
}
else
{
cout << "Unable to open file";
}
return 0;
}

void Model_OBJ::Release()
{
free(this->Faces_Triangles);
free(this->normals);
free(this->vertexBuffer);
}

void Model_OBJ::Draw()
{
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex arrays
glEnableClientState(GL_NORMAL_ARRAY); // Enable normal arrays
glVertexPointer(3,GL_FLOAT, 0,Faces_Triangles); // Vertex Pointer to triangle array
glNormalPointer(GL_FLOAT, 0, normals); // Normal pointer to normal array
glDrawArrays(GL_TRIANGLES, 0, TotalConnectedTriangles); // Draw the triangles
glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex arrays
glDisableClientState(GL_NORMAL_ARRAY); // Disable normal arrays
}

/************************************************** *************************
* Program code
************************************************** *************************/

Model_OBJ obj;
float g_rotation;

using namespace std;
GLfloat rtri; // Angle For The Triangle ( NEW )
void Init()
{
// Start up Allegro and AllegroGL systems
allegro_init();
install_allegro_gl();
install_keyboard();
install_mouse();

allegro_gl_clear_settings();
// Set some AllegroGL options
allegro_gl_set( AGL_COLOR_DEPTH, 32 );
allegro_gl_set( AGL_Z_DEPTH, 8 );
allegro_gl_set( AGL_SUGGEST, AGL_COLOR_DEPTH | AGL_Z_DEPTH );
// Set up a suitable viewing window
set_color_depth(32);
allegro_message("Passed Initial Color Depth");
set_gfx_mode(GFX_OPENGL_WINDOWED, 800, 600, 0, 0); //GFX_OPENGL_WINDOWED
allegro_message("Passed Initial Window");
// Set the background color to black (R,G,B,A)
glClearColor(0, 0, 0, 0);
}

int main()
{
Init();
obj.Load("untitled.obj");
glMatrixMode(GL_PROJECTION);
glViewport(0, 0, 800, 600);
GLfloat aspect = (GLfloat) 800 / 600;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glShadeModel( GL_SMOOTH );
glClearColor( 0.0f, 0.1f, 0.0f, 0.5f );
glClearDepth( 1.0f );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glEnable( GL_LIGHT0 );
glEnable( GL_COLOR_MATERIAL );
glShadeModel( GL_SMOOTH );
glDepthFunc( GL_LEQUAL );
glEnable( GL_DEPTH_TEST );
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
while(!key[KEY_ESC])
{
// Clear the screen
// Clear the screen and depth buffer:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
glRotatef(g_rotation,0,1,0);
glRotatef(90,0,1,0);
g_rotation++;
obj.Draw();
glPopMatrix();
// Flush the rendering pipeline:
glFlush();

// Flip the backbuffer to the Allegro screen:
allegro_gl_flip();

}

return 0;
}
END_OF_MAIN();

BionicBytes
05-17-2012, 01:00 AM
You seem to have a number of issues here.
Firstly, forget OBJ model reading and lighting.
Ask your self these basic questions first:
1. Is the application able to display even a simple quad.
2. Is the simple quad able to be lit properly.
If the answer to the above is No and No, then you must fix the application first!

For your OBJ you have a fundamental issue. I don't think you have ever got this working before have you?
The reason is that you have misinterpreted the meaning of the 'f' command, eg "f /1/3/4"
This does not mean vertex index 1,3 & 4 but refers to the shared vertex list at index 1; the shared texture coord at index 3 and the shared normal at index 4.
So f 1/3/4 is representing f v/t/n where v,t&n are indexes to your buffers.
So this code is wrong:


if (line.c_str()[0] == 'f') // The first character is an 'f': on this line is a point stored
{
line[0] = ' '; // Set first character to 0. This will allow us to use sscanf

int vertexNumber[4] = { 0, 0, 0 };
sscanf(line.c_str(),"%i%i%i", // Read integers from the line: f 1 2 3
&vertexNumber[0], // First point of our triangle. This is an
&vertexNumber[1], // pointer to our vertexBuffer list
&vertexNumber[2] ); // each point represents an X,Y,Z.

vertexNumber[0] -= 1; // OBJ file starts counting from 1
vertexNumber[1] -= 1; // OBJ file starts counting from 1
vertexNumber[2] -= 1; // OBJ file starts counting from 1

and vertexNumber[1] and vertexNumber[2] don't point to vertex Y and Vertex Z but to the ith Texture Coord and the ith Normal.

As for your application, there are mistakes in the setting up of the Projection matrix.


glMatrixMode(GL_PROJECTION);
glViewport(0, 0, 800, 600);
GLfloat aspect = (GLfloat) 800 / 600;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

Can you see, you have reset the projection matrix back to identity!
As for lighting, well you have not called glLightfv (lightPoisition) after setting up the ModelView matrix.

aanthonyz
05-17-2012, 04:05 AM
I will try to correct the problem. I can properly display a Quad and the .OBJ file does work but I havent worked on the lighting so i think thats where the problem may be but im still gonna fix the .OBJ loader.

aanthonyz
05-17-2012, 03:02 PM
Ok. I have tried what you said and this is what I get
730
Here is my updated code:

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

#include <windows.h>
#include <windowsx.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <cmath>

#define VK_Q 0x51
#define VK_E 0x45

float g_rotation;//angle of rotation
float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0;
int xPosg, yPosg;
int lastx,lasty;




/************************************************** *************************
OBJ Loading
************************************************** *************************/

class Model_OBJ
{
public:
Model_OBJ();
float* Model_OBJ::calculateNormal(float* coord1,float* coord2,float* coord3 );
int Model_OBJ::Load(char *filename); // Loads the model
void Model_OBJ::Draw(); // Draws the model on the screen
void Model_OBJ::Release(); // Release the model

float* normals; // Stores the normals
float* Faces_Triangles; // Stores the triangles
float* vertexBuffer; // Stores the points which make the object
long TotalConnectedPoints; // Stores the total number of connected verteces
long TotalConnectedTriangles; // Stores the total number of connected triangles

};


#define POINTS_PER_VERTEX 3
#define TOTAL_FLOATS_IN_TRIANGLE 9
using namespace std;

Model_OBJ::Model_OBJ()
{
this->TotalConnectedTriangles = 0;
this->TotalConnectedPoints = 0;
}

float* Model_OBJ::calculateNormal( float *coord1, float *coord2, float *coord3 )
{
/* calculate Vector1 and Vector2 */
float va[3], vb[3], vr[3], val;
va[0] = coord1[0] - coord2[0];
va[1] = coord1[1] - coord2[1];
va[2] = coord1[2] - coord2[2];

vb[0] = coord1[0] - coord3[0];
vb[1] = coord1[1] - coord3[1];
vb[2] = coord1[2] - coord3[2];

/* cross product */
vr[0] = va[1] * vb[2] - vb[1] * va[2];
vr[1] = vb[0] * va[2] - va[0] * vb[2];
vr[2] = va[0] * vb[1] - vb[0] * va[1];

/* normalization factor */
val = sqrt( vr[0]*vr[0] + vr[1]*vr[1] + vr[2]*vr[2] );

float norm[3];
norm[0] = vr[0]/val;
norm[1] = vr[1]/val;
norm[2] = vr[2]/val;


return norm;
}


int Model_OBJ::Load(char* filename)
{
string line;
ifstream objFile (filename);
if (objFile.is_open()) // If obj file is open, continue
{
objFile.seekg (0, ios::end); // Go to end of the file,
long fileSize = objFile.tellg(); // get file size
objFile.seekg (0, ios::beg); // we'll use this to register memory for our 3d model

vertexBuffer = (float*) malloc (fileSize); // Allocate memory for the verteces
Faces_Triangles = (float*) malloc(fileSize*sizeof(float)); // Allocate memory for the triangles
normals = (float*) malloc(fileSize*sizeof(float)); // Allocate memory for the normals

int triangle_index = 0; // Set triangle index to zero
int normal_index = 0; // Set normal index to zero

while (! objFile.eof() ) // Start reading file data
{
getline (objFile,line); // Get line from file

if (line.c_str()[0] == 'v') // The first character is a v: on this line is a vertex stored.
{
line[0] = ' '; // Set first character to 0. This will allow us to use sscanf

sscanf(line.c_str(),"%f %f %f ", // Read floats from the line: v X Y Z
&vertexBuffer[TotalConnectedPoints],
&vertexBuffer[TotalConnectedPoints+1],
&vertexBuffer[TotalConnectedPoints+2]);

TotalConnectedPoints += POINTS_PER_VERTEX; // Add 3 to the total connected points
}
if (line.c_str()[0] == 'f') // The first character is an 'f': on this line is a point stored
{
line[0] = ' '; // Set first character to 0. This will allow us to use sscanf

int vertexNumber[4] = { 0, 0, 0 };
sscanf(line.c_str(),"%i%i%i", // Read integers from the line: f 1 2 3
&vertexNumber[0], // First point of our triangle. This is an
&vertexNumber[1], // pointer to our vertexBuffer list
&vertexNumber[2] ); // each point represents an X,Y,Z.

vertexNumber[0] -= 1; // OBJ file starts counting from 1
vertexNumber[1] -= 1; // OBJ file starts counting from 1
vertexNumber[2] -= 1; // OBJ file starts counting from 1


/************************************************** ******************
* Create triangles (f 1 2 3) from points: (v X Y Z) (v X Y Z) (v X Y Z).
* The vertexBuffer contains all verteces
* The triangles will be created using the verteces we read previously
*/

int tCounter = 0;
for (int i = 0; i < POINTS_PER_VERTEX; i++)
{
Faces_Triangles[triangle_index + tCounter ] = vertexBuffer[3*vertexNumber[i] ];
Faces_Triangles[triangle_index + tCounter +1 ] = vertexBuffer[3*vertexNumber[i]+1 ];
Faces_Triangles[triangle_index + tCounter +2 ] = vertexBuffer[3*vertexNumber[i]+2 ];
tCounter += POINTS_PER_VERTEX;
}

/************************************************** *******************
* Calculate all normals, used for lighting
*/
float coord1[3] = { Faces_Triangles[triangle_index], Faces_Triangles[triangle_index+1],Faces_Triangles[triangle_index+2]};
float coord2[3] = {Faces_Triangles[triangle_index+3],Faces_Triangles[triangle_index+4],Faces_Triangles[triangle_index+5]};
float coord3[3] = {Faces_Triangles[triangle_index+6],Faces_Triangles[triangle_index+7],Faces_Triangles[triangle_index+8]};
float *norm = this->calculateNormal( coord1, coord2, coord3 );

tCounter = 0;
for (int i = 0; i < POINTS_PER_VERTEX; i++)
{
normals[normal_index + tCounter ] = norm[0];
normals[normal_index + tCounter +1] = norm[1];
normals[normal_index + tCounter +2] = norm[2];
tCounter += POINTS_PER_VERTEX;
}

triangle_index += TOTAL_FLOATS_IN_TRIANGLE;
normal_index += TOTAL_FLOATS_IN_TRIANGLE;
TotalConnectedTriangles += TOTAL_FLOATS_IN_TRIANGLE;
}
}
objFile.close(); // Close OBJ file
}
else
{
cout << "Unable to open file";
}
return 0;
}

void Model_OBJ::Release()
{
free(this->Faces_Triangles);
free(this->normals);
free(this->vertexBuffer);
}

void Model_OBJ::Draw()
{
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex arrays
glEnableClientState(GL_NORMAL_ARRAY); // Enable normal arrays
glVertexPointer(3,GL_FLOAT, 0,Faces_Triangles); // Vertex Pointer to triangle array
glNormalPointer(GL_FLOAT, 0, normals); // Normal pointer to normal array
glDrawArrays(GL_TRIANGLES, 0, TotalConnectedTriangles); // Draw the triangles
glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex arrays
glDisableClientState(GL_NORMAL_ARRAY); // Disable normal arrays
}
void camera (void) {
glRotatef(xrot,1.0,0.0,0.0); //rotate our camera on teh x-axis (left and right)
glRotatef(yrot,0.0,1.0,0.0); //rotate our camera on the y-axis (up and down)
glTranslated(-xpos,-ypos,-zpos); //translate the screen to the position of our camera
}
void mouseMovement(int x, int y) {
int diffx=x-lastx; //check the difference between the current x and the last x position
int diffy=y-lasty; //check the difference between the current y and the last y position
lastx=x; //set lastx to the current x position
lasty=y; //set lasty to the current y position
xrot += (float) diffy; //set the xrot to xrot with the addition of the difference in the y position
yrot += (float) diffx;// set the xrot to yrot with the addition of the difference in the x position
}

/************************************************** *************************
* Program code
************************************************** *************************/

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);
Model_OBJ obj;
long nScreenWidth = ::GetSystemMetrics(SM_CXSCREEN);
long nScreenHeight = ::GetSystemMetrics(SM_CYSCREEN);
float Textwidth = nScreenWidth/3;
float Textheight = nScreenWidth;
float PicWidth = nScreenWidth - Textwidth;
/**************************
* WinMain
*
**************************/

int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int iCmdShow)
{
WNDCLASS wc;
HWND hWnd;
HDC hDC;
HGLRC hRC;
MSG msg;
BOOL bQuit = FALSE;
/* 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 = "Calculus";
RegisterClass (&wc);

/* create main window */
hWnd = CreateWindow ("Calculus", "Calculus Project", WS_CAPTION | WS_MAXIMIZE | WS_VISIBLE,0, 0, nScreenWidth, nScreenHeight,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 */
glMatrixMode(GL_PROJECTION);
glViewport(0, 0, nScreenWidth, nScreenHeight);//glViewport(0, 0, PicWidth, nScreenHeight);
GLfloat aspect = (GLfloat) nScreenWidth / nScreenHeight;//GLfloat aspect = (GLfloat) nScreenWidth / nScreenHeight;

glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClearDepth( 1.0f );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glEnable(GL_LIGHTING);
glEnable( GL_LIGHT0 );
GLfloat light_pos[4] = {1,0,0,1};
GLfloat light_pos2[4] = {0,0,1,0};
glEnable( GL_COLOR_MATERIAL);
glLightfv(GL_LIGHT0,GL_AMBIENT,light_pos);
glLightfv(GL_POSITION, GL_LIGHT0,light_pos2);
glShadeModel( GL_SMOOTH );
glDepthFunc( GL_LEQUAL );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
camera();
glPushMatrix();
if(GetAsyncKeyState(VK_Q))
{
zpos = zpos+.02;
}
if(GetAsyncKeyState(VK_E))
{
zpos = zpos-.02;
}
if(GetAsyncKeyState(VK_UP))
{
ypos = ypos-.02;
}
if(GetAsyncKeyState(VK_DOWN))
{
ypos = ypos+.02;
}
if(GetAsyncKeyState(VK_LEFT))
{
xpos = xpos+.02;
}
if(GetAsyncKeyState(VK_RIGHT))
{
xpos = xpos-.02;
}
mouseMovement(xPosg,yPosg);
glRotatef(g_rotation,99,1,0);
glRotatef(90,0,1,0);
g_rotation=g_rotation+0.5;
obj.Draw();
glPopMatrix();
// Flush the rendering pipeline:
glFlush();
SwapBuffers (hDC);
Sleep(10);
}
}

/* 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_MOUSEMOVE:
int xPos,yPos;
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
//This is where coords should change to openGL coords
xPosg = xPos;
yPosg = yPos;
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);
obj.Load("untitled2.obj");
/* create and enable the render context (RC) */
*hRC = wglCreateContext( *hDC );
wglMakeCurrent( *hDC, *hRC );

}


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

void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent (NULL, NULL);
wglDeleteContext (hRC);
ReleaseDC (hWnd, hDC);
}


Im still a little bit confused on the .OBJ Loader part that I have to fix but since the major problem that I have is the lighting I want to fix that first.

BionicBytes
05-18-2012, 01:32 AM
Look at the above code you posted carefully. Copy and paste the parts where you have tried to setup the Projection and ModelView matricies into notepad.
You will then see that you have not setup either correctly. You then go on to specify light positions (gllightfv) eventhough you still only have an idenity ModelView matrix. Without a proper projection and/or a model view matrix your scene will not be setup properly for rendering or lighting.
hint- look at this:

glMatrixMode(GL_PROJECTION);
glViewport(0, 0, nScreenWidth, nScreenHeight);//glViewport(0, 0, PicWidth, nScreenHeight);
GLfloat aspect = (GLfloat) nScreenWidth / nScreenHeight;//GLfloat aspect = (GLfloat) nScreenWidth / nScreenHeight;

glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );

Can you tell me what's going on here?

aanthonyz
05-18-2012, 09:09 AM
Here is the updated code but still nothing. I have been looking everywhere for an example but i cant seem to find any. What should I do now?

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

#include <windows.h>
#include <windowsx.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <cmath>

#define VK_Q 0x51
#define VK_E 0x45

float g_rotation;//angle of rotation
float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0;
int xPosg, yPosg;
int lastx,lasty;




/************************************************** *************************
OBJ Loading
************************************************** *************************/

class Model_OBJ
{
public:
Model_OBJ();
float* Model_OBJ::calculateNormal(float* coord1,float* coord2,float* coord3 );
int Model_OBJ::Load(char *filename); // Loads the model
void Model_OBJ::Draw(); // Draws the model on the screen
void Model_OBJ::Release(); // Release the model

float* normals; // Stores the normals
float* Faces_Triangles; // Stores the triangles
float* vertexBuffer; // Stores the points which make the object
long TotalConnectedPoints; // Stores the total number of connected verteces
long TotalConnectedTriangles; // Stores the total number of connected triangles

};


#define POINTS_PER_VERTEX 3
#define TOTAL_FLOATS_IN_TRIANGLE 9
using namespace std;

Model_OBJ::Model_OBJ()
{
this->TotalConnectedTriangles = 0;
this->TotalConnectedPoints = 0;
}

float* Model_OBJ::calculateNormal( float *coord1, float *coord2, float *coord3 )
{
/* calculate Vector1 and Vector2 */
float va[3], vb[3], vr[3], val;
va[0] = coord1[0] - coord2[0];
va[1] = coord1[1] - coord2[1];
va[2] = coord1[2] - coord2[2];

vb[0] = coord1[0] - coord3[0];
vb[1] = coord1[1] - coord3[1];
vb[2] = coord1[2] - coord3[2];

/* cross product */
vr[0] = va[1] * vb[2] - vb[1] * va[2];
vr[1] = vb[0] * va[2] - va[0] * vb[2];
vr[2] = va[0] * vb[1] - vb[0] * va[1];

/* normalization factor */
val = sqrt( vr[0]*vr[0] + vr[1]*vr[1] + vr[2]*vr[2] );

float norm[3];
norm[0] = vr[0]/val;
norm[1] = vr[1]/val;
norm[2] = vr[2]/val;


return norm;
}


int Model_OBJ::Load(char* filename)
{
string line;
ifstream objFile (filename);
if (objFile.is_open()) // If obj file is open, continue
{
objFile.seekg (0, ios::end); // Go to end of the file,
long fileSize = objFile.tellg(); // get file size
objFile.seekg (0, ios::beg); // we'll use this to register memory for our 3d model

vertexBuffer = (float*) malloc (fileSize); // Allocate memory for the verteces
Faces_Triangles = (float*) malloc(fileSize*sizeof(float)); // Allocate memory for the triangles
normals = (float*) malloc(fileSize*sizeof(float)); // Allocate memory for the normals

int triangle_index = 0; // Set triangle index to zero
int normal_index = 0; // Set normal index to zero

while (! objFile.eof() ) // Start reading file data
{
getline (objFile,line); // Get line from file

if (line.c_str()[0] == 'v') // The first character is a v: on this line is a vertex stored.
{
line[0] = ' '; // Set first character to 0. This will allow us to use sscanf

sscanf(line.c_str(),"%f %f %f ", // Read floats from the line: v X Y Z
&vertexBuffer[TotalConnectedPoints],
&vertexBuffer[TotalConnectedPoints+1],
&vertexBuffer[TotalConnectedPoints+2]);

TotalConnectedPoints += POINTS_PER_VERTEX; // Add 3 to the total connected points
}
if (line.c_str()[0] == 'f') // The first character is an 'f': on this line is a point stored
{
line[0] = ' '; // Set first character to 0. This will allow us to use sscanf

int vertexNumber[4] = { 0, 0, 0 };
sscanf(line.c_str(),"%i%i%i", // Read integers from the line: f 1 2 3
&vertexNumber[0], // First point of our triangle. This is an
&vertexNumber[1], // pointer to our vertexBuffer list
&vertexNumber[2] ); // each point represents an X,Y,Z.

vertexNumber[0] -= 1; // OBJ file starts counting from 1
vertexNumber[1] -= 1; // OBJ file starts counting from 1
vertexNumber[2] -= 1; // OBJ file starts counting from 1


/************************************************** ******************
* Create triangles (f 1 2 3) from points: (v X Y Z) (v X Y Z) (v X Y Z).
* The vertexBuffer contains all verteces
* The triangles will be created using the verteces we read previously
*/

int tCounter = 0;
for (int i = 0; i < POINTS_PER_VERTEX; i++)
{
Faces_Triangles[triangle_index + tCounter ] = vertexBuffer[3*vertexNumber[i] ];
Faces_Triangles[triangle_index + tCounter +1 ] = vertexBuffer[3*vertexNumber[i]+1 ];
Faces_Triangles[triangle_index + tCounter +2 ] = vertexBuffer[3*vertexNumber[i]+2 ];
tCounter += POINTS_PER_VERTEX;
}

/************************************************** *******************
* Calculate all normals, used for lighting
*/
float coord1[3] = { Faces_Triangles[triangle_index], Faces_Triangles[triangle_index+1],Faces_Triangles[triangle_index+2]};
float coord2[3] = {Faces_Triangles[triangle_index+3],Faces_Triangles[triangle_index+4],Faces_Triangles[triangle_index+5]};
float coord3[3] = {Faces_Triangles[triangle_index+6],Faces_Triangles[triangle_index+7],Faces_Triangles[triangle_index+8]};
float *norm = this->calculateNormal( coord1, coord2, coord3 );

tCounter = 0;
for (int i = 0; i < POINTS_PER_VERTEX; i++)
{
normals[normal_index + tCounter ] = norm[0];
normals[normal_index + tCounter +1] = norm[1];
normals[normal_index + tCounter +2] = norm[2];
tCounter += POINTS_PER_VERTEX;
}

triangle_index += TOTAL_FLOATS_IN_TRIANGLE;
normal_index += TOTAL_FLOATS_IN_TRIANGLE;
TotalConnectedTriangles += TOTAL_FLOATS_IN_TRIANGLE;
}
}
objFile.close(); // Close OBJ file
}
else
{
cout << "Unable to open file";
}
return 0;
}

void Model_OBJ::Release()
{
free(this->Faces_Triangles);
free(this->normals);
free(this->vertexBuffer);
}

void Model_OBJ::Draw()
{
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex arrays
glEnableClientState(GL_NORMAL_ARRAY); // Enable normal arrays
glVertexPointer(3,GL_FLOAT, 0,Faces_Triangles); // Vertex Pointer to triangle array
glNormalPointer(GL_FLOAT, 0, normals); // Normal pointer to normal array
glDrawArrays(GL_TRIANGLES, 0, TotalConnectedTriangles); // Draw the triangles
glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex arrays
glDisableClientState(GL_NORMAL_ARRAY); // Disable normal arrays
}
void camera (void) {
glRotatef(xrot,1.0,0.0,0.0); //rotate our camera on teh x-axis (left and right)
glRotatef(yrot,0.0,1.0,0.0); //rotate our camera on the y-axis (up and down)
glTranslated(-xpos,-ypos,-zpos); //translate the screen to the position of our camera

}
void mouseMovement(int x, int y) {
int diffx=x-lastx; //check the difference between the current x and the last x position
int diffy=y-lasty; //check the difference between the current y and the last y position
lastx=x; //set lastx to the current x position
lasty=y; //set lasty to the current y position
xrot += (float) diffy; //set the xrot to xrot with the addition of the difference in the y position
yrot += (float) diffx;// set the xrot to yrot with the addition of the difference in the x position
}
/************************************************** *************************
* Program code
************************************************** *************************/

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);
Model_OBJ obj;
long nScreenWidth = ::GetSystemMetrics(SM_CXSCREEN);
long nScreenHeight = ::GetSystemMetrics(SM_CYSCREEN);
float Textwidth = nScreenWidth/3;
float Textheight = nScreenWidth;
float PicWidth = nScreenWidth - Textwidth;
GLfloat redDiffuseMaterial[] = {1.0, 0.0, 0.0}; //set the material to red
GLfloat whiteSpecularMaterial[] = {1.0, 1.0, 1.0}; //set the material to white
GLfloat greenEmissiveMaterial[] = {0.0, 1.0, 0.0}; //set the material to green
GLfloat whiteSpecularLight[] = {1.0, 1.0, 1.0}; //set the light specular to white
GLfloat blackAmbientLight[] = {0.0, 0.0, 0.0}; //set the light ambient to black
GLfloat whiteDiffuseLight[] = {1.0, 1.0, 1.0}; //set the diffuse light to white
GLfloat blankMaterial[] = {0.0, 0.0, 0.0}; //set the diffuselight to white
GLfloat mShininess[] = {128}; //set the shininess of the material


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

int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int iCmdShow)
{
WNDCLASS wc;
HWND hWnd;
HDC hDC;
HGLRC hRC;
MSG msg;
BOOL bQuit = FALSE;
/* 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 = "Calculus";
RegisterClass (&wc);
hWnd = CreateWindow ("Calculus", "Calculus Project", WS_CAPTION | WS_MAXIMIZE | WS_VISIBLE,0, 0, nScreenWidth, nScreenHeight,NULL, NULL, hInstance, NULL);
EnableOpenGL (hWnd, &hDC, &hRC);

glEnable( GL_DEPTH_TEST );
glEnable(GL_LIGHTING);
glEnable( GL_LIGHT0 );
glEnable(GL_COLOR_MATERIAL);

/* program main loop */
while (!bQuit)
{
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
else
{
/* OpenGL animation code goes here */
glViewport(0, 0, nScreenWidth, nScreenHeight);//glViewport(0, 0, PicWidth, nScreenHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat aspect = (GLfloat) nScreenWidth / nScreenHeight;
glTranslatef(0.0f, 0.0f, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glClearDepth( 1.0f );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_SPECULAR, whiteSpecularLight);
glLightfv(GL_LIGHT0, GL_AMBIENT, blackAmbientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteDiffuseLight);
glMaterialfv(GL_FRONT, GL_DIFFUSE, redDiffuseMaterial);
camera();

if(GetAsyncKeyState(VK_UP))
{
ypos = ypos-.02;
}
if(GetAsyncKeyState(VK_DOWN))
{
ypos = ypos+.02;
}
if(GetAsyncKeyState(VK_LEFT))
{
xpos = xpos+.02;
}
if(GetAsyncKeyState(VK_RIGHT))
{
xpos = xpos-.02;
}
mouseMovement(xPosg,yPosg);
glScaled(.5,.5,.5);
obj.Draw();
glPopMatrix();
glFlush();
SwapBuffers (hDC);
Sleep(10);
}
}
DisableOpenGL (hWnd, hDC, hRC);
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_MOUSEMOVE:
int xPos,yPos;
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
xPosg = xPos;
yPosg = yPos;
return 0;

case WM_KEYDOWN:
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;

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

void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
*hDC = GetDC (hWnd);
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);
obj.Load("Example.obj");
*hRC = wglCreateContext( *hDC );
wglMakeCurrent( *hDC, *hRC );

}

void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent (NULL, NULL);
wglDeleteContext (hRC);
ReleaseDC (hWnd, hDC);
}

BionicBytes
05-19-2012, 06:51 AM
Look you still have serious issues with the code here; you really need to look at tutorial sites like HeNe to get a grip with setting up the projection and model view matricies.
The code you have written here is just plain wrong and nonsense (bit harsh but true)


glViewport(0, 0, nScreenWidth, nScreenHeight);//glViewport(0, 0, PicWidth, nScreenHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat aspect = (GLfloat) nScreenWidth / nScreenHeight;
glTranslatef(0.0f, 0.0f, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glClearDepth( 1.0f );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_SPECULAR, whiteSpecularLight);
glLightfv(GL_LIGHT0, GL_AMBIENT, blackAmbientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteDiffuseLight);
glMaterialfv(GL_FRONT, GL_DIFFUSE, redDiffuseMaterial);
camera();

You need to do something like
glMatrixMode (GL_PROJECTION);
glLoadIdentity;
gluPerspective (..... )
glMatrixMode (GL_MODELVIEW);
glLoadIdentity;
camera;

instead you have PushMatrix with no corresponding popmatrix, a perspective projection which is Identity and still not calling glLightfv (specifying position) after setting the camera.