// *** LIGHTING--lit, shaded cube or sphere ***
// Lighting03View.cpp : implementation of the CLighting03View class
//
#include "stdafx.h"
#include "Lighting03.h"
#include "Lighting03Doc.h"
#include "Lighting03View.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include <math.h>
#include <gl\glaux.h>
/////////////////////////////////////////////////////////////////////////////
// CLighting03View
IMPLEMENT_DYNCREATE(CLighting03View, CView)
BEGIN_MESSAGE_MAP(CLighting03View, CView)
//{{AFX_MSG_MAP(CLighting03View)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_COMMAND(ID_OBJECT_CUBE, OnObjectCube)
ON_COMMAND(ID_OBJECT_SPHERE, OnObjectSphere)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLighting03View construction/destruction
CLighting03View::CLighting03View()
{
// TODO: add construction code here
// Lighting and material properties
m_currentObject = Sphere;
m_materialAmbient[0] = 1.0f;
m_materialAmbient[1] = 0.0f;
m_materialAmbient[2] = 0.0f;
m_materialAmbient[3] = 1.0f;
m_materialSpecular[0] = 1.0f;
m_materialSpecular[1] = 1.0f;
m_materialSpecular[2] = 1.0f;
m_materialSpecular[3] = 1.0f;
m_materialEmitted[0] = 0.0f;
m_materialEmitted[1] = 0.0f;
m_materialEmitted[2] = 0.0f;
m_materialEmitted[3] = 1.0f;
m_ambientLight0[0] = 0.2f;
m_ambientLight0[1] = 0.2f;
m_ambientLight0[2] = 0.2f;
m_ambientLight0[3] = 1.0f;
m_diffuseLight0[0] = 1.0f;
m_diffuseLight0[1] = 1.0f;
m_diffuseLight0[2] = 1.0f;
m_diffuseLight0[3] = 1.0f;
m_specularLight0[0] = 1.0f;
m_specularLight0[1] = 1.0f;
m_specularLight0[2] = 1.0f;
m_specularLight0[3] = 1.0f;
m_positionLight0[0] = 1.0f;
m_positionLight0[1] = 1.0f;
m_positionLight0[2] = 1.0f;
m_positionLight0[3] = 1.0f;
m_shininess = 20.0f;
}
CLighting03View::~CLighting03View()
{
}
BOOL CLighting03View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CLighting03View drawing
void CLighting03View::OnDraw(CDC* pDC)
{
CLighting03Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
wglMakeCurrent(pDC->m_hDC, m_hRC);
DrawWithOpenGL();
wglMakeCurrent(pDC->m_hDC, NULL);
}
/////////////////////////////////////////////////////////////////////////////
// CLighting03View diagnostics
#ifdef _DEBUG
void CLighting03View::AssertValid() const
{
CView::AssertValid();
}
void CLighting03View::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CLighting03Doc* CLighting03View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLighting03Doc)));
return (CLighting03Doc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CLighting03View message handlers
int CLighting03View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // Structure size.
1, // Structure version number.
PFD_DRAW_TO_WINDOW | // Property flags.
PFD_SUPPORT_OPENGL,
PFD_TYPE_RGBA,
24, // 24-bit color.
0, 0, 0, 0, 0, 0, // Not concerned with these.
0, 0, 0, 0, 0, 0, 0, // No alpha or accum buffer.
32, // 32-bit depth buffer.
0, 0, // No stencil or aux buffer.
PFD_MAIN_PLANE, // Main layer type.
0, // Reserved.
0, 0, 0 // Unsupported.
};
CClientDC clientDC(this);
int pixelFormat =
ChoosePixelFormat(clientDC.m_hDC, &pfd);
BOOL success =
SetPixelFormat(clientDC.m_hDC, pixelFormat, &pfd);
DescribePixelFormat(clientDC.m_hDC, pixelFormat,
sizeof(pfd), &pfd);
m_hRC = wglCreateContext(clientDC.m_hDC);
return 0;
}
void CLighting03View::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
wglDeleteContext(m_hRC);
}
void CLighting03View::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
CClientDC clientDC(this);
wglMakeCurrent(clientDC.m_hDC, m_hRC);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 7.0);
glViewport(0, 0, cx, cy);
wglMakeCurrent(NULL, NULL);
}
void CLighting03View::OnObjectCube()
{
// TODO: Add your command handler code here
m_currentObject = Cube;
Invalidate();
}
void CLighting03View::OnObjectSphere()
{
// TODO: Add your command handler code here
m_currentObject = Sphere;
Invalidate();
}
void CLighting03View::DrawWithOpenGL()
{
glShadeModel(GL_SMOOTH); //could be GL_FLAT
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE,
m_materialAmbient);
glMaterialfv(GL_FRONT, GL_SPECULAR, m_materialSpecular);
glMaterialfv(GL_FRONT, GL_EMISSION, m_materialEmitted);
glMaterialf(GL_FRONT, GL_SHININESS, m_shininess);
glLightfv(GL_LIGHT0, GL_AMBIENT, m_ambientLight0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, m_diffuseLight0);
glLightfv(GL_LIGHT0, GL_SPECULAR, m_specularLight0);
glLightfv(GL_LIGHT0, GL_POSITION, m_positionLight0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
if (m_currentObject == Cube)
DrawCube();
else
DrawSphere();
glFlush();
}
void CLighting03View::DrawCube()
{
glTranslatef(0.0f, 0.0f, -3.5f);
glRotatef(30.0f, -1.0f, 1.0f, 0.0f);
glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
double p1[] = {-0.5, 0.5, 0.5};
double p2[] = {-0.5, -0.5, 0.5};
double p3[] = {0.5, -0.5, 0.5};
double n[3];
CalcNormal(p1, p2, p3, n);
glBegin(GL_POLYGON);
glNormal3f((GLfloat)n[0], (GLfloat)n[1], (GLfloat)n[2]);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(0.5f, -0.5f, 0.5f);
glVertex3f(0.5f, 0.5f, 0.5f);
glEnd();
p1[0] = 0.5; p1[1] = 0.5; p1[2] = 0.5;
p2[0] = 0.5, p2[1] = -0.5; p2[2] = 0.5;
p3[0] = 0.5; p3[1] = -0.5; p3[2] = -0.5;
CalcNormal(p1, p2, p3, n);
glBegin(GL_POLYGON);
glNormal3f((GLfloat)n[0], (GLfloat)n[1], (GLfloat)n[2]);
glVertex3f(0.5f, 0.5f, 0.5f);
glVertex3f(0.5f, -0.5f, 0.5f);
glVertex3f(0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, 0.5f, -0.5f);
glEnd();
p1[0] = 0.5; p1[1] = 0.5; p1[2] = -0.5;
p2[0] = 0.5, p2[1] = -0.5; p2[2] = -0.5;
p3[0] = -0.5; p3[1] = -0.5; p3[2] = -0.5;
CalcNormal(p1, p2, p3, n);
glBegin(GL_POLYGON);
glNormal3f((GLfloat)n[0], (GLfloat)n[1], (GLfloat)n[2]);
glVertex3f(0.5f, 0.5f, -0.5f);
glVertex3f(0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glEnd();
p1[0] = -0.5; p1[1] = 0.5; p1[2] = -0.5;
p2[0] = -0.5, p2[1] = -0.5; p2[2] = -0.5;
p3[0] = -0.5; p3[1] = -0.5; p3[2] = 0.5;
CalcNormal(p1, p2, p3, n);
glBegin(GL_POLYGON);
glNormal3f((GLfloat)n[0], (GLfloat)n[1], (GLfloat)n[2]);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glEnd();
p1[0] = -0.5; p1[1] = -0.5; p1[2] = 0.5;
p2[0] = -0.5, p2[1] = -0.5; p2[2] = -0.5;
p3[0] = 0.5; p3[1] = -0.5; p3[2] = -0.5;
CalcNormal(p1, p2, p3, n);
glBegin(GL_POLYGON);
glNormal3f((GLfloat)n[0], (GLfloat)n[1], (GLfloat)n[2]);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, -0.5f, 0.5f);
glEnd();
p1[0] = -0.5; p1[1] = 0.5; p1[2] = -0.5;
p2[0] = -0.5, p2[1] = 0.5; p2[2] = 0.5;
p3[0] = 0.5; p3[1] = 0.5; p3[2] = 0.5;
CalcNormal(p1, p2, p3, n);
glBegin(GL_POLYGON);
glNormal3f((GLfloat)n[0], (GLfloat)n[1], (GLfloat)n[2]);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(0.5f, 0.5f, 0.5f);
glVertex3f(0.5f, 0.5f, -0.5f);
glEnd();
}
void CLighting03View::DrawSphere()
{
glTranslatef(0.0f, 0.0f, -3.5f);
glScalef(1.0,1.5,1.0);
GLUquadricObj *mySphere;
mySphere=gluNewQuadric();
gluQuadricDrawStyle(mySphere,GLU_FILL);
gluSphere(mySphere,1.0,12,12);
}
void CLighting03View::CalcNormal(double *p1, double *p2, double *p3, double *n)
{
// Form two vectors from the points.
double a[3], b[3];
a[0] = p2[0] - p1[0];
a[1] = p2[1] - p1[1];
a[2] = p2[2] - p1[2];
b[0] = p3[0] - p1[0];
b[1] = p3[1] - p1[1];
b[2] = p3[2] - p1[2];
// Calculate the cross product of the two vectors.
n[0] = a[1] * b[2] - a[2] * b[1];
n[1] = a[2] * b[0] - a[0] * b[2];
n[2] = a[0] * b[1] - a[1] * b[0];
// Normalize the new vector.
double length = sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
if (length != 0)
{
n[0] = n[0] / length;
n[1] = n[1] / length;
n[2] = n[2] / length;
}
}