DirectX10 龙书笔记- 一个颜色立方体程序

这篇是作为学习笔记之用,详细代码在Introduction to 3D Game Programming with Directx10里面的扉页,有个网址 www.d3dcoder.net 里面可以下载

这个程序的效果是:

这个demo展示了基本的directx基本的渲染流程.

首先是渲染管线: 它的作用是根据虚拟摄像机视角生成2D图像的基本步骤.

主要是类为ColoredCubeApp

class ColoredCubeApp : public D3DApp
{
public:
	ColoredCubeApp(HINSTANCE hInstance);
	~ColoredCubeApp();

	void initApp();  //初始化
	void onResize(); //窗口大小变化时候调用
	void updateScene(float dt); //每一帧调用,负责更新参数
	void drawScene(); //每一帧调用,负责绘制

private:
	void buildFX(); //着色器
	void buildVertexLayouts(); //输入汇编器,构建图元

private:

	Box mBox;

	ID3D10Effect* mFX;
	ID3D10EffectTechnique* mTech;
	ID3D10InputLayout* mVertexLayout;
	ID3D10EffectMatrixVariable* mfxWVPVar;

	D3DXMATRIX mView;
	D3DXMATRIX mProj;
	D3DXMATRIX mWVP;

	float mTheta;
	float mPhi;
};

这个类中的initAPP()为初始化渲染做准备

void ColoredCubeApp::initApp()
{
	D3DApp::initApp();
	mBox.init(md3dDevice, 0.3f);  //这个是所要创建立方体的初始化。 提供了顶点缓冲区,和索引缓冲区
	buildFX(); //这个是顶点着色器、几何着色器、像素着色器的配置
	buildVertexLayouts();//根据以上信息构建图元
}
下面看具体mBox.init是怎么初始化立方体的
void Box::init(ID3D10Device* device, float scale)
{
	md3dDevice = device;

	mNumVertices = 8;
	mNumFaces    = 12; // 2 per quad

	// Create vertex buffer
    Vertex vertices[] =
    {
		{D3DXVECTOR3(-1.0f, -1.0f, -1.0f), WHITE},
		{D3DXVECTOR3(-1.0f, +1.0f, -1.0f), BLACK},
		{D3DXVECTOR3(+1.0f, +1.0f, -1.0f), RED},
		{D3DXVECTOR3(+1.0f, -1.0f, -1.0f), GREEN},
		{D3DXVECTOR3(-1.0f, -1.0f, +1.0f), BLUE},
		{D3DXVECTOR3(-1.0f, +1.0f, +1.0f), YELLOW},
		{D3DXVECTOR3(+1.0f, +1.0f, +1.0f), CYAN},
		{D3DXVECTOR3(+1.0f, -1.0f, +1.0f), MAGENTA},
    };

	// Scale the box.
	for(DWORD i = 0; i < mNumVertices; ++i)
		vertices[i].pos *= scale;

	//顶点缓冲区
    D3D10_BUFFER_DESC vbd;
    vbd.Usage = D3D10_USAGE_IMMUTABLE;
    vbd.ByteWidth = sizeof(Vertex) * mNumVertices;
    vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA vinitData;
    vinitData.pSysMem = vertices;
    HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mVB));

	// Create the index buffer
    //索引缓冲区
	DWORD indices[] = {
		// front face
		0, 1, 2,
		0, 2, 3,

		// back face
		4, 6, 5,
		4, 7, 6,

		// left face
		4, 5, 1,
		4, 1, 0,

		// right face
		3, 2, 6,
		3, 6, 7,

		// top face
		1, 5, 6,
		1, 6, 2,

		// bottom face
		4, 0, 3,
		4, 3, 7
	};

	D3D10_BUFFER_DESC ibd;
    ibd.Usage = D3D10_USAGE_IMMUTABLE;
    ibd.ByteWidth = sizeof(DWORD) * mNumFaces*3;
    ibd.BindFlags = D3D10_BIND_INDEX_BUFFER;
    ibd.CPUAccessFlags = 0;
    ibd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA iinitData;
    iinitData.pSysMem = indices;
    HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mIB));
}

从以上可知,主要作用就是先构建所需要的不重复的点,然后构建一个立方体索引点(索引是为了节约资源,不必再重复构建点)。

下面看buildFX() 里面的内容

hr =
D3DX10CreateEffectFromFile(L"color.fx", 0, 0,

"fx_4_0",shaderFlags, 0,
md3dDevice,0, 0, &mFX, &compilationErrors,0);

主要为这一句。

其中color.fx 是一个文本文件

//=============================================================================
// color.fx by Frank Luna (C) 2008 All Rights Reserved.
//
// Transforms and colors geometry.
//=============================================================================

cbuffer cbPerObject
{
	float4x4 gWVP;
};

