本篇笔记要实现的是在屏幕上渲染出一个三角形,重点要学习的是渲染一个几何体的流程方式。

为了渲染几何图形,需要一个顶点缓存和一个描述顶点布局的输入层,还有着色器(主要是顶点着色器和像素着色器),下面来看看具体Demo的实现。

新建一个Win32项目 ,新建一个类我们叫做TriangleDemo,继承自前面教程我们实现的基类Dx11DemoBase。

TriangleDemo.h头文件

#pragma once

#include "Dx11DemoBase.h"

class TriangleDemo : public Dx11DemoBase
{
public:
TriangleDemo();
~TriangleDemo(); bool LoadContent() override;
void UnLoadContent() override; void Update(float dt) override;
void Render() override; private:
ID3D11Buffer *m_pVertexBuffer;
ID3D11InputLayout *m_pInputLayout;
ID3D11VertexShader *m_pSolidColorVS;
ID3D11PixelShader *m_pSolidColorPS;
};

在类中添加了四个成员变量,用来保存着色器、顶点缓存和顶点布局的指针。

定义顶点结构体

#include "TriangleDemo.h"
#include <xnamath.h> struct VertexPos
{
XMFLOAT3 pos;
}; TriangleDemo::TriangleDemo()
: m_pInputLayout(), m_pVertexBuffer(), m_pSolidColorPS(), m_pSolidColorVS()
{
} TriangleDemo::~TriangleDemo()
{
} void TriangleDemo::UnLoadContent()
{
if (m_pSolidColorPS)
m_pSolidColorPS->Release();
if (m_pSolidColorVS)
m_pSolidColorVS->Release();
if (m_pVertexBuffer)
m_pVertexBuffer->Release();
if (m_pInputLayout)
m_pInputLayout->Release();
m_pSolidColorVS = ;
m_pSolidColorPS = ;
m_pVertexBuffer = ;
m_pInputLayout = ;
}

着色器的加载

为了方便我们在基类中定义了一个CompileD3DShader函数实现加载着色器文本的功能,具体实现如下

bool Dx11DemoBase::CompileD3DShader(char* filePath, char* entry, char* shaderModel, ID3DBlob** buffer)
{
DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined _DEBUG || defined DEBUG
shaderFlags = D3DCOMPILE_DEBUG;
#endif ID3DBlob *errorBuffer = ;
HRESULT result; result = D3DX11CompileFromFile(filePath, , , entry, shaderModel, shaderFlags, , , buffer, &errorBuffer,); if (FAILED(result))
{
if (errorBuffer != )
{
OutputDebugString((char*)errorBuffer->GetBufferPointer());
errorBuffer->Release();
}
return false;
} if (errorBuffer != )
{
return false;
} return true;
}

具体加载着色器的代码我们写在LoadContent函数中,下面是该函数的一部分代码

 //载入顶点着色器
ID3DBlob *vsBuffer = ;
bool compileResult = CompileD3DShader("SolidColor.fx", "VS_Main", "vs_4_0", &vsBuffer);
if (!compileResult)
{
MessageBox(, "载入顶点着色器错误", "编译错误", MB_OK);
return false;
} HRESULT result;
result = m_pd3dDevice->CreateVertexShader(vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(),
, &m_pSolidColorVS); if (FAILED(result))
{
if (vsBuffer)
{
vsBuffer->Release();
}
return false;
} D3D11_INPUT_ELEMENT_DESC solidColorLayout[] =
{
{"POSITION",,DXGI_FORMAT_R32G32B32_FLOAT,,,D3D11_INPUT_PER_VERTEX_DATA,}
}; UINT numLayoutElements = ARRAYSIZE(solidColorLayout);
result = m_pd3dDevice->CreateInputLayout(solidColorLayout, numLayoutElements, vsBuffer->GetBufferPointer(),
vsBuffer->GetBufferSize(), &m_pInputLayout);
vsBuffer->Release(); if (FAILED(result))
{
return false;
} //载入像素着色器
ID3DBlob *psBuffer = ;
compileResult = CompileD3DShader("SolidColor.fx", "PS_Main", "ps_4_0", &psBuffer);
if (!compileResult)
{
MessageBox(, "像素着色器加载失败", "编译错误", MB_OK);
return false;
} result = m_pd3dDevice->CreatePixelShader(psBuffer->GetBufferPointer(), psBuffer->GetBufferSize(),
, &m_pSolidColorPS);
psBuffer->Release();
if (FAILED(result))
{
return false;
}

其中输入布局信息D3D11_INPUT_ELEMENT_DESC

(A description of a single element for the input-assembler stage.)

定义如下

typedef struct D3D11_INPUT_ELEMENT_DESC {
LPCSTR SemanticName;
UINT SemanticIndex;
DXGI_FORMAT Format;
UINT InputSlot;
UINT AlignedByteOffset;
D3D11_INPUT_CLASSIFICATION InputSlotClass;
UINT InstanceDataStepRate;
} D3D11_INPUT_ELEMENT_DESC;

顶点信息生成及处理

TriangleDemo::LoadContent() 的 上半部分完成了 inputlayout 和 shader, 剩下的就是 vertex 这些顶点的生成及处理了。

三角形的顶点列表 vertex list 存放处在 vertices数组里, 同时这个vertices 也作为 创建vertex buffer函数CreateBuffer()的参数之一:Subresource data。

下面是LoadContent()的另外一部分代码:

 VertexPos vertices[]  =
{
XMFLOAT3(0.5f, 0.5f, 0.5f),
XMFLOAT3(0.5f, -0.5f, 0.5f),
XMFLOAT3(-0.5f,-0.5f,0.5f)
}; D3D11_BUFFER_DESC vertexDesc;
ZeroMemory(&vertexDesc, sizeof(vertexDesc));
vertexDesc.Usage = D3D11_USAGE_DEFAULT;
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexDesc.ByteWidth = sizeof(VertexPos)* ; D3D11_SUBRESOURCE_DATA resourceData;
ZeroMemory(&resourceData, sizeof(resourceData));
resourceData.pSysMem = vertices; result = m_pd3dDevice->CreateBuffer(&vertexDesc, &resourceData, &m_pVertexBuffer);
if (FAILED(result))
{
return false;
} return true;

其中D3D11_BUFFER_DESC定义如下:

typedef struct D3D11_BUFFER_DESC {
UINT ByteWidth;
D3D11_USAGE Usage;
UINT BindFlags;
UINT CPUAccessFlags;
UINT MiscFlags;
UINT StructureByteStride;
} D3D11_BUFFER_DESC;

D3D11_SUBRESOURCE_DATA定义如下:

typedef struct D3D11_SUBRESOURCE_DATA {
const void *pSysMem;
UINT SysMemPitch;
UINT SysMemSlicePitch;
} D3D11_SUBRESOURCE_DATA;

渲染几何体

剩下代码是渲染几何体和 shaders 。我们在TriangleDemo::Render() 函数进行渲染几何体的工作

 void TriangleDemo::Render()
{
if (m_pImmediateContext == )
return;
//清除渲染目标视图
float clearColor[] = { 0.5f, 0.5f, 0.5f, 1.0f };//背景颜色
m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, clearColor); UINT stride = sizeof(VertexPos);
UINT offset = ;
//设置数据信息格式控制信息
m_pImmediateContext->IASetInputLayout(m_pInputLayout);
//设置要绘制的几何体信息
m_pImmediateContext->IASetVertexBuffers(,,&m_pVertexBuffer,&stride,&offset);
//指明如何绘制三角形
m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_pImmediateContext->VSSetShader(m_pSolidColorVS, , );
m_pImmediateContext->PSSetShader(m_pSolidColorPS, , );
m_pImmediateContext->Draw(, );
//马上输出
m_pSwapChain->Present(, );
}

着色器.fx文件代码

float4 VS_Main( float4 pos : POSITION ) : SV_POSITION  

{
return pos; } float4 PS_Main( float4 pos : SV_POSITION ) : SV_TARGET { return float4( 1.0f, 0.0f, 0.0f, 1.0f ); }

我们使用的vertex shader很简单的, 仅仅是传递输入的顶点坐标到输出设备;

pixel shader的工作也很简单, 仅仅是 为每个 像素pixel 配置一种固定的颜色( 红色)。

最终效果图

