MFC加载3ds模型初步

news2024/11/15 10:47:47

网上下一个资源,名为 OpenGL三维场景绘制.rar;

看一下它是用MFC和opengl,自己绘制三维场景;

运行一下,有一个exe可以运行;

有一个较新版本的不能运行;这应是缺少VC++运行库;

 

下面单独用VC6重新做了看一下;

新建一个单文档工程;

 

    把额外的五个头文件,3个cpp文件加进来;

主要的代码是在C3dsReader里,逐类型处理3D模型的对象;

CTriObject和CTriList是处理3ds文件里对象的,这里的list并不是一个通用的list;主要是这三个类加载3ds文件;

C3dsReader结构如下,

把View类成员定义加一下;绘制坐标的不要,DrawAxis(); 

 

主要的View类成员函数加上;

/
//	                  设置逻辑调色板
//
void CMy3dstestView::SetLogicalPalette(void)
{
    struct
    {
        WORD Version;
        WORD NumberOfEntries;
        PALETTEENTRY aEntries[256];
    } logicalPalette = { 0x300, 256 };

	BYTE reds[] = {0, 36, 72, 109, 145, 182, 218, 255};
	BYTE greens[] = {0, 36, 72, 109, 145, 182, 218, 255};
	BYTE blues[] = {0, 85, 170, 255};

    for (int colorNum=0; colorNum<256; ++colorNum)
    {
        logicalPalette.aEntries[colorNum].peRed =
            reds[colorNum & 0x07];
        logicalPalette.aEntries[colorNum].peGreen =
            greens[(colorNum >> 0x03) & 0x07];
        logicalPalette.aEntries[colorNum].peBlue =
            blues[(colorNum >> 0x06) & 0x03];
        logicalPalette.aEntries[colorNum].peFlags = 0;
    }

    m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette);
}


//
//						初始化openGL场景
//
BOOL CMy3dstestView::InitializeOpenGL(CDC* pDC)
{
	m_pDC = pDC;
	SetupPixelFormat();
	//生成绘制描述表
	m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc());
	//置当前绘制描述表
	::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);

	return TRUE;
}

//
//						设置像素格式
//
BOOL CMy3dstestView::SetupPixelFormat()
{
	PIXELFORMATDESCRIPTOR pfd = { 
	    sizeof(PIXELFORMATDESCRIPTOR),    // pfd结构的大小 
	    1,                                // 版本号 
	    PFD_DRAW_TO_WINDOW |              // 支持在窗口中绘图 
	    PFD_SUPPORT_OPENGL |              // 支持 OpenGL 
	    PFD_DOUBLEBUFFER,                 // 双缓存模式 
	    PFD_TYPE_RGBA,                    // RGBA 颜色模式 
	    24,                               // 24 位颜色深度 
	    0, 0, 0, 0, 0, 0,                 // 忽略颜色位 
	    0,                                // 没有非透明度缓存 
	    0,                                // 忽略移位位 
	    0,                                // 无累加缓存 
	    0, 0, 0, 0,                       // 忽略累加位 
	    32,                               // 32 位深度缓存     
	    0,                                // 无模板缓存 
	    0,                                // 无辅助缓存 
	    PFD_MAIN_PLANE,                   // 主层 
	    0,                                // 保留 
	    0, 0, 0                           // 忽略层,可见性和损毁掩模 
	}; 	
	int pixelformat;
	pixelformat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);//选择像素格式
	::SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd);	//设置像素格式
	if(pfd.dwFlags & PFD_NEED_PALETTE)
		SetLogicalPalette();	//设置逻辑调色板
	return TRUE;
}



//
//						场景绘制与渲染
//
BOOL CMy3dstestView::RenderScene() 
{
	::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	::glMatrixMode(GL_MODELVIEW);
	::glLoadIdentity();

	::glTranslatef( camPos[0], camPos[1], camPos[2] );
	::glRotatef( camRot[0], 1.0F, 0.0F, 0.0F );
	::glRotatef( camRot[1], 0.0F, 1.0F, 0.0F );
	::glRotatef( camRot[2], 0.0F, 0.0F, 1.0F );
	
	::glPushMatrix();
	::glTranslatef(scenePos[0], scenePos[1], scenePos[2]);
	::glRotatef( sceneRot[0], 1.0F, 0.0F, 0.0F );
	::glRotatef( sceneRot[1], 0.0F, 1.0F, 0.0F );
	::glRotatef( sceneRot[2], 0.0F, 0.0F, 1.0F );

	//DrawAxis();
	Draw3ds();
	
	::glPopMatrix();

	::SwapBuffers(m_pDC->GetSafeHdc());		//交互缓冲区
	return TRUE;
}

