【转载】从零实现3D图像引擎:(1)环境配置与项目框架
0. 要学懂3D程序设计,必然要精通3D相关的线性代数、3D几何、复分析等相关知识,我也因为如此才开始这个博客系列的写作,不自己实现,就不是自己的东西,从今天开始,将会把所学的数学知识,从数学推导到代码实现的心得全部记录于此。最终得到一个独立的3D图像引擎,也就完成了对3D图像知识的基本学习。
1. 文章布局。除了本文,所有文章都将由3部分组成。
1) 数学理论推导。
2) 不参看任何示例,只根据数学原理进行的代码实现。
3) 项目代码下载。
2. 语言与开发环境
1) 语言:C/C++。
3D游戏说白了就俩字:速度。所以对于面向对象这种东西,在速度面前完全可以无视,而且对于数学和图形库来说,本来也没有过多的对象间关系,多是数据结构与函数的关系,所以C++特性我应该不会用很多,有时为了速度还会穿插asm、SIMD和FPU的使用。
2) 开发工具:VS2010。强大到没得说。
3) 图形接口:D3D。(DirectX SDK June 2010,下载地址:http://www.microsoft.com/downloads/en/details.aspx?FamilyID=3021d52b-514e-41d3-ad02-438a3ba730ba)
“给我显存地址,我就能创造一个游戏”。这是从零实现3D图像引擎的目的,也是我认为学会3D编程的必经之路。本来我想使用DirectDraw,完全不使用D3D,而且即便是DirectDraw,也只是用它来获取显存地址,其他API全都不用。但是由于现在DirectX SDK已经都没有ddraw.h了,再使用ddraw是给自己找麻烦,所以我将使用D3D,但只使用其获得表面地址。因此我将完全抛弃硬件加速,但也反而更可以了解硬件加速到底都在做什么。PS:D3D的初始化的能力更强大,在ddraw时,我们还需要重新调整窗口大小,并且每次写入像素时,还要考虑到窗口边框所造成的像素偏移,而在D3D的初始化时都已经做好了。
3. 约定与配置
对于这个图形库,我们有以下几个约定:
1) 支持Unicode
2) 窗口程序,方便调试
3) 屏幕色深32BPP
4) 加载的位图均为24位位图
5) 基于X86系统
需要配置的就只有2个地方:
1) 在VC++ Directories的Include和Lib中加入DirectX SDK相应目录
2) Linker的Input加入d3d9.lib和d3dx9.lib
4. 项目框架
这是我们要在项目中用到的文件:

