⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 surfaceview.cpp

📁 这是一个vc++的小程序
💻 CPP
字号:
// SurfaceView.cpp : implementation of the CSurfaceView class
//

#include "stdafx.h"
#include "Surface.h"

#include "SurfaceDoc.h"
#include "SurfaceView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


#pragma comment(lib,  "OpenGL32.lib")
#pragma comment(lib,  "glu32.lib")

#include "GL\gl.h"
#include "GL\glu.h"

/////////////////////////////////////////////////////////////////////////////
// CSurfaceView

IMPLEMENT_DYNCREATE(CSurfaceView,  CView)

BEGIN_MESSAGE_MAP(CSurfaceView,  CView)
	//{{AFX_MSG_MAP(CSurfaceView)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSurfaceView construction/destruction

CSurfaceView::CSurfaceView()
{
	// TODO: add construction code here
	m_pDC = NULL;
	m_pDib = NULL;
}

CSurfaceView::~CSurfaceView()
{

}

BOOL CSurfaceView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	//设置 OpenGL 窗口风格,   
	cs.style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CSurfaceView drawing

void CSurfaceView::OnDraw(CDC* pDC)
{
	DrawScene();
}	

/////////////////////////////////////////////////////////////////////////////
// CSurfaceView diagnostics

#ifdef _DEBUG
void CSurfaceView::AssertValid() const
{
	CView::AssertValid();
}

void CSurfaceView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CSurfaceDoc* CSurfaceView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSurfaceDoc)));
	return (CSurfaceDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CSurfaceView message handlers

//设置像素格式
BOOL CSurfaceView::SetupPixelFormat()
{
	static PIXELFORMATDESCRIPTOR pfd = 
	{
        sizeof(PIXELFORMATDESCRIPTOR),    // size of this pfd
        1,                               // version number
        PFD_DRAW_TO_WINDOW |            // support window
          PFD_SUPPORT_OPENGL, 			// support OpenGL
        PFD_TYPE_RGBA,                   // RGBA type
        24,                              // 24-bit color depth
        0,  0,  0,  0,  0,  0,                // color bits ignored
        0,                               // no alpha buffer
        0,                               // shift bit ignored
        0,                               // no accumulation buffer
        0,  0,  0,  0,                      // accum bits ignored
        32,                              // 32-bit z-buffer
        0,                               // no stencil buffer
        0,                               // no auxiliary buffer
        PFD_MAIN_PLANE,                  // main layer
        0,                               // reserved
        0,  0,  0                         // layer masks ignored
    };

	//选择硬件所支持的像素格式与 pfd 最接近的一个
    int nPixelformat;
    if ( (nPixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(),   &pfd)) == 0 )
    {
        MessageBox("ChoosePixelFormat failed");
        return FALSE;
    }

	//设置已经匹配的像素格式
    if (SetPixelFormat(m_pDC->GetSafeHdc(),   nPixelformat,  &pfd) == FALSE)
    {
        MessageBox("SetPixelFormat failed");
        return FALSE;
    }
    return TRUE;
}

//初始化OpenGL
void CSurfaceView::Init()
{
	PIXELFORMATDESCRIPTOR pfd;
 
	m_pDC = new CClientDC(this);
	ASSERT(m_pDC != NULL);

	//设置像素格式
    if(!SetupPixelFormat())return;

	//测试并描述像素格式
    int nIndex = GetPixelFormat(m_pDC->GetSafeHdc());
    DescribePixelFormat(m_pDC->GetSafeHdc(),   nIndex,  sizeof(pfd),   &pfd);

	//创建着色描述表
	HGLRC hrc = wglCreateContext(m_pDC->GetSafeHdc());

	//当前化着色描述表
	wglMakeCurrent(m_pDC->GetSafeHdc(),   hrc);

	//允许深度测试,  深度初始值为远剪切面深度(规格化坐标系中)
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
}

int CSurfaceView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	
	Init();	

	m_pDib = new CDib("valley.bmp");

	return 0;
}

void CSurfaceView::OnDestroy() 
{
	CView::OnDestroy();
	
	// TODO: Add your message handler code here

	//获取当前着色描述表句柄
	HGLRC hrc = wglGetCurrentContext();

	//撤消与着色描述表关联的着色任务
	wglMakeCurrent(NULL,  NULL);

	//释放
	if(hrc)wglDeleteContext(hrc);
	if(m_pDC) delete m_pDC;
	if(m_pDib) delete m_pDib;
}

void CSurfaceView::OnSize(UINT nType,  int cx,  int cy) 
{
	CView::OnSize(nType,  cx,  cy);
	
	// TODO: Add your message handler code here
	//启动透视变换矩阵
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	//设置视景体
	glFrustum(-1.0,  1.0,  -1.0,  1.0,  3.0,  7.0);

	//设置视口
	glViewport(0,  0,  (GLsizei)cx,  (GLsizei)cy);
}

//
void CSurfaceView::DrawScene()
{
	//启动模型变换矩阵,  并单位化
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	//将景物移至视景体之中
	glTranslatef(0.0f,  0.0f,  -4.5f);

	//颜色缓冲区清除颜色为白色
	glClearColor(1.0f,  1.0f,  1.0f,  1.0f);
	//同时清除颜色缓冲区和深度缓冲区
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	DrawBezierSurface();

	//完成绘制指令后交换缓冲区
	glFinish();	
}