//
//							Draw3ds()
//
void CMy3dstestView::Draw3ds()
{
	if (m_3dsLoaded) 
	{
			//AfxMessageBox("开始绘制!!!");
			m_triList.drawGL();
	}
}

void CMy3dstestView::Init(GLvoid)
{

	m_3dsLoaded  = FALSE;

	camPos[0]	 = 0.0f;
	camPos[1]	 = 0.0f;
	camPos[2]	 = -500.0f;
	camRot[0]	 = 20.0f;
	camRot[1]	 = -20.0f;
	camRot[2]	 = 0.0f;

	scenePos[0]	 = 0.0f;
	scenePos[1]	 = 0.0f;
	scenePos[2]	 = 0.0f;
	sceneRot[0]	 = 0.0f;
	sceneRot[1]	 = 0.0f;
	sceneRot[2]	 = 0.0f;
	mouseprevpoint.x = 0;
	mouseprevpoint.y = 0;
	mouserightdown = FALSE;
	mouseleftdown = FALSE;


	m_triList.Init();
	
	::glShadeModel(GL_FLAT);
	
	::glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
	
	::glClearDepth(1.0F);

	::glEnable(GL_DEPTH_TEST);

	::glEnable(GL_CULL_FACE);

	GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f};
	GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f};
	GLfloat lightPos[]     = {6000.0f,6000.0f,6000.0f, 1.0f};

	glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
	glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
	
	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

}

void CMy3dstestView::SetCamPos(int axis, int value, BOOL increment, BOOL apply)
{
	if(increment)
	{
		camPos[axis] += (float)value*camPos[axis]/100;
	}
	else
	{
		camPos[axis] = (float)value/2;
	}

	::glMatrixMode(GL_MODELVIEW);
	::glLoadIdentity();

	RenderScene();

}

void CMy3dstestView::SetSceneRot(int axis, int value, BOOL increment, BOOL apply)
{
	if(increment)
		sceneRot[axis] += (sceneRot[axis] >=360) ? (-360 + value/2): value/2;
	else
		sceneRot[axis] = (sceneRot[axis] >=360) ? (-360 + value/2): value/2;
	
	RenderScene();
}

BOOL CMy3dstestView::OpenFile(LPCTSTR lpszPathName)
{
	//AfxMessageBox("视类打开文件!!!");
	char* file = new char[strlen(lpszPathName)];
	strcpy(file, lpszPathName);	

	C3dsReader Loader;
	BOOL result;
	if( m_triList.getNumObjects() > 0 ) m_triList.removeAllObjects();
	
	result = Loader.Reader(file, &m_triList);
	if( result) 
	{
		m_3dsLoaded = TRUE;
		m_triList.doAfterMath();

	}
	
	return result;
	

}

int CMy3dstestView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	//
	m_pDC = new CClientDC(this);
	InitializeOpenGL(m_pDC);
	Init();	
	return 0;
}

void CMy3dstestView::OnDestroy() 
{
	CView::OnDestroy();
	
	// TODO: Add your message handler code here
	::wglMakeCurrent(0,0);
	::wglDeleteContext( m_hRC);
	if (m_hPalette)
	    DeleteObject(m_hPalette);
	if ( m_pDC )
	{
		delete m_pDC;
	}
}

View类的OnCreate消息处理函数需要从类向导加上; 

 

OnDestroy()也是;

 

     其他鼠标的,窗口改变大小的处理,定时器的,先不要;在OnCreate和OnDestroy()里是做了一些初始化和销毁工作;然后还要把gl的头文件加入stdafx.h;

    #include <gl/gl.h>
    #include <gl/glu.h>
    #include <gl/glaux.h>
    #include <gl/glut.h>

