Below is the implementation of my MFC based simple test.it draws a simple pinocchio(an Anim8or model) and a textured cube.But wait…Where are the lights? Its too dark isnt it? Whats going wrong?
Thanks for your interest guys. \ )K
// GLTest1View.cpp : implementation of the CGLTest1View class
//
#include “stdafx.h”
#include “GLTest1.h”
#include “GLTest1Doc.h”
#include “GLTest1View.h”
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = FILE;
#endif
extern Anim8orObject object_pinokyo;
#define PINOKYO 1
/////////////////////////////////////////////////////////////////////////////
// CGLTest1View
IMPLEMENT_DYNCREATE(CGLTest1View, CView)
BEGIN_MESSAGE_MAP(CGLTest1View, CView)
//{{AFX_MSG_MAP(CGLTest1View)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_WM_KEYDOWN()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_KEYUP()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGLTest1View construction/destruction
CGLTest1View::CGLTest1View()
{
// TODO: add construction code here
// Set the glOrtho() X range
m_glX1 = -5.0; m_glX2 = 5.0;
// Set the glOrtho() Y range
m_glY1 = -5.0; m_glY2 = 5.0;
// Set the glOrtho() Z range
m_glZ1 = -10.0; m_glZ2 = 10.0;
m_xrot = m_yrot = m_zrot = 0;
m_active = true;
m_Status = false;
}
CGLTest1View::~CGLTest1View()
{
}
BOOL CGLTest1View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style |= ( WS_CLIPCHILDREN |
WS_CLIPSIBLINGS | CS_OWNDC );
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CGLTest1View drawing
void CGLTest1View::OnDraw(CDC* pDC)
{
CGLTest1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
RenderScene(pDC);
}
/////////////////////////////////////////////////////////////////////////////
// CGLTest1View printing
BOOL CGLTest1View::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CGLTest1View::OnBeginPrinting(CDC* /pDC/, CPrintInfo* /pInfo/)
{
// TODO: add extra initialization before printing
}
void CGLTest1View::OnEndPrinting(CDC* /pDC/, CPrintInfo* /pInfo/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CGLTest1View diagnostics
#ifdef _DEBUG
void CGLTest1View::AssertValid() const
{
CView::AssertValid();
}
void CGLTest1View: ump(CDumpContext& dc) const
{
CView: ump(dc);
}
CGLTest1Doc* CGLTest1View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGLTest1Doc)));
return (CGLTest1Doc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CGLTest1View message handlers
int CGLTest1View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER,
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer (depth)
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
CClientDC dc(this);
m_hDC = dc.m_hDC;
// Get the best available match of pixel format for the device context
// In other words, if this computer doesn't support features that I
// asked for, try to get the next best thing. i.e. 16-bit color mode
// instead of 24-bit color mode.
int pixelFormat = ChoosePixelFormat(m_hDC, &pfd);
// Set the pixel format to the best pixel format I can get (see above)
// and if that operation fails, bring up a message box that tells the
// user the error.
if (!SetPixelFormat(m_hDC, pixelFormat, &pfd))
{
MessageBox("Error: Unable to Set Pixel Format in CGLTemplate1View::OnCreate()",
"Application Error", MB_ICONERROR);
}
// Creates an OpenGL rendering context so that OpenGL knows how to draw
// to this view. You can't use OpenGL in MFC without using the handle
// that this function returns
m_hRC = wglCreateContext(m_hDC);
//////////////////////////////////////////////////////
// END: Stuff I put here myself
//////////////////////////////////////////////////////
wglMakeCurrent(m_hDC, m_hRC);
return 0;
}
void CGLTest1View::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
// Release OpenGL resources
// WARNING: Memory / Resource leaks could occur
// if you don't do this
wglDeleteContext(m_hRC);
}
void CGLTest1View::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
//////////////////////////////////////////////////////
// BEGIN: Stuff I put here myself
//////////////////////////////////////////////////////
// Set up the OpenGL viewing area so that
// it is the same size as the MFC client area
CClientDC dc(this);
// Tell Windows that you want to work with this view
// in OpenGL mode
wglMakeCurrent(dc.m_hDC, m_hRC);
// Set the matrix mode to GL_PROJECTION so that
// the viewing details can be taken care of
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(m_glX1, m_glX2, m_glY1, m_glY2, m_glZ1, m_glZ2);
glViewport(0, 0, cx, cy);
// Set the matrix mode to GL_MODELVIEW so that
// the modeling can be done
glMatrixMode(GL_MODELVIEW);
wglMakeCurrent(NULL, NULL);
//////////////////////////////////////////////////////
// END: Stuff I put here myself
//////////////////////////////////////////////////////
}
void CGLTest1View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if((GetAsyncKeyState( VK_UP ) & 0x8000) == 0x8000)
{ m_xrot-=3.0f; }
if((GetAsyncKeyState( VK_DOWN ) & 0x8000) == 0x8000)
{ m_xrot+=3.0f; }
if((GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000)
{ m_yrot+=3.0f; }
if((GetAsyncKeyState( VK_LEFT ) & 0x8000) == 0x8000)
{ m_yrot-=3.0f; }
CDC* pDC = GetDC();
RenderScene(pDC);
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CGLTest1View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
SetCapture();
CView::OnLButtonDown(nFlags, point);
}
void CGLTest1View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
::ReleaseCapture();
CView::OnMouseMove(nFlags, point);
}
void CGLTest1View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CView::OnLButtonUp(nFlags, point);
}
void CGLTest1View::BuildCircle(int circleid, float radius)
{
int i;
float cosine, sine;
glNewList(circleid, GL_COMPILE);
glBegin(GL_POLYGON);
for(i=0;i<100;i++){
cosine=cos(i2PI/100.0);
sine=sin(i2PI/100.0);
glVertex2f(radiuscosine,radiussine);
}
glEnd();
glEndList();
}
void CGLTest1View::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
CView::OnKeyUp(nChar, nRepCnt, nFlags);
}
AUX_RGBImageRec* CGLTest1View::LoadBMP(char *Filename)
{
FILE *File = NULL;
if(!Filename){return NULL;}
File = fopen(Filename,"r");
if(File)
{
fclose(File);
return auxDIBImageLoad(Filename);
}
else
return NULL;
}
int CGLTest1View::LoadGLTextures(char* FileName)
{
AUX_RGBImageRec *TextureImage[3]; // Create Storage Space For The Texture
memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL
// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
if (TextureImage[0]=LoadBMP(FileName))
{
glGenTextures(4, &m_texture[0]); // Create 3 Textures
// Typical Texture Generation Using Data From The Bitmap
// 1st
glBindTexture(GL_TEXTURE_2D, m_texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
//2nd
glBindTexture(GL_TEXTURE_2D, m_texture[1]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//3rd
TextureImage[1]=LoadBMP("Data/bihull.bmp");
glBindTexture(GL_TEXTURE_2D, m_texture[2]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D,3,TextureImage[1]->sizeX,TextureImage[1]->sizeY,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[1]->data);
//4th with a different texture
TextureImage[2]=LoadBMP("Data/wall.bmp");
glBindTexture(GL_TEXTURE_2D, m_texture[3]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D,3,TextureImage[2]->sizeX,TextureImage[2]->sizeY,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[2]->data);
}
for(int i=0;i<2;i++){
if (TextureImage[i]) // If Texture Exists
{
if (TextureImage[i]->data) // If Texture Image Exists
{
free(TextureImage[i]->data); // Free The Texture Image Memory
}
free(TextureImage[i]); // Free The Image Structure
}
}
return 1;
}
void CGLTest1View::RenderScene(CDC *pDC)
{
// Tell windows that its OpenGL time
wglMakeCurrent(pDC->m_hDC, m_hRC);
//****************************
if(!m_Status){
InitGL();
m_Status=true;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//***************************
glLoadIdentity();
glTranslatef(0.5f,-3.0f,0.0f);
glRotatef(m_xrot,1.0f,0.0f,0.0f);
glRotatef(m_yrot,0.0f,1.0f,0.0f);
glRotatef(m_zrot,0.0f,0.0f,1.0f);
glPushMatrix();
glTranslatef(0.0f,4.0f,0.0f);
glCallList(PINOKYO);
glPopMatrix();
DrawCube();
SwapBuffers(pDC->GetSafeHdc());
// Tell windows that I'm done with OpenGL
wglMakeCurrent(NULL, NULL);
}
void CGLTest1View::InitGL()
{
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glClearColor(0.3, 0.3, 0.3, 0.5);
glClearDepth(4.0);
LIGHT light0 = {
{ 0.4f, 1.0f, 1.0f, 1.0f, },
{ 1.0f, 1.0f, 0.8f, 1.0f, },
{ 1.0f, 0.6f, 0.3f, 1.0f, },
{ 0.5f, 6.0f, 0.0f, 1.0f, },
};
LIGHT light1 = {
{ 0.0f, 0.0f, 0.0f, 1.0f, },
{ 1.0f, 1.0f, 1.0f, 1.0f, },
{ 1.0f, 1.0f, 1.0f, 1.0f, },
{ 0.5f, 3.0f, 2.0f, 0.0f, },
};
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0,GL_AMBIENT,light0.ambient);
glLightfv(GL_LIGHT0,GL_DIFFUSE,light0.diffuse);
glLightfv(GL_LIGHT0,GL_SPECULAR,light0.specular);
glLightfv(GL_LIGHT0, GL_POSITION, light0.position);
glEnable(GL_LIGHT1);
glLightfv(GL_LIGHT1,GL_AMBIENT,light1.ambient);
glLightfv(GL_LIGHT1,GL_DIFFUSE,light1.diffuse);
glLightfv(GL_LIGHT1,GL_SPECULAR,light1.specular);
glLightfv(GL_LIGHT1, GL_POSITION, light1.position);
glEnable(GL_LIGHTING);
LoadObject();
m_GLManager.SetMemoryForTextures(3);
m_GLManager.m_textureFiles[0]="Data/bihull.bmp";
m_GLManager.m_textureFiles[1]="Data/Nehe.bmp";
m_GLManager.m_textureFiles[2]="Data/wall.bmp";
m_GLManager.LoadGLTextures();
}
void CGLTest1View::LoadObject()
{
int g,i, k, index, matno;
float *coords, *normals;
unsigned char *matindices;
Anim8orMesh *fmesh;
glNewList(PINOKYO, GL_COMPILE);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
for (g = 0; g < object_pinokyo.nMeshes ; g++)
{
fmesh=object_pinokyo.meshes[g];
coords = fmesh->coordinates;
normals = fmesh->normals;
matindices = fmesh->matindices;
matno = -1;
for (i = 0, k = 0; i < fmesh->nIndices; i += 3, k++) {
if (matno != matindices[k]) {
if (matno != -1)
glEnd();
matno = matindices[k];
//***************************************
SetMaterial(&fmesh->materials[matno]);
//********************************************
glBegin(GL_TRIANGLES);
}
index = fmesh->indices[i]; //i=0 , i=3
glNormal3fv(&normals[index*3]); //n[0] , n[9]
glVertex3fv(&coords[index*3]); //c[0] , c[9]
index = fmesh->indices[i + 1]; //i=1 , i=4
glNormal3fv(&normals[index*3]); //n[3] , n[12]
glVertex3fv(&coords[index*3]); //c[3] , c[12]
index = fmesh->indices[i + 2]; //i=2 , i=5
glNormal3fv(&normals[index*3]); //n[6] , n[15]
glVertex3fv(&coords[index*3]); //c[6] , c[15]
}
glEnd();
}
glEndList();
}
void CGLTest1View::SetMaterial(Anim8orMaterial *fMat)
{
float ambient[4], diffuse[4], specular[4], emissive[4];
ambient[0] = fMat->ambient[0]*fMat->Ka;
ambient[1] = fMat->ambient[1]*fMat->Ka;
ambient[2] = fMat->ambient[2]*fMat->Ka;
ambient[3] = fMat->ambient[3];
diffuse[0] = fMat->diffuse[0]*fMat->Kd;
diffuse[1] = fMat->diffuse[1]*fMat->Kd;
diffuse[2] = fMat->diffuse[2]*fMat->Kd;
diffuse[3] = fMat->diffuse[3];
specular[0] = fMat->specular[0]*fMat->Ks;
specular[1] = fMat->specular[1]*fMat->Ks;
specular[2] = fMat->specular[2]*fMat->Ks;
specular[3] = fMat->specular[3];
emissive[0] = fMat->emissive[0]*fMat->Ke;
emissive[1] = fMat->emissive[1]*fMat->Ke;
emissive[2] = fMat->emissive[2]*fMat->Ke;
emissive[3] = fMat->emissive[3];
glMaterialfv(GL_FRONT, GL_AMBIENT, &ambient[0]);
glMaterialfv(GL_FRONT, GL_DIFFUSE, &diffuse[0]);
glMaterialfv(GL_FRONT, GL_SPECULAR, &specular[0]);
glMaterialfv(GL_FRONT, GL_EMISSION, &emissive[0]);
glMaterialf(GL_FRONT, GL_SHININESS, fMat->Roughness);
}
void CGLTest1View: rawCube()
{
// Typical Texture Generation Using Data From The Bitmap
if( glIsTexture(m_GLManager.m_textures[0]) )
{ glBindTexture(GL_TEXTURE_2D, m_GLManager.m_textures[0]); }
glBegin(GL_QUADS);
// Front Face
glNormal3f(0.0f,0.0f,1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glNormal3f(0.0f,0.0f,-1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glEnd();
if( glIsTexture(m_GLManager.m_textures[1]) )
{ glBindTexture(GL_TEXTURE_2D, m_GLManager.m_textures[1]); }
glBegin(GL_QUADS);
// Top Face
glNormal3f(0.0f,1.0f,0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
glNormal3f(0.0f,-1.0f,0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();
if( glIsTexture(m_GLManager.m_textures[2]) )
{ glBindTexture(GL_TEXTURE_2D, m_GLManager.m_textures[2]); }
glBegin(GL_QUADS);
// Right face
glNormal3f(1.0f,0.0f,0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glNormal3f(-1.0f,0.0f,0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
}