📄 sceneview.cpp
字号:
// SceneView.cpp : implementation of the CSceneView class
//
#include "stdafx.h"
#include "Scene.h"
#include "SceneDoc.h"
#include "SceneView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "ZBuffer.h"
#include "BRender.h"
#include "TypedStack.h"
#include "Lighting.h"
/////////////////////////////////////////////////////////////////////////////
// CSceneView
IMPLEMENT_DYNCREATE(CSceneView, CView)
BEGIN_MESSAGE_MAP(CSceneView, CView)
//{{AFX_MSG_MAP(CSceneView)
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSceneView construction/destruction
CSceneView::CSceneView()
{
// TODO: add construction code here
//视点
VERTEX3D viewer = {0.0f, 0.0f, 8.0f};
//视口变换中进行放大处理, 屏幕位置距离视点100个单位;
//透视中心(屏幕坐标)为(250, 250)
VIEWFINDER viewFinder = {100.0f, 8.0f, 8.0f, {200, 200}};
m_viewer = viewer;
m_viewFinder = viewFinder;
}
CSceneView::~CSceneView()
{
delete m_pSphere0;
delete m_pSphere1;
delete m_pCube0;
delete m_pCube1;
delete m_pCube2;
delete[] m_pLights;
delete m_pCB;
}
BOOL CSceneView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CSceneView drawing
void CSceneView::OnDraw(CDC* pDC)
{
m_pCB->SwapBuffer(pDC);
}
/////////////////////////////////////////////////////////////////////////////
// CSceneView diagnostics
#ifdef _DEBUG
void CSceneView::AssertValid() const
{
CView::AssertValid();
}
void CSceneView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CSceneDoc* CSceneView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSceneDoc)));
return (CSceneDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSceneView message handlers
int CSceneView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
//第一阶段, 建立场景,设置光源和材质属性,完成光照计算
//第一步, 申明两个球对象和一个三个立方体
//球
m_pSphere0 = new CSphere(0.35f, 32, 32);
m_pSphere1 = m_pSphere0->Clone();
//立方体
m_pCube0 = new CCube(3.0f, 0.05f, 3.0f);
m_pCube1 = new CCube(0.4f, 1.2f, 0.2f);
m_pCube2 = m_pCube1->Clone();
//组织场景, 进行几何变换
//构造一个矩阵堆栈
CTypedStack<CMatrix3d> matrixStack;
//变换矩阵
CMatrix3d mGeometry;
//方位矩阵
mGeometry.RotateX(35.0f);
mGeometry.RotateY(-35.0f);
mGeometry.RotateZ(-15.0f);
matrixStack.Push(mGeometry);
mGeometry.Translate(0.15f, 0.0f, 0.0f);
m_pCube0->Transform(mGeometry);
mGeometry.Translate(-0.3f, 0.6f, 1.0f);
m_pSphere0->Transform(mGeometry);
mGeometry.Translate(0.6f, 0.0f, 0.0f);
m_pSphere1->Transform(mGeometry);
mGeometry.Translate(1.05f, -0.6f, -1.0f);
m_pCube1->Transform(mGeometry);
mGeometry.Translate(-2.6f, -0.3f, 0.0f);
m_pCube2->Transform(mGeometry);
//法线:
CMatrix3d mn = matrixStack.Pop();
//物体的顶点法线:
m_pSphere0->TransVertexNormals(mn);
m_pSphere1->TransVertexNormals(mn);
//立方体的法线
//首先求出小面的法线, 然后平均小面的法线
m_pCube0->TransFacetNormals(mn);
m_pCube1->TransFacetNormals(mn);
m_pCube2->TransFacetNormals(mn);
m_pCube0->EvenVertexNormals();
m_pCube1->EvenVertexNormals();
m_pCube2->EvenVertexNormals();
//第二步:设置材质和光源
//设置两个光源
m_pLights = new CLightObj[2];
//设置第一盏灯(泛光灯)
float amb_omni[4] = {0.2f, 0.2f, 0.2f, 1.0f};
float dif_omni[4] = {1.0f, 1.0f, 1.0f, 1.0f};
float spe_omni[4] = {1.0f, 1.0f, 1.0f, 1.0f};
float pos_omni[4] = {0.0f, 0.0f, 8.0f, 1.0f};
m_pLights[0].Lightfv(G3D_AMBIENT, amb_omni);
m_pLights[0].Lightfv(G3D_DIFFUSE, dif_omni);
m_pLights[0].Lightfv(G3D_SPECULAR, spe_omni);
m_pLights[0].Lightfv(G3D_POSITION, pos_omni);
//设置第一盏灯(聚光灯)
float amb_spot[4] = {0.2f, 0.2f, 0.2f, 1.0f};
float dif_spot[4] = {1.0f, 0.0f, 0.0f, 1.0f};
float spe_spot[4] = {1.0f, 1.0f, 1.0f, 1.0f};
float pos_spot[4] = {0.0f, 8.0f, 8.0f, 1.0f};
float dir_spot[4] = {0.0f, -1.0f, -1.0f, 1.0f};
m_pLights[1].Lightfv(G3D_AMBIENT, amb_spot);
m_pLights[1].Lightfv(G3D_DIFFUSE, dif_spot);
m_pLights[1].Lightfv(G3D_SPECULAR, spe_spot);
m_pLights[1].Lightfv(G3D_POSITION, pos_spot);
m_pLights[1].Lightfv(G3D_SPOT_DIRECTION, dir_spot);
m_pLights[1].Lightf(G3D_SPOT_CUTOFF, 5.3f);
m_pLights[1].Lightf(G3D_SPOT_EXPONENT, 50.0f);
//第三步, 定义材质
//黄色材质
float ambMaterial[4] = {0.2f, 0.2f, 0.2f, 1.0f};
float difMaterial[4] = {0.8f, 0.8f, 0.0f, 1.0f};
float speMaterial[4] = {1.0f, 1.0f, 1.0f, 1.0f};
float shininess = 50.0f;
//设置材质
m_material.Materialfv(G3D_FRONT, G3D_AMBIENT, ambMaterial);
m_material.Materialfv(G3D_FRONT, G3D_DIFFUSE, difMaterial);
m_material.Materialfv(G3D_FRONT, G3D_SPECULAR, speMaterial);
m_material.Materialf(G3D_FRONT, G3D_SHININESS, shininess);
//第四步, 进行光照计算
CLighting lighting;
//允许局部光照模型
lighting.LightModelb(G3D_LIGHT_MODEL_LOCAL_VIEWER, TRUE);
//光照计算
lighting.Lighting(m_pSphere0, m_material, m_viewer, m_pLights, 2);
lighting.Lighting(m_pSphere1, m_material, m_viewer, m_pLights, 2);
lighting.Lighting(m_pCube0, m_material, m_viewer, m_pLights, 2);
lighting.Lighting(m_pCube1, m_material, m_viewer, m_pLights, 2);
lighting.Lighting(m_pCube2, m_material, m_viewer, m_pLights, 2);
//第一阶段已经完毕
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
//第二阶段
//
//开始绘制到内存
//第一步, 初始化颜色缓冲区, 申请深度缓冲区
m_pCB = new CColorBuffer(430, 350);
//m_pCB->SetBkColor(255, 255, 255, 255);
//深度缓冲区, 与颜色缓冲区大小保持一致
CZBuffer* pZB = new CZBuffer(430, 350);
pZB->InitAllDepth(500.0f);
//第二步, 着色
CBRender renderer;
//光滑明暗模型
renderer.Render(m_pSphere0, m_viewer, m_viewFinder, m_pCB, pZB, G3D_RENDER_GOURAUD_SMOOTH);
renderer.Render(m_pSphere1, m_viewer, m_viewFinder, m_pCB, pZB, G3D_RENDER_GOURAUD_SMOOTH);
renderer.Render(m_pCube0, m_viewer, m_viewFinder, m_pCB, pZB, G3D_RENDER_GOURAUD_SMOOTH);
renderer.Render(m_pCube1, m_viewer, m_viewFinder, m_pCB, pZB, G3D_RENDER_GOURAUD_SMOOTH);
renderer.Render(m_pCube2, m_viewer, m_viewFinder, m_pCB, pZB, G3D_RENDER_GOURAUD_SMOOTH);
delete pZB;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -