【寒江雪】Direct3D11纹理贴图

来源:互联网 发布:nginx 图片服务器架构 编辑:程序博客网 时间:2024/04/20 07:26

  今天是元旦节,先祝大家节日快乐.由于准备要交一个游戏,对老师代码的梳理要拉得比较快,因此有许多疏漏的地方,还请大家指出,从错误中可以学到更多的东西,知不足而改进。
  光线进入人眼,人们可以看到这个世界。而纹理则定义了这个世界长的样子。在Direct3D中,给物体增加纹理贴图,使物体多姿多彩。在介绍如何在程序中添加纹理贴图之前,先介绍纹理贴图的基础知识,在学习Direct3D9的过程中,我初步了解了一些贴图的知识,并把学到的东西总结成知识点在以下这篇文章当中:


http://blog.csdn.net/lkysyzxz/article/details/53817343

  下面着重讲解Direct3D11可编程渲染管线中是如何给物体增加纹理贴图的.

加载贴图文件

  在Direct3D11的程序中,我们得先定义ID3D11ShaderResourceView来保存贴图资源.
  紧接着,我们通过D3DX11CreateShaderResourceViewFromFile函数来将图形文件载入内存。该函数的
原型如下:

HRESULT D3DX11CreateShaderResourceViewFromFile(  _In_  ID3D11Device             *pDevice,  _In_  LPCTSTR                  pSrcFile,  _In_  D3DX11_IMAGE_LOAD_INFO   *pLoadInfo,  _In_  ID3DX11ThreadPump        *pPump,  _Out_ ID3D11ShaderResourceView **ppShaderResourceView,  _Out_ HRESULT                  *pHResult);
  • ID3D11Device *pDevice:这是设备接口指针,就是初始化的时候创建的
  • LPCTSTR pSrcFile:这是文件名,就是我们贴图文件的文件名
  • D3DX11_IMAGE_LOAD_INFO *pLoadInfo:定义加载图片的信息,基本上是宽度高度,深度等信息,一般设为NULL即可.
  • ID3DX11ThreadPump *pPump:加载纹理的线程,设为NULL表示不需要其他线程来执行该操作.
  • ID3D11ShaderResourceView **ppShaderResourceView:调用这个函数就是为了初始化这个参数,填我们定义的ID3D11ShaderResourceView接口指针的地址,用于管理加载的纹理.
  • HRESULT *pHResult:如果使用另外一个线程加载该资源,并且需要返回值的时候,就将返回值的地址填设置为这个参数。

  下面是一个调用示例:

hr=D3DX11CreateShaderResourceViewFromFile(d3dSys->D3DDevice(),L".//res//BOX.bmp", NULL, NULL, &m_pTexture, NULL);        if (FAILED(hr)) {            return hr;        }

定义顶点结构

  为了使用纹理,顶点的结构就有所改变.多增加了一个纹理坐标

struct Vertex {    XMFLOAT3 Position;    XMFLOAT3 Norm;    XMFLOAT2 Tex;  //新增加的纹理坐标};

  在Effect文件中也要做相应的修改,创建输入布局的时候,对各参数的描述也要做相应的修改.

//顶点着色器的输入结构struct VS_INPUT{    float4 Pos : POSITION;   //顶点坐标    float3 Norm : NORMAL;    //法向量    float2 Tex:TEXCOORD0;   //纹理坐标};//像素着色器的输入结构struct PS_INPUT{    float4 Pos : SV_POSITION;           //顶点坐标    float3 Norm : TEXCOORD0;            //法向量    float4 ViewDirection : TEXCOORD1;   //视点方向    float4 LightVector : TEXCOORD2;     //对点光源和聚光灯有效,                                        //前3各分量记录“光照向量”                                        //最后一个分量记录光照距离    float2 Tex:TEXCOORD3;   //纹理坐标};

  在Effect文件中添加纹理变量和设置采样器状态,通过设置这些参数可以提高采样精度:

Texture2D Texture;SamplerState Sampler{    Filter = MIN_MAG_MIP_LINEAR;    AddressU = WRAP;    AddressV = WRAP;};

  关于这些参数的设置可以参考MSDN的说明,也可以看一下我的另一篇笔记,不过后者对DX11的参考价值不大.


http://blog.csdn.net/lkysyzxz/article/details/53831813

