// OGLDemoView.cpp : implementation of the COGLDemoView class
//
#include "stdafx.h"
#include <math.h>
#include "OGLDemo.h"
#include "OGLDemoDoc.h"
#include "OGLDemoView.h"
#include ".\ogldemoview.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define M_PI 3.14159265358979323846
/////////////////////////////////////////////////////////////////////////////
// COGLDemoView
IMPLEMENT_DYNCREATE(COGLDemoView, CView)
BEGIN_MESSAGE_MAP(COGLDemoView, CView)
//{{AFX_MSG_MAP(COGLDemoView)
ON_WM_SIZE()
ON_WM_ERASEBKGND()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
ON_COMMAND(ID_RENDER_POLYGONOFFSET, OnRenderPolygonoffset)
ON_COMMAND(ID_RENDER_STENCILBUFFER, OnRenderStencilbuffer)
ON_COMMAND(ID_RENDER_STENCILBUFFERWITHDISPLAYLIST, OnRenderStencilbufferwithdisplaylist)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COGLDemoView construction/destruction
COGLDemoView::COGLDemoView()
: m_rtri(0), m_rquad(0), m_bResizing(true), m_listCreated( false ), m_renderType( eRenderPolygon )
{
// TODO: add construction code here
}
COGLDemoView::~COGLDemoView()
{
}
BOOL COGLDemoView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// COGLDemoView drawing
void COGLDemoView::OnDraw(CDC* pDC)
{
COGLDemoDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
m_wgl.Begin(pDC);
if (m_bResizing)
{
CRect rect;
GetClientRect(&rect);
glViewport(0,0, rect.Width(), rect.Height());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(35,rect.Width()/(double)rect.Height(),1,100);
gluLookAt(0,0,0,0,0,-10,0,1,0);
glMatrixMode(GL_MODELVIEW);
}
glDisable( GL_DITHER );
glEnable( GL_DEPTH_TEST );
GLfloat pos[4] = { 3.0f, 5.0f, 2.0f, 1.0f };
GLfloat white[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat black[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
glDisable( GL_LIGHTING );
glEnable( GL_LIGHT1 );
glLightfv( GL_LIGHT1, GL_POSITION, pos );
glLightfv( GL_LIGHT1, GL_DIFFUSE, white );
glLightfv( GL_LIGHT1, GL_SPECULAR, black );
glEnable( GL_COLOR_MATERIAL );
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, black );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if ( !m_listCreated )
CreateDisplayLists();
switch ( m_renderType )
{
case eRenderPolygon:
DrawGLScenePolygonOffset();
break;
case eRenderStencilBuffer:
DrawGLSceneStencil();
break;
case eRenderStencilBufferWithDisplayList:
DrawGLSceneStencilDisplayList();
break;
}
m_wgl.End();
}
/////////////////////////////////////////////////////////////////////////////
// COGLDemoView diagnostics
#ifdef _DEBUG
void COGLDemoView::AssertValid() const
{
CView::AssertValid();
}
void COGLDemoView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
COGLDemoDoc* COGLDemoView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COGLDemoDoc)));
return (COGLDemoDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// COGLDemoView message handlers
int COGLDemoView::DrawGLScenePolygonOffset()
{
glLoadIdentity(); // Reset The View
glTranslatef(-1.5f,0.0f,-6.0); // Move Left And Into The Screen
glRotatef(m_rtri,0.0f,1.0f,0.0f); // Rotate The Pyramid On It's Y Axis
// Render Object 3
glPushAttrib( GL_ALL_ATTRIB_BITS );
glEnable( GL_POLYGON_OFFSET_FILL );
glPolygonOffset( -2.5f, -2.5f );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glLineWidth( 3.0f );
glColor3f( 1.0f, 1.0f, 1.0f );
RenderMesh3();
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glEnable( GL_LIGHTING );
glColor3f( 0.0f, 0.0f, 0.0f );
RenderMesh3();
glPopAttrib();
glLoadIdentity();
glTranslatef(1.5f,0.0f,-7.0f); // Move Right And Into The Screen
glRotatef(m_rquad,1.0f,1.0f,1.0f); // Rotate The Cube On X, Y & Z
// Render Object 2
glPushAttrib( GL_ALL_ATTRIB_BITS );
glEnable( GL_POLYGON_OFFSET_FILL );
glPolygonOffset( -2.5f, -2.5f );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glLineWidth( 3.0f );
glColor3f( 1.0f, 1.0f, 1.0f );
RenderMesh2();
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glEnable( GL_LIGHTING );
glColor3f( 0.0f, 0.0f, 0.0f );
RenderMesh2();
glPopAttrib();
m_rtri+=0.5f; // Increase The Rotation Variable For The Triangle
m_rquad-=0.4f; // Decrease The Rotation Variable For The Quad
return TRUE; // Keep Going
}
int COGLDemoView::DrawGLSceneStencil()
{
glLoadIdentity(); // Reset The View
glTranslatef(-1.5f,0.0f,-6.0); // Move Left And Into The Screen
glRotatef(m_rtri,0.0f,1.0f,0.0f); // Rotate The Pyramid On It's Y Axis
// Render object 3
glPushAttrib( GL_ALL_ATTRIB_BITS );
glEnable( GL_LIGHTING );
glClearStencil(0);
glClear( GL_STENCIL_BUFFER_BIT );
glEnable( GL_STENCIL_TEST );
glStencilFunc( GL_ALWAYS, 1, 0xFFFF );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glColor3f( 0.0f, 0.0f, 0.0f );
RenderMesh3();
glDisable( GL_LIGHTING );
glStencilFunc( GL_NOTEQUAL, 1, 0xFFFF );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
glLineWidth( 3.0f );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glColor3f( 1.0f, 1.0f, 1.0f );
RenderMesh3();
glPopAttrib();
glLoadIdentity();
glTranslatef(1.5f,0.0f,-7.0f); // Move Right And Into The Screen
glRotatef(m_rquad,1.0f,1.0f,1.0f); // Rotate The Cube On X, Y & Z
// Render object 2
glPushAttrib( GL_ALL_ATTRIB_BITS );
glEnable( GL_LIGHTING );
glClearStencil(0);
glClear( GL_STENCIL_BUFFER_BIT );
glEnable( GL_STENCIL_TEST );
glStencilFunc( GL_ALWAYS, 1, -1 );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glColor3f( 0.0f, 0.0f, 0.0f );
RenderMesh2();
glDisable( GL_LIGHTING );
glStencilFunc( GL_NOTEQUAL, 1, -1 );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
glLineWidth( 3.0f );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glColor3f( 1.0f, 1.0f, 1.0f );
RenderMesh2();
glPopAttrib();
m_rtri+=0.5f; // Increase The Rotation Variable For The Triangle
m_rquad-=0.4f; // Decrease The Rotation Variable For The Quad
return TRUE;
}
int COGLDemoView::DrawGLSceneStencilDisplayList()
{
glLoadIdentity(); // Reset The View
glTranslatef(-1.5f,0.0f,-6.0); // Move Left And Into The Screen
glRotatef(m_rtri,0.0f,1.0f,0.0f); // Rotate The Pyramid On It's Y Axis
// Render object 3
glCallList( 1 );
glLoadIdentity();
glTranslatef(1.5f,0.0f,-7.0f); // Move Right And Into The Screen
glRotatef(m_rquad,1.0f,1.0f,1.0f); // Rotate The Cube On X, Y & Z
// Render object 2
glCallList( 2 );
m_rtri+=0.5f; // Increase The Rotation Variable For The Triangle
m_rquad-=0.4f; // Decrease The Rotation Variable For The Quad
return TRUE;
}
int COGLDemoView::CreateDisplayLists()
{
glNewList( 1, GL_COMPILE );
glPushAttrib( GL_ALL_ATTRIB_BITS );
glEnable( GL_LIGHTING );
glClearStencil(0);
glClear( GL_STENCIL_BUFFER_BIT );
glEnable( GL_STENCIL_TEST );
glStencilFunc( GL_ALWAYS, 1, 0xFFFF );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glColor3f( 0.2f, 0.2f, 1.0f );
RenderMesh3();
glDisable( GL_LIGHTING );
glStencilFunc( GL_NOTEQUAL, 1, 0xFFFF );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
glLineWidth( 3.0f );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glColor3f( 1.0f, 1.0f, 1.0f );
RenderMesh3();
glPopAttrib();
glEndList();
glNewList( 2, GL_COMPILE );
glPushAttrib( GL_ALL_ATTRIB_BITS );
glEnable( GL_LIGHTING );
glClearStencil(0);
glClear( GL_STENCIL_BUFFER_BIT );
glEnable( GL_STENCIL_TEST );
glStencilFunc( GL_ALWAYS, 1, -1 );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glColor3f( 0.2f, 0.2f, 1.0f );
RenderMesh2();
glDisable( GL_LIGHTING );
glStencilFunc( GL_NOTEQUAL, 1, -1 );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
glLineWidth( 3.0f );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glColor3f( 1.0f, 1.0f, 1.0f );
RenderMesh2();
glPopAttrib();
glEndList();
m_listCreated = true;
return TRUE;
}
void COGLDemoView::RenderMesh1()
{
glBegin(GL_TRIANGLES); // Start Drawing The Pyramid
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front)
glVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front)
glVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front)
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right)
glVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right)
glVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right)
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back)
glVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back)
glVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back)
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left)
glVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left)
glVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left)
glEnd(); // Done Drawing The Pyramid
}
void COGLDemoView::RenderMesh2()
{
glBegin(GL_QUADS); // Start Drawing The Cube
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Back)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Back)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Back)
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Back)
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
glEnd(); // Done Drawing The Quad
}
void COGLDemoView::RenderMesh3()
{
float radius = 1.0f;
static const int uDensity = 10;
static const int vDensity = 20;
float points[uDensity+1][vDensity+1][3];
for ( int uu = 0; uu <= uDensity; ++uu )
{
for ( int vv = 0; vv <= vDensity; ++vv )
{
float theta = (float) ( M_PI * uu / uDensity );
float phi = (float) ( 2 * M_PI * vv / vDensity );
points[uu][vv][0] = radius * cos( theta );
points[uu][vv][1] = radius * sin( theta ) * cos( phi );
points[uu][vv][2] = radius * sin( theta ) * sin( phi );
}
}
glBegin( GL_TRIANGLES );
for ( int ii = 0; ii < uDensity; ++ii )
{
for ( int jj = 0; jj < vDensity; ++jj )
{
glNormal3f( points[ii][jj][0], points[ii][jj][1], points[ii][jj][2] );
glVertex3f( points[ii][jj][0], points[ii][jj][1], points[ii][jj][2] );
glNormal3f( points[ii][jj+1][0], points[ii][jj+1][1], points[ii][jj+1][2] );
glVertex3f( points[ii][jj+1][0], points[ii][jj+1][1], points[ii][jj+1][2] );
glNormal3f( points[ii+1][jj][0], points[ii+1][jj][1], points[ii+1][jj][2] );
glVertex3f( points[ii+1][jj][0], points[ii+1][jj][1], points[ii+1][jj][2] );
glNormal3f( points[ii][jj+1][0], points[ii][jj+1][1], points[ii][jj+1][2] );
glVertex3f( points[ii][jj+1][0], points[ii][jj+1][1], points[ii][jj+1][2] );
glNormal3f( points[ii+1][jj][0], points[ii+1][jj][1], points[ii+1][jj][2] );
glVertex3f( points[ii+1][jj][0], points[ii+1][jj][1], points[ii+1][jj][2] );
glNormal3f( points[ii+1][jj+1][0], points[ii+1][jj+1][1], points[ii+1][jj+1][2] );
glVertex3f( points[ii+1][jj+1][0], points[ii+1][jj+1][1], points[ii+1][jj+1][2] );
}
}
glEnd();
}
void COGLDemoView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
m_bResizing = true;
}
void COGLDemoView::OnInitialUpdate()
{
CView::OnInitialUpdate();
CClientDC dc(this);
m_wgl.Begin(&dc);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
m_wgl.End();
((COGLDemoApp*)AfxGetApp())->m_pIdleView = this;
}
BOOL COGLDemoView::OnEraseBkgnd(CDC* pDC)
{
return true;
}
void COGLDemoView::OnDestroy()
{
CView::OnDestroy();
((COGLDemoApp*)AfxGetApp())->m_pIdleView = NULL;
}
void COGLDemoView::OnRenderPolygonoffset()
{
m_renderType = eRenderPolygon;
}
void COGLDemoView::OnRenderStencilbuffer()
{
m_renderType = eRenderStencilBuffer;
}
void COGLDemoView::OnRenderStencilbufferwithdisplaylist()
{
m_renderType = eRenderStencilBufferWithDisplayList;
}