当前位置:文档之家› 计算机图形学课程设计报告 简单光照

计算机图形学课程设计报告 简单光照

计算机图形学课程设计报告 简单光照
计算机图形学课程设计报告 简单光照

目录

目录............................................................................................... I

一、选题背景....................................................... 错误!未定义书签。

1.1 内容要求 ................................................. 错误!未定义书签。

1.1.1 内容设计 (2)

1.1.2 基本要求 (2)

二、算法设计....................................................... 错误!未定义书签。

2.1 相关原理 ................................................. 错误!未定义书签。

2.1.1 明暗模型 (3)

2.1.2 镜面反射与Phong模型 (3)

2.1.3 渲染 (3)

2.2 模块划分 (4)

三、程序及功能说明 (2)

3.1 光照类型选择模块 (4)

3.2 材质选择模块 (6)

3.3 光照位置选择模块 (8)

四、结果分析 (11)

4.1 运行截图...... .. (11)

五、总结........................................................... 错误!未定义书签。

六、课程设计心得体会....................................... 错误!未定义书签。参考文献............................................................... 错误!未定义书签。源程序. (18)

三、程序及功能说明

3.1 光照类型选择模块

1、漫反射光代码

if(Chk2)

{

if(First)

{

p[0].c=Ambientc+Diffusec*f[0];

p[1].c=Ambientd+Diffused*f[1];

p[2].c=Ambientr+Diffuser*f[2];

}

else

{

p[0].c=Ambientd+Diffused*f[0];

p[1].c=Ambientdr+Diffusedr*f[1];

p[2].c=Ambientr+Diffuser*f[2];

}

}

2、环境光代码

if(Chk1)

{ if(First)

{

p[0].c=Ambientc;

p[1].c=Ambientd;

p[2].c=Ambientr;

}

else

{

p[0].c=Ambientd;

p[1].c=Ambientdr;

p[2].c=Ambientr;

}

}

double c0,c1,c2,dist[3];//c0常数衰减因子,c1线性衰减因子,c2二次衰减因子,dist定点与光源的距离

double f[3];

c0=0.65;c1=0.00002;c2=0.000001;

for(int i=0;i<3;i++)

{

dist[i]=sqrt((p[i].x-Positionx)*(p[i].x-Positionx)

+(p[i].y-Positiony)*(p[i].y-Positiony)

+(p[i].z-Positionz)*(p[i].z-Positionz));

f[i]=1.0/(c0+c1*dist[i]+c2*dist[i]*dist[i]);

f[i]=Min(f[i]);

}

double dCosc,dCosd,dCosr,dCosdr;

dCosc=Dot(Lv,N1);dCosd=Dot(Lv,Nd);dCosr=Dot(Lv,Nr);dCosdr=Dot(Lv,N dr);

dCosc=(dCosc<0.0f)?0.0f:dCosc;

dCosd=(dCosd<0.0f)?0.0f:dCosd;

dCosr=(dCosr<0.0f)?0.0f:dCosr;

dCosdr=(dCosdr<0.0f)?0.0f:dCosdr;

MyRGB Diffusec=lightP.diffuse*dCosc;

MyRGB Diffused=lightP.diffuse*dCosd;

MyRGB Diffuser=lightP.diffuse*dCosr;

MyRGB Diffusedr=lightP.diffuse*dCosdr;

3、镜面反射光代码

if(Chk3)

{

double sCosc,sCosd,sCosdr,sCosr;

Vector Hvector,Hv;

Hvector=(LPosition+VisualV)*0.5;//平分矢量

Hv=Hvector.Unit();

sCosc=Dot(Hv,N1);sCosd=Dot(Hv,Nd);sCosr=Dot(Hv,Nr);sCosdr=Dot(Hv,N dr);

for(int i=0;i

{

sCosc*=sCosc;

sCosd*=sCosd;

sCosr*=sCosr;

sCosdr*=sCosdr;

}

sCosc=(dCosc<0.0f)?0.0f:sCosc;

sCosd=(dCosd<0.0f)?0.0f:sCosd;

sCosr=(dCosr<0.0f)?0.0f:sCosr;

sCosdr=(dCosdr<0.0f)?0.0f:sCosdr;

MyRGB Specularc=lightP.specular*sCosc;

MyRGB Speculard=lightP.specular*sCosd;

MyRGB Specularr=lightP.specular*sCosr;

MyRGB Speculardr=lightP.specular*sCosdr;

if(First)

{

p[0].c=Ambientc+Diffusec*f[0]+Specularc*f[0];

p[1].c=Ambientd+Diffused*f[1]+Speculard*f[1];

p[2].c=Ambientr+Diffuser*f[2]+Specularr*f[2];

}

else

{

p[0].c=Ambientd+Diffused*f[0]+Speculard*f[0];

p[1].c=Ambientdr+Diffusedr*f[1]+Speculardr*f[1];

p[2].c=Ambientr+Diffuser*f[2]+Specularr*f[2];

}

}

for(int k=0;k<3;k++)

{

Project(p[k]);

Point[k].x=ScreenP.x;

Point[k].y=ScreenP.y;

Point[k].c=ScreenP.c;

}

if(Dot(Uv,N1)>=0)//根据数量积正负消隐

{

CreatBucket();//初始化桶

Et();//用于建立边表

SphereFill(mdc);//进行填充

}

}