  在顶点着色器和像素着色器中要添加一些代码.

//顶点着色器末尾output.Tex = input.Tex;//像素着色器末尾float4 TexColor = float4(1.0f, 1.0f, 1.0f, 1.0f);TexColor = Texture.Sample(Sampler, input.Tex);finalColor = TexColor*finalColor;finalColor.a = finalColor.a*TexColor.a;

示例程序核心代码

LightScene.h

#pragma once#include"dxUtil.h"#include"Light.h"struct Vertex {    XMFLOAT3 Position;    XMFLOAT3 Norm;    XMFLOAT2 Tex;};class Scene;class Cube;class Cube {private:    Material           m_Mat;    ID3D11Buffer      *m_pVertexBuffer;//顶点缓存    UINT               m_uStrid;    UINT               m_uOffset;    ID3D11Buffer      *m_pIndexBuffer;//索引缓存    XMFLOAT4X4 m_world; //物体的位置    ID3D11ShaderResourceView *m_pTexture;//纹理public:    Cube()        : m_pVertexBuffer(NULL), m_pIndexBuffer(NULL)    {        XMStoreFloat4x4(&m_world, XMMatrixIdentity());    }    ID3D11Buffer ** GetVertexBuffer() {        return &m_pVertexBuffer;    }    ID3D11Buffer *GetIndexBuffer() {        return m_pIndexBuffer;    }    UINT GetStrid() {        return m_uStrid;    }    UINT GetOffset() {        return m_uOffset;    }    Material GetMaterial(){        return m_Mat;    }    XMMATRIX GetWorldPosition() {        return XMLoadFloat4x4(&m_world);    }    HRESULT Init(DirectSystem* d3dSys) {        HRESULT hr;        Vertex vertices[] = {            { XMFLOAT3(1,1,1),XMFLOAT3(1,1,1),XMFLOAT2(0,0) },            { XMFLOAT3(-1,1,1),XMFLOAT3(-1,1,1),XMFLOAT2(1,0) },            { XMFLOAT3(-1,-1,1),XMFLOAT3(-1,-1,1),XMFLOAT2(1,1)},            { XMFLOAT3(1,-1,1),XMFLOAT3(1,-1,1),XMFLOAT2(0,1)},            { XMFLOAT3(1,1,-1),XMFLOAT3(1,1,-1),XMFLOAT2(0,0)},            { XMFLOAT3(-1,1,-1),XMFLOAT3(-1,1,-1),XMFLOAT2(1,0) },            { XMFLOAT3(-1,-1,-1),XMFLOAT3(-1,-1,-1),XMFLOAT2(1,1) },            { XMFLOAT3(1,-1,-1),XMFLOAT3(1,-1,-1),XMFLOAT2(0,1) },            { XMFLOAT3(1,1,1),XMFLOAT3(1,1,1),XMFLOAT2(0,0) },            { XMFLOAT3(-1,1,1),XMFLOAT3(-1,1,1),XMFLOAT2(3,0) },            { XMFLOAT3(-1,1,-1),XMFLOAT3(-1,1,-1),XMFLOAT2(3,3)},            { XMFLOAT3(1,1,-1),XMFLOAT3(1,1,-1),XMFLOAT2(0,3) },            { XMFLOAT3(1,-1,1),XMFLOAT3(1,-1,1),XMFLOAT2(0,0) },            { XMFLOAT3(-1,-1,1),XMFLOAT3(-1,-1,1),XMFLOAT2(1,0) },            { XMFLOAT3(-1,-1,-1),XMFLOAT3(-1,-1,-1),XMFLOAT2(1,1) },            { XMFLOAT3(1,-1,-1),XMFLOAT3(1,-1,-1),XMFLOAT2(0,1) },            { XMFLOAT3(-1,1,1),XMFLOAT3(-1,1,1),XMFLOAT2(0,0) },            { XMFLOAT3(-1,-1,1),XMFLOAT3(-1,-1,1),XMFLOAT2(1,0) },            { XMFLOAT3(-1,1,-1),XMFLOAT3(-1,1,-1),XMFLOAT2(0,1) },            { XMFLOAT3(-1,-1,-1),XMFLOAT3(-1,-1,-1),XMFLOAT2(1,1) },            { XMFLOAT3(1,1,1),XMFLOAT3(1,1,1),XMFLOAT2(0,0) },            { XMFLOAT3(1,-1,1),XMFLOAT3(1,-1,1),XMFLOAT2(1,0) },            { XMFLOAT3(1,1,-1),XMFLOAT3(1,1,-1),XMFLOAT2(0,1) },            { XMFLOAT3(1,-1,-1),XMFLOAT3(1,-1,-1),XMFLOAT2(1,1) }        };        WORD indexs[] =        {            0,1,2,            0,2,3,            4,6,5,            4,7,6,            8,10,9,            8,11,10,            12,13,14,            12,14,15,            16,18,19,            16,19,17,            20,21,23,            20,23,22        };        D3D11_BUFFER_DESC vertexBuffer;        ::ZeroMemory(&vertexBuffer, sizeof(vertexBuffer));        vertexBuffer.BindFlags = D3D11_BIND_VERTEX_BUFFER;        vertexBuffer.ByteWidth = sizeof(Vertex) * ARRAYSIZE(vertices);        vertexBuffer.CPUAccessFlags = 0;        vertexBuffer.Usage = D3D11_USAGE_DEFAULT;        D3D11_SUBRESOURCE_DATA initVertexData;        ::ZeroMemory(&initVertexData, sizeof(initVertexData));        initVertexData.pSysMem = vertices;        hr=d3dSys->D3DDevice()->CreateBuffer(&vertexBuffer, &initVertexData,&m_pVertexBuffer);        if (FAILED(hr))        {            return hr;        }        m_uStrid = sizeof(Vertex);        m_uOffset = 0;        D3D11_BUFFER_DESC indexBuffer;        ::ZeroMemory(&indexBuffer, sizeof(indexBuffer));        indexBuffer.BindFlags = D3D11_BIND_INDEX_BUFFER;        indexBuffer.ByteWidth = sizeof(WORD)*ARRAYSIZE(indexs);        indexBuffer.Usage = D3D11_USAGE_DEFAULT;        D3D11_SUBRESOURCE_DATA initIndexData;        ::ZeroMemory(&initIndexData, sizeof(initIndexData));        initIndexData.pSysMem = indexs;        hr=d3dSys->D3DDevice()->CreateBuffer(&indexBuffer, &initIndexData, &m_pIndexBuffer);        if (FAILED(hr)) {            return hr;        }        m_Mat.ambient = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);        m_Mat.diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);        m_Mat.specular = XMFLOAT4(1.0f, 1.0f, 1.0f,1.0f);        m_Mat.power = 5.0f;        hr=D3DX11CreateShaderResourceViewFromFile(d3dSys->D3DDevice(), L".//res//BOX.bmp", NULL, NULL, &m_pTexture, NULL);        if (FAILED(hr)) {            return hr;        }        return S_OK;    }    HRESULT SetCubeParm(DirectSystem *d3dSys,ID3DX11Effect *effect) {        d3dSys->D3DDeviceContext()->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &m_uStrid, &m_uOffset);        d3dSys->D3DDeviceContext()->IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);        d3dSys->D3DDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);        effect->GetVariableByName("World")->AsMatrix()->SetMatrix((float*)&m_world);        effect->GetVariableByName("MatAmbient")->AsVector()->SetFloatVector((float*)&m_Mat.ambient);        effect->GetVariableByName("MatDiffuse")->AsVector()->SetFloatVector((float*)&m_Mat.diffuse);        effect->GetVariableByName("MatSpecular")->AsVector()->SetFloatVector((float*)&m_Mat.specular);        effect->GetVariableByName("MatPower")->AsScalar()->SetFloat(m_Mat.power);        effect->GetVariableByName("Texture")->AsShaderResource()->SetResource(m_pTexture);        return S_OK;    }    VOID Update(float deltaTime) {        static float angle = 0;        angle += deltaTime;        if (angle > 6.28f)            angle = 0.0f;        XMMATRIX world;        world=XMLoadFloat4x4(&m_world);        world=XMMatrixRotationY(angle);        XMStoreFloat4x4(&m_world, world);    }    ~Cube() {        SAFE_RELEASE(m_pVertexBuffer);        SAFE_RELEASE(m_pIndexBuffer);        SAFE_RELEASE(m_pTexture);    }};class Scene {private:    ID3DX11Effect     *m_pEffect;    ID3DX11EffectTechnique *m_pTechnique;    ID3D11InputLayout *m_pInputLayout;  //输入布局    Cube *m_pCube;    Light m_PointLight;public:    Scene()        :m_pEffect(NULL),m_pTechnique(NULL),m_pInputLayout(NULL),m_pCube(NULL)    {    }    HRESULT Draw(DirectSystem *d3dSys) {        XMMATRIX view;        XMMATRIX projection;        XMVECTOR eyePosition;        view  = d3dSys->GetViewMatrix();        projection = d3dSys->GetProjectionMatrix();        eyePosition = d3dSys->GetEyePosition();        m_pCube->SetCubeParm(d3dSys,m_pEffect);        m_pEffect->GetVariableByName("View")->AsMatrix()->SetMatrix((float*)&view);        m_pEffect->GetVariableByName("Projection")->AsMatrix()->SetMatrix((float*)&projection);        m_pEffect->GetVariableByName("EyePosition")->AsVector()->SetFloatVector((float*)&eyePosition);        m_pEffect->GetVariableByName("type")->AsScalar()->SetInt(m_PointLight.type);        m_pEffect->GetVariableByName("LightPosition")->AsVector()->SetFloatVector((float*)&m_PointLight.position);        m_pEffect->GetVariableByName("LightAmbient")->AsVector()->SetFloatVector((float*)&m_PointLight.ambient);        m_pEffect->GetVariableByName("LightDiffuse")->AsVector()->SetFloatVector((float*)&m_PointLight.diffuse);        m_pEffect->GetVariableByName("LightSpecular")->AsVector()->SetFloatVector((float*)&m_PointLight.specular);        m_pEffect->GetVariableByName("LightAtt0")->AsScalar()->SetFloat(m_PointLight.attenuation0);        m_pEffect->GetVariableByName("LightAtt1")->AsScalar()->SetFloat(m_PointLight.attenuation1);        m_pEffect->GetVariableByName("LightAtt2")->AsScalar()->SetFloat(m_PointLight.attenuation2);        d3dSys->D3DDeviceContext()->IASetInputLayout(m_pInputLayout);        m_pTechnique->GetPassByIndex(0)->Apply(0, d3dSys->D3DDeviceContext());        d3dSys->D3DDeviceContext()->DrawIndexed(36, 0, 0);        return S_OK;    }    VOID Update(float deltaTime) {        m_pCube->Update(deltaTime);    }    HRESULT Init(DirectSystem *d3dSys) {        HRESULT hr;        ID3DBlob *effectBlob;        hr=D3DX11CompileFromFile(L"LightShader.fx", NULL, NULL,            NULL, "fx_5_0", NULL, 0, NULL, &effectBlob, NULL, NULL);        if (FAILED(hr)) {            return hr;        }        hr=D3DX11CreateEffectFromMemory(effectBlob->GetBufferPointer(), effectBlob->GetBufferSize(),            0, d3dSys->D3DDevice(), &m_pEffect, NULL);        if (FAILED(hr)) {            return hr;        }        m_pTechnique = m_pEffect->GetTechniqueByName("T0");        D3DX11_PASS_DESC passDesc;        m_pTechnique->GetPassByIndex(0)->GetDesc(&passDesc);        D3D11_INPUT_ELEMENT_DESC inputDesc[] = {            { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 , D3D11_INPUT_PER_VERTEX_DATA, 0 },            { "NORMAL",   0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },            { "TEXCOORD",  0,DXGI_FORMAT_R32G32_FLOAT    , 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }        };        UINT inputDescNum = ARRAYSIZE(inputDesc);        hr = d3dSys->D3DDevice()->CreateInputLayout(inputDesc, inputDescNum,            passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &m_pInputLayout);        if (FAILED(hr)) {            return hr;        }        m_pCube = new Cube();        m_pCube->Init(d3dSys);        m_PointLight.type = 1;        m_PointLight.position = XMFLOAT4(-4.0f, 4.0f, -4.0f, 1.0f);        m_PointLight.diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);        m_PointLight.ambient = XMFLOAT4(0.3f, 0.2f, 0.1f, 1.0f);        m_PointLight.specular = XMFLOAT4(0.5f, 0.5f, 0.9f, 1.0f);        m_PointLight.attenuation0 = 0;        m_PointLight.attenuation1 = 0.1f;        m_PointLight.attenuation2 = 0;        m_pTechnique = m_pEffect->GetTechniqueByName("T_PointLight");    }    ~Scene() {        delete m_pCube;        SAFE_RELEASE(m_pInputLayout);        SAFE_RELEASE(m_pTechnique);        SAFE_RELEASE(m_pEffect);    }};


Copyright© by 寒江雪
Date:2017.1.1

0 0
原创粉丝点击