Directx11学习笔记【十】 画一个简单的三角形的更多相关文章

  1. Directx11学习笔记【十一】 画一个简单的三角形--effect框架的使用

    这里不再介绍effect框架的具体使用,有关effect框架使用可参考http://www.cnblogs.com/zhangbaochong/p/5475961.html 实现的功能依然是画一个简单 ...

  2. Directx11教程(6) 画一个简单的三角形(2)

    原文:Directx11教程(6) 画一个简单的三角形(2)      在上篇教程中,我们实现了在D3D11中画一个简单的三角形,但是,当我们改变窗口大小时候,三角形形状却随着窗口高宽比例改变而改变, ...

  3. Directx11教程(5) 画一个简单的三角形(1)

    原文:Directx11教程(5) 画一个简单的三角形(1)       在本篇教程中,我们将通过D3D11画一个简单的三角形.在D3D11中,GPU的渲染主要通过shader来操作(当然还有一些操作 ...

  4. OpenGL学习笔记(1) 画一个三角形

    最近找实习有一丢丢蛋疼,沉迷鬼泣5,四周目通关,又不想写代码,写篇笔记复习一下,要好好学图形学啊 用OpenGL画一个三角形 项目的简介 记录一下跟着learnOpenGL学习的过程 笔记里的代码放在 ...

  5. Linux系统学习笔记之 1 一个简单的shell程序

    不看笔记,长时间不用自己都忘了,还是得经常看看笔记啊. 一个简单的shell程序 shell结构 1.#!指定执行脚本的shell 2.#注释行 3.命令和控制结构 创建shell程序的步骤 第一步: ...

  6. 【opencv学习笔记五】一个简单程序:图像读取与显示

    今天我们来学习一个最简单的程序,即从文件读取图像并且创建窗口显示该图像. 目录 [imread]图像读取 [namedWindow]创建window窗口 [imshow]图像显示 [imwrite]图 ...

  7. Django 学习笔记之六 建立一个简单的博客应用程序

    最近在学习django时建立了一个简单的博客应用程序,现在把简单的步骤说一下.本人的用的版本是python 2.7.3和django 1.10.3,Windows10系统 1.首先通过命令建立项目和a ...

  8. OpenGL学习笔记(2) 画一个正方形

    画一个正方形 其实,画正方形就是画两个三角形,用四个顶点以及使用索引来实现 完整代码在Square项目的Application.cpp里 先贴上窗口初始化代码 void BaseInit() { gl ...

  9. [原创]java WEB学习笔记12:一个简单的serlet连接数据库实验

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  10. UNP学习笔记2——从一个简单的ECHO程序分析TCP客户/服务器之间的通信

    1 概述 编写一个简单的ECHO(回复)程序来分析TCP客户和服务器之间的通信流程,要求如下: 客户从标准输入读入一行文本,并发送给服务器 服务器从网络输入读取这个文本,并回复给客户 客户从网络输入读 ...

随机推荐

  1. 为什么国外程序员爱用苹果Mac电脑?(转)

    Mac 在国外很受欢迎,尤其是在 设计/web开发/IT 人员圈子里.普通用户喜欢 Mac 可以理解,毕竟 Mac 设计美观,简单好用,没有病毒.那么为什么专业人士也对 Mac 情有独钟呢?从个人使用 ...

  2. [置顶] think in java interview-高级开发人员面试宝典(七)

    上两周研发任务太紧了,所以担搁了一下,我们继续我们的面试之旅. 下面是一个基于图书系统的15道SQL问答,供大家参考 问题描述:本题用到下面三个关系表:CARD     借书卡.   CNO 卡号,N ...

  3. 下载jdk文件后缀是.gz而不是.tar.gz怎么办

    用chrom浏览器下载了linux版的jdk,发现文件后缀是.gz,没看过这玩意,一打开,还是一个.gz文件,原本以为是新文件后缀呢.那个百度google啊. . ..最后都没发现有这方面的资料啊.. ...

  4. poj2528(线段树)

    题目连接:http://poj.org/problem?id=2528 题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报 分析:离散化+线段树,这题因为每个数字其实表示的是一个单位长度,因 ...

  5. 低版本的 opencv库的 vs2010 打开 高版本opencv

    打开track.vcxproj文件, 注释掉跟版本有关的行就可. 本例子中,当用双击.sln用vs2010打开高版本的opencv项目时,会出现错误, 并且会有错误信息提示,双击该错误信息,就会打开该 ...

  6. HTML中的div标签

    在网页制作过程过中,能够把一些独立的逻辑部分划分出来.放在一个<div>标签中,这个<div>标签的作用就相当于一个容器. 为了使逻辑更加清晰,我们能够为这一个独立的逻辑部分设 ...

  7. Linux进程同步之记录锁(fcntl)

    记录锁相当于线程同步中读写锁的一种扩展类型,可以用来对有亲缘或无亲缘关系的进程进行文件读与写的同步,通过fcntl函数来执行上锁操作.尽管读写锁也可以通过在共享内存区来进行进程的同步,但是fcntl记 ...

  8. PHP实现冒泡排序、双向冒泡排序算法

    冒泡排序(Bubble Sort),是一种较简单的.稳定的排序算法.冒泡排序算法步骤:比较相邻的元素,如果第一个比第二个大,就交换他们两个的位置:对每对相邻的元素执行同样的操作,这样一趟下来,最后的元 ...

  9. SSL与TLS的区别以及介绍(转)

    SSL:(Secure Socket Layer,安全套接字层),位于可靠的面向连接的网络层协议和应用层协议之间的一种协议层.SSL通过互相认证.使用数字签名确保完整性.使用加密确保私密性,以实现客户 ...

  10. EF 执行视图

    IEnumerable<V_stocks> summary = db.Database.SqlQuery<V_stocks>("SELECT * FROM dbo.V ...