void CTestView::Project(P3d &P)//透视变换

{

ViewP.x=k[1]*P.x-k[3]*P.y;//观察坐标系的三维坐标

ViewP.y=-k[7]*P.x-k[8]*P.y+k[2]*P.z;

ViewP.z=-k[5]*P.x-k[6]*P.y-k[4]*P.z+R;

ScreenP.x=D*ViewP.x/ViewP.z;//屏幕坐标系的二维坐标ScreenP.y=ROUND(D*ViewP.y/ViewP.z);

ScreenP.c=P.c;

}

void CTestView::InitParameter()//透视变换常数

{

k[1]=sin(PI*Thta/180);

k[2]=sin(PI*Fei/180);

k[3]=cos(PI*Thta/180);

k[4]=cos(PI*Fei/180);

k[5]=k[3]*k[2];

k[6]=k[1]*k[2];

k[7]=k[3]*k[4];

k[8]=k[1]*k[4];

}

3.2 材质选择模块

1、金材质代码

void CTestView::OnCheck4()//金

{

// TODO: Add your control notification handler code here

UpdateData(true);

if(!Chk4)

{

n=5;//聚光指数

MaterialA.red=0.247;MaterialA.green=0.2;MaterialA.blue=0.075;

MaterialD.red=0.752;MaterialD.green=0.606;MaterialD.blue=0.226;

MaterialS.red=0.628;MaterialS.green=0.556;MaterialS.blue=0.366;

LightA.red=1.0f;LightA.green=1.0f;LightA.blue=1.0f;

LightD.red=1.0f;LightD.green=1.0f;LightD.blue=1.0f;

LightS.blue=1.0-LightA.blue*MaterialA.blue-LightD.blue*MaterialD.blue;

LightS.red=1.0-LightA.red*MaterialA.red-LightD.red*MaterialD.red;//光源颜色

LightS.green=1.0-LightA.green*MaterialA.green-LightD.green*MaterialD.gr een;

Chk4=!Chk4;

}

else

{

Chk4=!Chk4;

}

Invalidate(false);

UpdateData(false);

}

2、银材质代码

void CTestView::OnCheck5()//银

{

// TODO: Add your control notification handler code here

UpdateData(true);

if(!Chk5)

{

n=6;

MaterialA.red=0.192;MaterialA.green=0.192;MaterialA.blue=0.192;

MaterialD.red=0.508;MaterialD.green=0.508;MaterialD.blue=0.508;

MaterialS.red=0.508;MaterialS.green=0.508;MaterialS.blue=0.508;

LightA.red=1.0f;LightA.green=1.0f;LightA.blue=1.0f;

LightD.red=1.0f;LightD.green=1.0f;LightD.blue=1.0f;

LightS.red=1.0-LightA.red*MaterialA.red-LightD.red*MaterialD.red;//光源颜色

LightS.green=1.0-LightA.green*MaterialA.green-LightD.green*MaterialD.gr een;

LightS.blue=1.0-LightA.blue*MaterialA.blue-LightD.blue*MaterialD.blue;

Chk5=!Chk5;

}

else

{

Chk5=!Chk5;

}

Invalidate(false);

UpdateData(false);

}

3、红宝石材质代码

void CTestView::OnCheck7()//红宝石

{

// TODO: Add your control notification handler code here

UpdateData(true);

if(!Chk7)

{

n=3;

MaterialA.red=0.175;MaterialA.green=0.012;MaterialA.blue=0.012;

MaterialD.red=0.614;MaterialD.green=0.041;MaterialD.blue=0.041;

MaterialS.red=0.728;MaterialS.green=0.527;MaterialS.blue=0.527;

LightA.red=1.0f;LightA.green=1.0f;LightA.blue=1.0f;

LightD.red=1.0f;LightD.green=1.0f;LightD.blue=1.0f;

LightS.red=1.0-LightA.red*MaterialA.red-LightD.red*MaterialD.red;//光源颜色

LightS.green=1.0-LightA.green*MaterialA.green-LightD.green*MaterialD.gr een;

LightS.blue=1.0-LightA.blue*MaterialA.blue-LightD.blue*MaterialD.blue;

Chk7=!Chk7;

}

else

{

Chk7=!Chk7;

}

Invalidate(false);

UpdateData(false);

}

4、绿宝石材质代码

void CTestView::OnCheck6()//绿宝石

{

// TODO: Add your control notification handler code here

UpdateData(true);

if(!Chk6)

{

n=3;

MaterialA.red=0.022;MaterialA.green=0.175;MaterialA.blue=0.023;

MaterialD.red=0.076;MaterialD.green=0.614;MaterialD.blue=0.075;

MaterialS.red=0.633;MaterialS.green=0.728;MaterialS.blue=0.633;

LightA.red=1.0f;LightA.green=1.0f;LightA.blue=1.0f;

LightD.red=1.0f;LightD.green=1.0f;LightD.blue=1.0f;

LightS.red=1.0-LightA.red*MaterialA.red-LightD.red*MaterialD.red;//

光源颜色

LightS.green=1.0-LightA.green*MaterialA.green-LightD.green*MaterialD.gr een;

LightS.blue=1.0-LightA.blue*MaterialA.blue-LightD.blue*MaterialD.blue;

Chk6=!Chk6;

}

else

{

Chk6=!Chk6;

}

Invalidate(false);

UpdateData(false);

}

3.2 光照位置选择模块

1、上右位置代码

void CTestView::OnCheck11()

{

// TODO: Add your control notification handler code here

UpdateData(true);

if(!Chk11)

{

Positionx=300;Positiony=300;Positionz=-300;

Chk11=!Chk11;

}

else

{

Chk11=!Chk11;

}

Invalidate(false);

UpdateData(false);

}

2、下右位置代码

void CTestView::OnCheck12()

{

// TODO: Add your control notification handler code here

UpdateData(true);

if(!Chk12)

{

Positionx=300;Positiony=300;Positionz=300;

Chk12=!Chk12;

}

else

{

Chk12=!Chk12;

}

Invalidate(false);

UpdateData(false);

}

3、上左位置代码

void CTestView::OnCheck9()

{

// TODO: Add your control notification handler code here

UpdateData(true);

if(!Chk9)

{

Positionx=-300;Positiony=300;Positionz=-300;

Chk9=!Chk9;

}

else

{

Chk9=!Chk9;

}

Invalidate(false);

UpdateData(false);

}

4、下左位置代码

void CTestView::OnCheck10()

{

// TODO: Add your control notification handler code here

UpdateData(true);

if(!Chk10)

{

Positionx=-300;Positiony=300;Positionz=300;

Chk10=!Chk10;

}

else

{

Chk10=!Chk10;

}

Invalidate(false);

UpdateData(false);

}

四、结果分析

4.1 运行截图

图4-1 左上角光照显示结果

图4-2 右下角光照显示结果

图4-3 右上角光照显示结果

图4-4 左下角

源程序#include "stdafx.h"

#include "Test.h"

#include "TestDoc.h"

#include "TestView.h"

#include "math.h"//数学头文件

#define ROUND(a) int(a+0.5)//四舍五入

#define PI 3.1415926//圆周率

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

// CTestView

IMPLEMENT_DYNCREATE(CTestView, CView)

BEGIN_MESSAGE_MAP(CTestView, CView) //{{AFX_MSG_MAP(CTestView)

ON_WM_ERASEBKGND()

ON_COMMAND(IDR_Light, OnLight)

ON_BN_CLICKED(IDC_CHECK1, OnCheck1)

ON_BN_CLICKED(IDC_CHECK2, OnCheck2)

ON_BN_CLICKED(IDC_CHECK3, OnCheck3)

ON_BN_CLICKED(IDC_CHECK4, OnCheck4)

ON_BN_CLICKED(IDC_CHECK5, OnCheck5)

ON_BN_CLICKED(IDC_CHECK6, OnCheck6)

ON_BN_CLICKED(IDC_CHECK7, OnCheck7)

ON_BN_CLICKED(IDC_CHECK8, OnCheck8)

ON_BN_CLICKED(IDC_CHECK9, OnCheck9)

ON_BN_CLICKED(IDC_CHECK10, OnCheck10) ON_BN_CLICKED(IDC_CHECK11, OnCheck11) ON_BN_CLICKED(IDC_CHECK12, OnCheck12) //}}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()

/////////////////////////////////////////////////////////////////////////////

// CTestView construction/destruction

CTestView::CTestView()

{

// TODO: add construction code here

Chk1=Chk2=Chk3=Chk4=Chk5=Chk6=false;

Chk7=Chk8=Chk9=Chk10=Chk11=Chk12=false;

r=100;//球半径

R=300;Fei=90;Thta=90;D=800;//视点参数

LightA.red=1.0f;LightA.green=1.0f;LightA.blue=1.0f;

LightD.red=1.0f;LightD.green=1.0f;LightD.blue=1.0f;

n=5;//高光指数

}

CTestView::~CTestView()

{

}

BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs)

{

// TODO: Modify the Window class or styles here by modifying

// the CREATESTRUCT cs

return CView::PreCreateWindow(cs);

}

/////////////////////////////////////////////////////////////////////////////

// CTestView drawing

void CTestView::OnDraw(CDC* pDC)

{

CTestDoc* pDoc = GetDocument();

ASSERT_V ALID(pDoc);

// TODO: add draw code for native data here

AfxGetMainWnd()->SetWindowText("光照模型:光源");

GetMaxX();

GetMaxY();

InitParameter();

ReadPoint();

ReadFace();

DrawGlobe();

}

/////////////////////////////////////////////////////////////////////////////

// CTestView printing

BOOL CTestView::OnPreparePrinting(CPrintInfo* pInfo)

{

// default preparation

return DoPreparePrinting(pInfo);

}

void CTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) {

// TODO: add extra initialization before printing

}

void CTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) {

// TODO: add cleanup after printing

}

/////////////////////////////////////////////////////////////////////////////

// CTestView diagnostics

#ifdef _DEBUG

void CTestView::AssertValid() const

{

CView::AssertValid();

}

void CTestView::Dump(CDumpContext& dc) const

{

CView::Dump(dc);

}

CTestDoc* CTestView::GetDocument() // non-debug version is inline

{

ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTestDoc)));

return (CTestDoc*)m_pDocument;

}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CTestView message handlers

void CTestView::GetMaxX()//获得屏幕宽度

{

CRect Rect;

GetClientRect(&Rect);

MaxX=Rect.right;

}

void CTestView::GetMaxY()//获得屏幕高度

{

CRect Rect;

GetClientRect(&Rect);

MaxY=Rect.bottom;

}

void CTestView::ReadPoint()//读入点坐标{

double afa,beta;

for(int i=0;i<37;i++)

{

afa=i*5*PI/180;

for(int j=0;j<72;j++)

{

beta=j*5*PI/180;

P[i][j].x=r*sin(afa)*cos(beta);

P[i][j].y=r*sin(afa)*sin(beta);

P[i][j].z=r*cos(afa);

}

}

}

void CTestView::ReadFace()//读入面坐标{

for(int i=0;i<36;i++)

{

for(int j=0;j<72;j++)

{

F[i][j].p[0]=P[i][j];

F[i][j].p[1]=P[i+1][j];

if(j==71)

{

F[i][j].p[2]=P[i+1][0];

F[i][j].p[3]=P[i][0];

}

else

{

F[i][j].p[2]=P[i+1][j+1];

F[i][j].p[3]=P[i][j+1];

}

}

}

}

void CTestView::DrawGlobe()

{

CRect Rect;

GetClientRect(&Rect);

CDC MemDC;

CBitmap Bitmap,*OldBitmap;

Bitmap.LoadBitmap(IDB_BITMAP2);

MemDC.CreateCompatibleDC(GetDC());

OldBitmap=MemDC.SelectObject(&Bitmap);

MemDC.BitBlt(0,0,Rect.Width(),Rect.Height(),&Picture,0,0,SRCCOPY);

for(int i=0;i<36;i++)

{

for(int j=0;j<72;j++)

{

for(int m=0;m<4;m++)

{

P1[m].x=F[i][j].p[m].x;

P1[m].y=F[i][j].p[m].y;

P1[m].z=F[i][j].p[m].z;

Pdown[m].x=F[i+1][j].p[m].x;

Pdown[m].y=F[i+1][j].p[m].y;

Pdown[m].z=F[i+1][j].p[m].z;

if(j==71)

{

Pright[m].x=F[i][0].p[m].x;

Pright[m].y=F[i][0].p[m].y;

相关主题
文本预览
相关文档 最新文档