// RenderDlg.cpp : implementation file
//
#include "stdafx.h"
#include "3D04VC.h"
#include "RenderDlg.h"
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glaux.lib")
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CRenderDlg dialog
CRenderDlg::CRenderDlg(CWnd* pParent /*=NULL*/)
: CDialog(CRenderDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CRenderDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
/************************************************************************/
m_rot = 0;
m_TimerID = -1;
m_bSuspended = TRUE;
m_bQuit = FALSE;
/************************************************************************/
}
void CRenderDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CRenderDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CRenderDlg, CDialog)
//{{AFX_MSG_MAP(CRenderDlg)
ON_WM_DESTROY()
ON_WM_PAINT()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRenderDlg message handlers
BOOL CRenderDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_DC.Attach(::GetDC(*this));
//进行OGL初始化
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), 1 ,PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER
, PFD_TYPE_RGBA, 24, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 32, 0, 0, PFD_MAIN_PLANE, 0, 0, 0
};
int pixelFormat = ChoosePixelFormat(m_DC, &pfd); //返回最匹配的像素格式
BOOL success = SetPixelFormat(m_DC,pixelFormat,&pfd); //设置像素格式
ASSERT(success);
m_TimerGLRC = ::wglCreateContext(m_DC);
::wglMakeCurrent(m_DC, m_TimerGLRC);
InitGL();
DWORD tid;
m_ThreadHandle = ::CreateThread(NULL, 0, ThreadProc, this, 0, &tid);
ASSERT(m_ThreadHandle != NULL);
DoTimer();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
unsigned long CRenderDlg::ThreadProc(void *pData)
{
CRenderDlg* pThis = (CRenderDlg*)pData;
pThis->InitThreadGLCTX();
while (!pThis->m_bQuit) {
if (pThis->m_bSuspended) {
Sleep(1);
} else {
pThis->Invalidate(FALSE);
}
}
::wglDeleteContext(pThis->m_ThreadGLRC);
return 0;
}
void CRenderDlg::InitThreadGLCTX()
{
m_ThreadGLRC = ::wglCreateContext(m_DC);
ASSERT(m_ThreadGLRC!=NULL);
::wglMakeCurrent(m_DC, m_ThreadGLRC);
InitGL();
}
void CRenderDlg::OnDestroy()
{
CDialog::OnDestroy();
m_bQuit = TRUE;
CloseHandle(m_ThreadHandle);
}
void CRenderDlg::Repaint()
{
CRect rt;
GetClientRect(&rt);
glViewport(0,0,rt.Width(), rt.Height());
// Clear the color and depth buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-3, 3, 0, 4, -3, 3);
// Go to the model view matrix mode
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.5, 2, -1);
glRotatef(m_rot, 1.0, 1.0, 1.0); // Rotates around the x and y axis
Drawscene(0.0,0.0,0.0,3.0,1.0);
glFlush();
SwapBuffers(m_DC);
m_rot++;
m_rot %= 360;
}
void CRenderDlg::lft(double x, double y, double z, double l)
{
double x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,x5,y5,z5,x6,y6,z6,x7,y7,z7,x8,y8,z8;
x1=x-l/2;y1=y-l/2;z1=z-l/2;
x2=x+l/2;y2=y-l/2;z2=z-l/2;
x3=x-l/2;y3=y-l/2;z3=z+l/2;
x4=x+l/2;y4=y-l/2;z4=z+l/2;
x5=x-l/2;y5=y+l/2;z5=z+l/2;
x6=x+l/2;y6=y+l/2;z6=z+l/2;
x7=x-l/2;y7=y+l/2;z7=z-l/2;
x8=x+l/2;y8=y+l/2;z8=z-l/2;
glBegin(GL_QUADS);
glColor3f (0.5, 0.5,0.5);
glNormal3f( 0.0, -1.0, 0.0);
glVertex3d(x1,y1,z1);
glVertex3d(x2,y2,z2);
glVertex3d(x4,y4,z4);
glVertex3d(x3,y3,z3);
glColor3f (0.5, 0.0, 1.0);
glNormal3f (0.0, 0.0, 1.0);
glVertex3d(x3,y3,z3);
glVertex3d(x4,y4,z4);
glVertex3d(x6,y6,z6);
glVertex3d(x5,y5,z5);
glColor3f (1.0, 1.0, 1.0);
glNormal3f (0.0, 1.0, 0.0);
glVertex3d(x5,y5,z5);
glVertex3d(x6,y6,z6);
glVertex3d(x8,y8,z8);
glVertex3d(x7,y7,z7);
glColor3f (1.0, 1.0, 0.0);
glNormal3f (0.0, 0.0, -1.0);
glVertex3d(x7,y7,z7);
glVertex3d(x8,y8,z8);
glVertex3d(x2,y2,z2);
glVertex3d(x1,y1,z1);
glColor3f (1.0, 0.0, 1.0);
glNormal3f (-1.0, 0.0, 0.0);
glVertex3d(x1,y1,z1);
glVertex3d(x3,y3,z3);
glVertex3d(x5,y5,z5);
glVertex3d(x7,y7,z7);
glColor3f (1.0, 0.0, 0.5);
glNormal3f (1.0, 0.0, 0.0);
glVertex3d(x2,y2,z2);
glVertex3d(x8,y8,z8);
glVertex3d(x6,y6,z6);
glVertex3d(x4,y4,z4);
glEnd();
}
void CRenderDlg::Drawscene(double x, double y, double z, double l,double n)
{
if (n < 1) {
//画立方体
glColor3f (0.5,0.5,1.0);
l=l/3;
lft(x-l,y+l,z-l,l);//后左上
lft(x,y+l,z-l,l);//后中上
lft(x+l,y+l,z-l,l);//后右上
lft(x-l,y,z-l,l);//后左中
lft(x+l,y,z-l,l);//后右中
lft(x-l,y-l,z-l,l);//后左下
lft(x,y-l,z-l,l);//后中下
lft(x+l,y-l,z-l,l);//后右下
lft(x-l,y+l,z,l);//中左上
lft(x+l,y+l,z,l);//中右上
lft(x-l,y-l,z,l);//中左下
lft(x+l,y-l,z,l);//中右下
lft(x-l,y+l,z+l,l);//前左上
lft(x,y+l,z+l,l);//前中上
lft(x+l,y+l,z+l,l);//前右上
lft(x-l,y,z+l,l);//前左中
lft(x+l,y,z+l,l);//前右中
lft(x-l,y-l,z+l,l);//前左下
lft(x,y-l,z+l,l);//前中下
lft(x+l,y-l,z+l,l);//前右下
}
else {
l=l/3;
Drawscene(x-l,y+l,z-l,l,n-1);//后左上
Drawscene(x,y+l,z-l,l,n-1); //后中上
Drawscene(x+l,y+l,z-l,l,n-1);//后右上
Drawscene(x-l,y,z-l,l,n-1);//后左中
Drawscene(x+l,y,z-l,l,n-1);//后右中
Drawscene(x-l,y-l,z-l,l,n-1);//后左下
Drawscene(x,y-l,z-l,l,n-1);//后中下
Drawscene(x+l,y-l,z-l,l,n-1);//后右下
Drawscene(x-l,y+l,z,l,n-1);//中左上
Drawscene(x+l,y+l,z,l,n-1);//中右上
Drawscene(x-l,y-l,z,l,n-1);//中左下
Drawscene(x+l,y-l,z,l,n-1);//中右下
Drawscene(x-l,y+l,z+l,l,n-1);//前左上
Drawscene(x,y+l,z+l,l,n-1); //前中上
Drawscene(x+l,y+l,z+l,l,n-1);//前右上
Drawscene(x-l,y,z+l,l,n-1);//前左中
Drawscene(x+l,y,z+l,l,n-1);//前右中
Drawscene(x-l,y-l,z+l,l,n-1);//前左下
Drawscene(x,y-l,z+l,l,n-1);//前中下
Drawscene(x+l,y-l,z+l,l,n-1);//前右下
}
}
void CRenderDlg::InitGL()
{
CRect rt;
GetClientRect(&rt);
glViewport(0,0,rt.Width(), rt.Height());
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
}
void CRenderDlg::OnPaint()
{
CPaintDC dc(this);
Repaint();
}
void CRenderDlg::DoTimer()
{
m_bSuspended = TRUE;
if (m_TimerID == -1) {
SetTimer(10, 100, NULL);
m_TimerID = 10;
}
}
void CRenderDlg::DoThread()
{
m_bSuspended = FALSE;
if (m_TimerID == -1) {
KillTimer(10);
m_TimerID = -1;
}
}
void CRenderDlg::OnTimer(UINT nIDEvent)
{
Invalidate(FALSE);
CDialog::OnTimer(nIDEvent);
}