到此运行一下程序,出来一个有背景的窗口;

 

然后再看打开文件,为Doc类添加OnOpenDocument函数,

 

其实现代码只有一句如下,

    if( ((CMy3dstestApp*)AfxGetApp())->OpenFile(lpszPathName) ) return TRUE;

它去调用了App类的OpenFile函数;

把App类的OpenFile函数定义加上;

 

 App类的OpenFile函数实现,

BOOL CMy3dstestApp::OpenFile(LPCTSTR lpszPathName)
{
    return ((CMy3dstestView*)((CFrameWnd*)m_pMainWnd)->GetActiveView())->OpenFile(lpszPathName);
}

    这样最终会调用到View类的OpenFile函数;

是在View类OnDraw里面调用RenderScene来渲染场景;

void CMy3dstestView::OnDraw(CDC* pDC)
{
	CMy3dstestDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	RenderScene();
}

RenderScene() 主要调用Draw3ds();

此时对象已经读入列表;

Draw3ds()主要执行 m_triList.drawGL();

triList的drawGL()实现如下,

    void CTriList::drawGL()
    {
        for (int i=0; i <numobjects; i++)
        {
           objects[i]->drawGL();
        }     
        glPopMatrix();

    }

通过调用CTriObject的drawGL()来逐个绘制;

现在运行程序,打开一个文件看一下;啥也没绘制;先到这里,下回再看;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/690465.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux下RPM软件包管理

目录 1、软件包管理介绍1.1、软件包分类1.2、源码包1.3、RPM包 2、RPM包管理-包命名和依赖性2.1、RPM命名规则2.2、RPM包依赖性 3、RPM包管理-安装升级和与卸载3.1、包全名与包名3.2、RPM安装3.3、RPM包升级3.4、卸载 4、RPM包管理-查询4.1、查询是否安装4.2、查询软件包详细信…

Gitlab将本地代码推送到远程空仓库

目录 引言 1、设置Git为源代码管理插件 2、创建Git仓库 3、设置多个远程仓库 引言 如果我们的本地代码想上传到公司内部的服务器&#xff0c;首先我们需要在VS2022中创建Git仓库&#xff0c;然后设置远程仓库的地址&#xff0c;才能将本地代码推送到远端。在远端会根据你本地…

表格式表单-table式from表单-合并行-合并列

效果: 使用【colspan】合并行 和【rowspan】合并列 html: <!-- 添加或修改报告数据库对话框 --><el-dialog :title"title" :visible.sync"open" width"1500px" append-to-body><el-form ref"form" :model"form&q…

Android Jetpack Compose之Checkbox的使用

Android Jetpack Compose 是一个现代化的 UI 工具包&#xff0c;为开发者提供了一种声明式的方式来构建出美观且功能强大的 Android 应用。在本文中&#xff0c;我们将详细介绍其中的一个重要组件——Checkbox。 一. Checkbox 简介 Checkbox 是 Jetpack Compose 中的一个组件&…

STM32单片机(三)第四节:GPIO输入练习2(光敏传感器控制蜂鸣器)

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

一文学会如何使用Docker

Docker常见使用 1、Docker安装 ## 下载阿里源repo文件 $ curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo $ curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo$ yum clean …

详解8种不同类型的防火墙

什么是防火墙&#xff1f; 防火墙是一种监视网络流量并检测潜在威胁的安全设备或程序&#xff0c;作为一道保护屏障&#xff0c;它只允许非威胁性流量进入&#xff0c;阻止危险流量进入。 防火墙是client-server模型中网络安全的基础之一&#xff0c;但它们容易受到以下方面的攻…

选择低代码平台的正确方式

传统开发模式早已不能满足大多数追求效率的企业的要求&#xff0c;低代码平台的出现正是可以缓解相应的开发压力&#xff0c;作为使用者我们更应该擦亮眼睛&#xff0c;选择合适的平台产品&#xff0c;充分利用新技术带来的新价值。小编在以前的文章有介绍过低代码平台应该如何…

php中的双引号与单引号的基本使用

字符串,在各类编程语言中都是一个非常重要的数据类型 网页当中的图片,文字,特殊符号,HTMl标签,英文等都属于字符串 PHP字符串变量用于存储并处理文本, 在创建字符串之后&#xff0c;我们就可以对它进行操作。我们可以直接在函数中使用字符串&#xff0c;或者把它存储在变量中 字…

360手机命令行进入fastboot线刷模式 360手机刷机

360手机命令行进入fastboot线刷模式 360手机刷机 参考&#xff1a;360手机-360刷机360刷机包twrp、root 360刷机包360手机刷机&#xff1a;360rom.github.io 【前言】 因360手机特殊&#xff1b;且因机器情况而异&#xff1b;导致360手机进不去fastboot线刷模式、360手机进…

基于Java+Swing实现坦克大战游戏

基于JavaSwing实现坦克大战游戏 一、系统介绍二、功能展示三、其他系统四、获取源码 一、系统介绍 此系统是使用Java语言实现坦克大战游戏程序&#xff0c;玩家通过连接访问进入游戏&#xff0c;通过操纵坦克来守卫基地&#xff0c;玩家还可以获得超级武器来提升坦克的属性&am…

点云特征描述子概述、PFH描述子提取

1、 6种点云特征描述子简概 NARF&#xff08;Normal Aligned Radial Feature&#xff09;特征点描述子&#xff1a;NARF描述子是一种基于法线对齐的径向特征描述子。它通过将点云表面分割为小的网格单元&#xff0c;并计算每个单元中的法线直方图&#xff0c;从而提取特征。NA…

【网站监控】如何监控自己的网站(接口)

网站监控-如何监控自己的网站 前言一、开始使用1、使用API进行监控数据采集?2、请求参数3、如何查看监控效果? 二、注意点 前端必备工具&#xff08;免费图床、API、chatAI等&#xff09;推荐网站LuckyCola: https://luckycola.com.cn/ 前言 网站接口监控是指对接口的状态进…

Keil为啥比IAR更受欢迎?

关注星标公众号&#xff0c;不错过精彩内容 作者 | strongerHuang 微信公众号 | strongerHuang 最近交流群在讨论【选择Keil和IAR的问题】&#xff0c;这就顺便展开来说下。 你可能觉得Keil、IAR这种集成开发环境界面比较古老&#xff0c;又不好用。 但是&#xff0c;这里告诉大…

ConcurrentModificationException异常分析与解决

ConcurrentModificationException异常分析与解决 1、场景重现&#xff0c;制造ConcurrentModificationException异常 Testpublic void ConcurrentModificationExceptionTest() {JSONArray jsonArray new JSONArray();JSONObject jsonObject new JSONObject();jsonObject.put…

改写cocos2d的ProgressTimer实现任意起始点的Radial进度条

解释一下要做的事&#xff1a; 原生ProgressTimer控件的进度起始点只能是在&#xff08;0.5&#xff0c;1&#xff09;的位置&#xff0c;如下&#xff1a; 我们要改成可以将矩形边上的任意点作为起始点&#xff0c;如下&#xff1a; 首先讲一下绘制的逻辑&#xff1a; 先根…

3: PCIe BDF(Bus,Device,Function)

目录 1.概述 2.BUS&#xff1a;总线号 3.Device&#xff1a;设备号 4.Function&#xff1a;功能号 1.概述 PCIe总线中的每一个功能都有一个唯一的标识符与之对应。这个标识符就是BDF&#xff08;Bus&#xff0c;Device&#xff0c;Function&#xff09; 2.BUS&#xff1a;总…

基于Java客户管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

SSD202D-GPIO调试驱动-三

前面又两个介绍 SSD202D-GPIO调试驱动-一 SSD202D-GPIO调试驱动-二 主要是调试方法: insmod gpio_lonbon.ko 然后可以再看到一下节点 //出现以下节点 proc/gpio-lb/dbg sys/kernel/debug/gpio-lb/debug sys/class/gpio-lb/ dev/gpio-lb 然后

python中MongoEngine简单使用

python中MongoEngine简单使用 1 MongoEngine介绍 MongoEngine是一个处理MongoDB的对象文档映射器。pymongo是非面向对象的方式操作数据。 MongoEngine开发文档 # 开发文档 http://docs.mongoengine.org/index.html# 数据类型 http://docs.mongoengine.org/apireference.htm…