3DConsole:我们实验的控制台
3DLib:3D相关的函数,也包含了D3D表面的相关控制
Math:数学库
Diagnosis:诊断库,用于生成一些日志
Helper:辅助函数库,比如读写文件等
Math、Diagnosis、Helper今天没有用到,空着而已。
3DConsole,要负责创建窗口、系统消息的循环等一般Win32程序的工作,并在其中适当的位置插入Game_Init()、Game_Main()、Game_Shutdown()方法的调用。这些一看代码便知,这里另外做了一些计时的工作,以将输出锁定到一定的帧数,并且在空闲时也不会总会去做判断而跑满CPU。计时器代码如下:
// 函数定义
DWORD GetClock()
{
return GetTickCount();
} void StartClock()
{
g_Clock = GetClock();
} void WaitClock()
{
while((GetClock() - g_Clock) < WAIT_TIME)
{
Sleep(5);
}
}
3DLib,本文实现了对D3D的初始化,并实现了绘制一个像素的代码,代码中有注释:
#include "CPPYIN.3DLib.h" bool _CPPYIN_3DLib::Init3DLib(HINSTANCE hInstance, HWND hWnd, int width, int height)
{
IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION); D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.Windowed = TRUE;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice);
d3d9->Release(); pDevice->CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface, 0); return true;
} int _CPPYIN_3DLib::DrawPixel(int x,int y, DWORD color)
{
// 创建并初始化锁定区域
D3DLOCKED_RECT lr;
memset(&lr, 0, sizeof(lr)); // 锁定
pSurface->LockRect(&lr,NULL,D3DLOCK_DISCARD); // 像素着色
DWORD* pBits = (DWORD*)lr.pBits;
pBits[x + y * (lr.Pitch >> 2)] = color; // 解锁
pSurface->UnlockRect(); return 1;
} void _CPPYIN_3DLib::FlipSurface()
{
// 获取后台缓存
IDirect3DSurface9* backBuffer = 0;
pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer); // 使用自定义表面填充后台缓存
pDevice->StretchRect(pSurface, 0, backBuffer, 0, D3DTEXF_NONE); // GetBackBuffer所得的缓存需要被释放,否则会内存泄露
backBuffer->Release(); // 将交换链中的后台缓存显示
pDevice->Present(0, 0, 0, 0);
} void _CPPYIN_3DLib::Release3DLib()
{
pSurface->Release();
pDevice->Release();
}
【转载】从零实现3D图像引擎:(1)环境配置与项目框架的更多相关文章
- 【转载】从零实现3D图像引擎:(2)画2D直线不简单
原文:从零实现3D图像引擎:(2)画2D直线不简单 1. 数学分析 1) 画直线的问题 本来我以为画直线会很容易,随便拿个直线公式,遍历X求Y画出来不就完了么,但事实并非如此.以2D直线为例,因为3D ...
- Activiti6.0 spring5 工作流引擎 java SSM流程审批 项目框架
1.模型管理 :web在线流程设计器.预览流程xml.导出xml.部署流程 2.流程管理 :导入导出流程资源文件.查看流程图.根据流程实例反射出流程模型.激活挂起 3.运行中流程:查看流程信息.当前任 ...
- 转载:[转]如何学好3D游戏引擎编程
[转]如何学好3D游戏引擎编程 Albert 本帖被 gamengines 从 游戏引擎(Game Engine) 此文为转载,但是值得一看. 此篇文章献给那些为了游戏编程不怕困难的热血青年,它的 ...
- 棒!使用.NET Core构建3D游戏引擎
原文地址:https://mellinoe.wordpress.com/2017/01/18/net-core-game-engine/ 作者:ERIC MELLINO 翻译:杨晓东(Savorboa ...
- achartengine andorid图像引擎入门
最近在帮机械学院开发一个app 用了第三方的图像引擎——achartengine功能还算强大(虽然相比于Html那些第三方图像引擎还是差点不过也够用了) 入门: 参考http://blog.csdn. ...
- 排名前10的H5、Js 3D游戏引擎和框架
由于很多人都在用JavaScript.HTML5和WebGL技术创建基于浏览器的3D游戏,所有JavaScript 3D游戏引擎是一个人们主题.基于浏览器的游戏最棒的地方是平台独立,它们能在iOS.A ...
- 全息眼镜HoloLens可快速捕捉真人3D图像
http://www.d9soft.com/zixun/62287.html 北京时间3月28日午间消息,微软研发部门开发出一种新的3D视频捕捉系统“Holoportation”,可以实现将某人3D图 ...
- C++ 3D物理引擎库BulletPhysics基本使用
前言:最近在接触OpenGl和DX11的时候,顺便学习了Bullet这个3D物理引擎的基本使用,记录一下. |BulletPhysics介绍 BulletPhysics是一个跨平台的开源物理引擎,也是 ...
- Python 画3D图像
绘制一副3D图像 draw3D(X,Y,Z, angle) import numpy as np from matplotlib import pyplot as plt from mpl_toolk ...
随机推荐
- codeforces 917D Stranger Trees
题目链接 正解:矩阵树定理+拉格朗日插值. 一下午就搞了这一道题,看鬼畜英文题解看了好久.. 首先这题出题人给了两种做法,感觉容斥+$prufer$序列+$dp$的做法细节有点多所以没看,然而这个做法 ...
- MySQL查询时强制区分大写和小写
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zyb_icanplay7/article/details/24981791 平时非常少会考虑数据存储 ...
- Hive分区表创建,增加及删除
1.创建Hive分区表,按字段分区 CREATE TABLE test1 ( id bigint , create_time timestamp , user_id string) partition ...
- oracle数据库之用户管理
转载 Oracle创建用户.角色.授权.建表 一.oracle数据库的权限系统分为系统权限与对象权限: 系统权限( database system privilege )可以让用户执行特定的命令集 ...
- 深入学习c++--重新审视auto
1. auto推断变量类型 2. auto遍历 3. 自定义类可使用auto
- Observer(观察者)模式
1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来说,当某个对象的状态发生改变时,你仍然需要对象之间能互相通信.但是 ...
- mysql 全量备份与增量备份
全量备份[root@master adm]# cat DBfullBak.sh #!/bin/bash #use mysqldump to fully backup mysql data BakDir ...
- ES6读书笔记(二)
前言 前段时间整理了ES6的读书笔记:<ES6读书笔记(一)>,现在为第二篇,本篇内容包括: 一.数组扩展 二.对象扩展 三.函数扩展 四.Set和Map数据结构 五.Reflect 本文 ...
- DDL-常见的约束
一.常见的约束NOT NULL:非空,该字段的值必填UNIQUE:唯一,该字段的值不可重复DEFAULT:默认,该字段的值不用手动插入有默认值CHECK:检查,mysql不支持PRIMARY KEY: ...
- putty登录出现access denied的解决办法
[转]https://www.aliyun.com/jiaocheng/152659.html 在/etc/ssh/sshd_config 中有个 PermitRootLogin, 改成“Permit ...