void VS(float3 iPosL  : POSITION,
        float4 iColor : COLOR,
        out float4 oPosH  : SV_POSITION,
        out float4 oColor : COLOR)
{
	// Transform to homogeneous clip space.
	oPosH = mul(float4(iPosL, 1.0f), gWVP);

	// Just pass vertex color into the pixel shader.
    oColor = iColor;
}

float4 PS(float4 posH  : SV_POSITION,
          float4 color : COLOR) : SV_Target
{
    return color;
}

technique10 ColorTech
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}
以上可以看成类c++的文件,就是定义一组操作。
然后通过
void ColoredCubeApp::buildVertexLayouts()
{
	// Create the vertex input layout.
	D3D10_INPUT_ELEMENT_DESC vertexDesc[] =
	{
		{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
		{"COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0}
	};

	// Create the input layout
    D3D10_PASS_DESC PassDesc;
    mTech->GetPassByIndex(0)->GetDesc(&PassDesc);
    HR(md3dDevice->CreateInputLayout(vertexDesc, 2, PassDesc.pIAInputSignature,
		PassDesc.IAInputSignatureSize, &mVertexLayout));
}

上面这个函数调用color.fx里面相应的操作函数实现图元的构建。

准备工作完成了。现在就是绘制过程了

void ColoredCubeApp::drawScene()
{
	D3DApp::drawScene();

	// Restore default states, input layout and primitive topology
	// because mFont->DrawText changes them.  Note that we can
	// restore the default states by passing null.
	//md3dDevice->OMSetDepthStencilState(0, 0);
	float blendFactors[] = {0.0f, 0.0f, 0.0f, 0.0f};
	//md3dDevice->OMSetBlendState(0, blendFactors, 0xffffffff);
    md3dDevice->IASetInputLayout(mVertexLayout);
	//图ª?元a列¢D表À¨ª-三¨y角?形?
    md3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP);

	// set constants
	mWVP = mView*mProj;
	mfxWVPVar->SetMatrix((float*)&mWVP);

    D3D10_TECHNIQUE_DESC techDesc;
    mTech->GetDesc( &techDesc );
    for(UINT p = 0; p < techDesc.Passes; ++p)
    {
        mTech->GetPassByIndex( p )->Apply(0);//更¨¹新?GPU 常¡ê量¢?缓o冲?区?,ê?将?着Á?色¦?器¡Â绑㨮定¡§到Ì?管¨¹线?,ê?启?动¡¥pass

		mBox.draw();
    }

	mSwapChain->Present(0, 0);
}

void ColoredCubeApp::updateScene(float dt)
{
	D3DApp::updateScene(dt);

	// Update angles based on input to orbit camera around box.
	if(GetAsyncKeyState('A') & 0x8000)	mTheta -= 2.0f*dt;
	if(GetAsyncKeyState('D') & 0x8000)	mTheta += 2.0f*dt;
	if(GetAsyncKeyState('W') & 0x8000)	mPhi -= 2.0f*dt;
	if(GetAsyncKeyState('S') & 0x8000)	mPhi += 2.0f*dt;

	// Restrict the angle mPhi.
	if( mPhi < 0.1f )	mPhi = 0.1f;
	if( mPhi > PI-0.1f)	mPhi = PI-0.1f;

	// Convert Spherical to Cartesian coordinates: mPhi measured from +y
	// and mTheta measured counterclockwise from -z.
	float x =  5.0f*sinf(mPhi)*sinf(mTheta);
	float z = -5.0f*sinf(mPhi)*cosf(mTheta);
	float y =  5.0f*cosf(mPhi);

	// Build the view matrix.   观?察¨¬者?到Ì?世º¨¤界?的Ì?矩?阵¨®
	D3DXVECTOR3 pos(x, y, z);
	D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
	D3DXMatrixLookAtLH(&mView, &pos, &target, &up);
}

目前还只是第一个比较完整的demo 细节代码很多还没有理解透彻。我们能了解个大概流程就可以啦。后面会越学越懂的

时间: 2024-08-08 20:22:11

DirectX10 龙书笔记- 一个颜色立方体程序的相关文章

Directx10 龙书笔记- 雾效的实现

雾 : 说白了就是一层有颜色的(一般是白色,灰色) 蒙蒙的感觉 混在光线里面. 不管是白天还是黑天. 龙书里面是这样实现的: 1.  给雾定义一个颜色 float3 gFogColor={0.7f,0.7f,0.7f}; 2. 然后呢在顶点着色器里面计算出 顶点级别的雾化需要的颜色加成比例 加成比例: 意思是当距离摄像机,就是你的眼睛越远,雾的浓度越大,就是颜色越深. 根据这个得出一个(0,1)的和距离有关的比例系数 vout.fogLerp = saturate((d-gFogStart)/g

Directx10 龙书笔记- 第7章课后题 实现火焰动画

火焰的图片我是没找到,找到了几张雷电的,就在d3dcoder.net 的directx10那本书代码下载的Bolt Animations for Chapter 9  里面 里面很多张图片,由于c++也是初学,一时来不及弄字符串拼接的函数. 只能定义很多个帧bmp 然后一个一个载入了 具体代码是建立在那个"crate" 例子工程, 就是那个木箱子的代码基础上. 添加的代码如下: ID3D10ShaderResourceView* mDiffusePic[9]; 我定义了一个能装9张图片

【龙书笔记】编译器简介及程序构建过程综述

备注:本文是近期重新阅读编译器经典教材<Compilers Principles, Techniques, & Tools>一书(又称DragonBook,龙书)的其中一篇读书笔记. 1. 什么是编译器 从本质来看,平时提到的"编程语言"其实都是一些助记符,用于向其他人或机器描述我们想要完成的逻辑运算.这些易于人类理解的语言想要被计算机理解并正确执行,就必须被转换成机器码,而完成这一转换过程的软件系统就是编译器. 简言之,编译器其实也是一个计算机程序,它可以读取用一

【龙书笔记】用Python实现一个简单数学表达式从中缀到后缀语法的翻译器(采用递归下降分析法)

上篇笔记介绍了语法分析相关的一些基础概念,本篇笔记根据龙书第2.5节的内容实现一个针对简单表达式的后缀式语法翻译器Demo. 备注:原书中的demo是java实例,我给出的将是逻辑一致的Python版本的实现. 在简单后缀翻译器代码实现之前,还需要介绍几个基本概念. 1. 自顶向下分析法(top-down parsing) 顾名思义,top-down分析法的思路是推导产生式时,以产生式开始符号作为root节点,从上至下依次构建其子节点,最终构造出语法分析树.在具体实现时,它会把输入字符串从左到右

【龙书笔记】语法分析涉及的基础概念简介

本篇笔记是我对龙书第2.3-2.5节内容的理解,主要介绍编译器前端关于语法分析的众多基础概念.下篇笔记将根据本篇笔记的主要内容,实现一个针对简单表达式的后缀式语法翻译器Demo(原书中是java实例,我给出的将是逻辑一致的Python版本的实现). 1. 语法分析(Syntax Analysis) 简单来说,语法分析的任务是分析输入的符号字符串(string of symbols, 通常是词法分析产生的tokens)是否遵循某种语言在其上下文无关文法(context-free grammar)中

编译原理 龙书 第二章 一个简单的算术式(+,-)翻译器实现

昨天晚上决定正面硬刚神课<编译原理>.硬上龙书. 下面是 一个简单的算术式中缀变后缀的翻译器. 这个也是 龙书中 一个C实现源码 .部分用c++改写. #include <iostream> #include <ctype.h> #include <stdlib.h> #include <stdio.h> using namespace std; int lookahead; void error()//错误处理 { cout<<&q

龙书学习笔记(三)

在将第五章每个示例代码过了一遍之后,大致明白了光照这一章的内容,主要分为四点: 一.光照的类型分为三种,并且均通过结构D3DCOLORVALUE或D3DXCOLOR来表示光线的颜色 环境光(Ambient Light)经其它表面反射到达物体表面,并照亮整个场景,通常用做较低代价的粗略模拟. 漫射光(Diffuse Light)沿着特定的方向传播,到达某个表面后将沿着各个方向均匀反射,因此从各个方向观察物体表面亮度均相同. 镜面光(Specular Light)沿着特定的方向传播,到达一表面后将沿

龙书学习笔记(二)

补线代之余抽空把第四章上色学了,之所以说之余,是因为这一章内容确实不怎么多,不过为了巩固知识,便结合刚学的上色又做了一个小程序. 首先进行回顾,这一章学到的一共有四点: 一.Direct3D中颜色用RGB(Red.Green.Blue)三元组表示,用两种结构来保存 D3DCOLOR,即unsigned long,共32位,分成4个8位项,分别保存Alpha(这玩意的作用会在第七章学到).红.绿.蓝,均在0x00~0xff之间取值(就是0~255) 通过结构体来保存(D3DXCOLOR和D3DCO

一个合格的程序员应该读过哪些书

编者按:2008年8月4日,StackOverflow 网友 Bert F 发帖提问:哪本最具影响力的书,是每个程序员都应该读的? “如果能时光倒流,回到过去,作为一个开发人员,你可以告诉自己在职业生涯初期应该读一本,你会选择哪本书呢?我希望这个书单列表内容丰富,可以涵盖很多东西.” 很多程序员响应,他们在推荐时也写下自己的评语.以前就有国内网友介绍这个程序员书单,不过都是推荐数 Top 10的书. 其实除了前10本之外,推荐数前30左右的书籍都算经典,笔者整理编译这个问答贴,同时摘译部分推荐人