//绘制纹理映射Bezier曲面
void CSurfaceView::DrawBezierSurface()
{
	//几何控制点

	GLfloat vertexCtrlPts[4][4][3] = {
		{{-1.1f,  -0.6f,  0.2f},   {-0.2f,  -0.6f,  0.4f},   
		{0.2f,  -0.6f,  0.4f},     {0.4f,  -0.6f,  0.2f}},  
		{{-0.6f,  -0.2f,  0.1f},   {-0.2f,  -0.2f,  0.5f},   
		{0.2f,  -0.2f,  0.5f},     {0.6f,  -0.2f,  0.1f}},  
		{{-0.6f,  0.2f,  0.3f}, 	{-0.2f,  0.2f,  0.5f},   
		{0.2f,  0.2f,  0.5f}, 		{0.6f,  0.2f,  0.3f}},  
		{{-0.6f,  0.6f,  0.2f}, 	{-0.2f,  0.6f,  0.4f},   
		{0.2f,  0.6f,  0.4f}, 		{1.1f,  0.6f,  0.2f}},  
	};

	//纹理控制点
	GLfloat textureCtrlPts[2][2][2] = {
		{{1.0f,  0.0f},  {1.0f,  1.0f}}, 
		{{0.0f,  0.0f}, {0.0f,  1.0f}}};

	//构造纹理图像数据
	GLubyte* pTextureBits = (GLubyte*)m_pDib->GetDibData();
	
	//图像的宽度一定要满足(以下解释来自于在线帮助):
	//(1)		The width of the texture image. Must be 2 ^ n + 2 (border) for some integer n. 
	//(2)		The height of the texture image. Must be 2 ^ m + 2 (border) for some integer m. 
	
	//			OpenGL在这一点上作得并不好!

	GLint nWidth = m_pDib->GetWidth();
	GLint nHeight = m_pDib->GetHeight();

	glPixelStorei(GL_UNPACK_ALIGNMENT,  1);


	//(3)	The width of the border. Must be either 0 or 1. 

	//定义纹理
	glTexImage2D(GL_TEXTURE_2D,  0,  3,  nWidth,  nHeight, 
		0,  GL_BGR_EXT,  GL_UNSIGNED_BYTE,  pTextureBits);

	//控制纹理, 说明滤波方式
	glTexParameterf(GL_TEXTURE_2D,  GL_TEXTURE_WRAP_S,  GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D,  GL_TEXTURE_WRAP_T,  GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D,  GL_TEXTURE_MAG_FILTER,  GL_NEAREST);
	glTexParameterf(GL_TEXTURE_2D,  GL_TEXTURE_MIN_FILTER,  GL_NEAREST);
	
	//说明纹理映射方式
	glTexEnvf(GL_TEXTURE_ENV,  GL_TEXTURE_ENV_MODE,  GL_DECAL);

	//二维评价器:	生成几何坐标和纹理坐标
    glMap2f(GL_MAP2_VERTEX_3,  0,  1,  3,  4, 
        0,  1,  12,  4,  (const float*)vertexCtrlPts);
    glMap2f(GL_MAP2_TEXTURE_COORD_2,  0,  1,  2,  2,  
        0,  1,  4,  2,  (const float*)textureCtrlPts);

	//光照
	CreateLightAndMaterial();
	
	//启动纹理贴图和法线自动计算功能
	glEnable(GL_TEXTURE_2D);
    glEnable(GL_MAP2_TEXTURE_COORD_2);
    glEnable(GL_MAP2_VERTEX_3);

	glEnable(GL_AUTO_NORMAL);
    glEnable(GL_NORMALIZE);

	
	//利用二维评价器的计算结果实现网格分割
    glMapGrid2f(30,  0.0,  1.0,  30,  0.0,  1.0);

	//绘制
    glPushMatrix ();
		glScalef(1.1f,  1.1f,  1.1f);
		glRotatef(90.0f,  0.0f,  .0f,  1.0f);
		glEvalMesh2(GL_FILL,  0,  30,  0,  30);
    glPopMatrix();

	//挂起各功能
	glDisable(GL_MAP2_VERTEX_3);
    glDisable(GL_MAP2_TEXTURE_COORD_2);

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_AUTO_NORMAL);
	glDisable(GL_NORMALIZE);
	glDisable(GL_LIGHTING);
	glDisable(GL_LIGHT0);
}


//创建光源、材质
void CSurfaceView::CreateLightAndMaterial()
{
	//定义光源属性.漫反射、镜面高光均采用缺省值.
	//泛光光源。
    GLfloat lightAmb[] = {0.2f,  0.2f,  0.2f,  1.0f };
    GLfloat lightPos[] = {1.0f,  1.0f,  2.0f,  1.0f };

	//材质,环境反射系数采用缺省值,光照射前面。
    GLfloat matDiffuse[] = {0.0f,  0.7f,  0.7f,  1.0f };
    GLfloat matSpecular[] = {1.0f,  1.0f,  1.0f,  1.0f };
    GLfloat matShininess[] = {60.0f };
    
	//允许光照, 并开启第0个光源
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

	//设置第0个光源的属性
    glLightfv(GL_LIGHT0,  GL_AMBIENT,  lightAmb);
    glLightfv(GL_LIGHT0,  GL_POSITION,  lightPos);
    
	//设置材质属性.
    glMaterialfv(GL_FRONT,  GL_DIFFUSE,  matDiffuse);
    glMaterialfv(GL_FRONT,  GL_SPECULAR,  matSpecular);
    glMaterialfv(GL_FRONT,  GL_SHININESS,  matShininess);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -