Initialize the shader

目录

  • Loads the shader files and makes it usable to DirectX and the GPU
  • Compile the shader programs into buffers
    • D3DCompileFromFile function
  • Create the shader objects
    • ID3D11Device::CreateVertexShader method
  • Create the layout of the vertex data
    • D3D11_INPUT_ELEMENT_DESC structure
  • CreateInputLayout
    • ID3D11Device::CreateInputLayout method
  • constant buffer
    • ID3D11Device::CreateInputLayout method

Loads the shader files and makes it usable to DirectX and the GPU

Now we will start with one of the more important functions to this tutorial which is called InitializeShader. This function is what actually loads the shader files and makes it usable to DirectX and the GPU. You will also see the setup of the layout and how the vertex buffer data is going to look on the graphics pipeline in the GPU. The layout will need the match the VertexType in the modelclass.h file as well as the one defined in the color.vs file.

bool ColorShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* vsFilename, WCHAR* psFilename)
{
    HRESULT result;
    ID3D10Blob* errorMessage;
    ID3D10Blob* vertexShaderBuffer;
    ID3D10Blob* pixelShaderBuffer;
    D3D11_INPUT_ELEMENT_DESC polygonLayout[2];
    unsigned int numElements;
    D3D11_BUFFER_DESC matrixBufferDesc;

    // Initialize the pointers this function will use to null.
    errorMessage = 0;
    vertexShaderBuffer = 0;
    pixelShaderBuffer = 0;

Compile the shader programs into buffers

Here is where we compile the shader programs into buffers. We give it the name of the shader file, the name of the shader, the shader version (5.0 in DirectX 11), and the buffer to compile the shader into. If it fails compiling the shader it will put an error message inside the errorMessage string which we send to another function to write out the error. If it still fails and there is no errorMessage string then it means it could not find the shader file in which case we pop up a dialog box saying so.

    // Compile the vertex shader code.
    result = D3DCompileFromFile(vsFilename, NULL, NULL, "ColorVertexShader", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0,
                    &vertexShaderBuffer, &errorMessage);
    if(FAILED(result))
    {
        // If the shader failed to compile it should have writen something to the error message.
        if(errorMessage)
        {
            OutputShaderErrorMessage(errorMessage, hwnd, vsFilename);
        }
        // If there was  nothing in the error message then it simply could not find the shader file itself.
        else
        {
            MessageBox(hwnd, vsFilename, L"Missing Shader File", MB_OK);
        }

        return false;
    }

    // Compile the pixel shader code.
    result = D3DCompileFromFile(psFilename, NULL, NULL, "ColorPixelShader", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0,
                    &pixelShaderBuffer, &errorMessage);
    if(FAILED(result))
    {
        // If the shader failed to compile it should have writen something to the error message.
        if(errorMessage)
        {
            OutputShaderErrorMessage(errorMessage, hwnd, psFilename);
        }
        // If there was nothing in the error message then it simply could not find the file itself.
        else
        {
            MessageBox(hwnd, psFilename, L"Missing Shader File", MB_OK);
        }

        return false;
    }

D3DCompileFromFile function

Note You can use this API to develop your Windows Store apps, but you can‘t use it in apps that you submit to the Windows Store. Refer to the section, "Compiling shaders for UWP", in the remarks for D3DCompile2.

Compiles Microsoft High Level Shader Language (HLSL) code into bytecode for a given target.

Syntax


HRESULT D3DCompileFromFile(
  LPCWSTR                pFileName,
  const D3D_SHADER_MACRO *pDefines,
  ID3DInclude            *pInclude,
  LPCSTR                 pEntrypoint,
  LPCSTR                 pTarget,
  UINT                   Flags1,
  UINT                   Flags2,
  ID3DBlob               **ppCode,
  ID3DBlob               **ppErrorMsgs
);

Parameters

pFileName

A pointer to a constant null-terminated string that contains the name of the file that contains the shader code.

pDefines

An optional array of D3D_SHADER_MACRO structures that define shader macros. Each macro definition contains a name and a NULL-terminated definition. If not used, set to NULL.

pInclude

An optional pointer to an ID3DInclude interface that the compiler uses to handle include files. If you set this parameter to NULL and the shader contains a #include, a compile error occurs. You can pass the D3D_COMPILE_STANDARD_FILE_INCLUDE macro, which is a pointer to a default include handler. This default include handler includes files that are relative to the current directory.

#define D3D_COMPILE_STANDARD_FILE_INCLUDE ((ID3DInclude*)(UINT_PTR)1)

pEntrypoint

A pointer to a constant null-terminated string that contains the name of the shader entry point function where shader execution begins. When you compile an effect, D3DCompileFromFile ignores pEntrypoint; we recommend that you set pEntrypoint to NULL because it is good programming practice to set a pointer parameter to NULL if the called function will not use it.

pTarget

A pointer to a constant null-terminated string that specifies the shader target or set of shader features to compile against. The shader target can be a shader model (for example, shader model 2, shader model 3, shader model 4, or shader model 5 and later). The target can also be an effect type (for example, fx_4_1). For info about the targets that various profiles support, see Specifying Compiler Targets.

Flags1

A combination of shader compile options that are combined by using a bitwise OR operation. The resulting value specifies how the compiler compiles the HLSL code.

Flags2

A combination of effect compile options that are combined by using a bitwise OR operation. The resulting value specifies how the compiler compiles the effect. When you compile a shader and not an effect file, D3DCompileFromFile ignores Flags2; we recommend that you set Flags2 to zero because it is good programming practice to set a nonpointer parameter to zero if the called function will not use it.

ppCode

A pointer to a variable that receives a pointer to the ID3DBlob interface that you can use to access the compiled code.

ppErrorMsgs

An optional pointer to a variable that receives a pointer to the ID3DBlob interface that you can use to access compiler error messages, or NULL if there are no errors.


Create the shader objects

Once the vertex shader and pixel shader code has successfully compiled into buffers we then use those buffers to create the shader objects themselves. We will use these pointers to interface with the vertex and pixel shader from this point forward.

    // Create the vertex shader from the buffer.
    result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_vertexShader);
    if(FAILED(result))
    {
        return false;
    }

    // Create the pixel shader from the buffer.
    result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &m_pixelShader);
    if(FAILED(result))
    {
        return false;
    }

ID3D11Device::CreateVertexShader method

Create a vertex-shader object from a compiled shader.

Syntax


HRESULT CreateVertexShader(
  const void         *pShaderBytecode,
  SIZE_T             BytecodeLength,
  ID3D11ClassLinkage *pClassLinkage,
  ID3D11VertexShader **ppVertexShader
);

Parameters

pShaderBytecode

Type: const void*

A pointer to the compiled shader.

BytecodeLength

Type: SIZE_T

Size of the compiled vertex shader.

pClassLinkage

Type: ID3D11ClassLinkage*

A pointer to a class linkage interface (see ID3D11ClassLinkage); the value can be NULL.

ppVertexShader

Type: ID3D11VertexShader**

Address of a pointer to a ID3D11VertexShader interface. If this is NULL, all other parameters will be validated, and if all parameters pass validation this API will return S_FALSE instead of S_OK.

Return Value

Type: HRESULT

This method returns one of the Direct3D 11 Return Codes.

Remarks

The Direct3D 11.1 runtime, which is available starting with Windows 8, provides the following new functionality for CreateVertexShader.

The following shader model 5.0 instructions are available to just pixel shaders and compute shaders in the Direct3D 11.0 runtime. For the Direct3D 11.1 runtime, because unordered access views (UAV) are available at all shader stages, you can use these instructions in all shader stages.

Therefore, if you use the following shader model 5.0 instructions in a vertex shader, you can successfully pass the compiled vertex shader to pShaderBytecode. That is, the call to CreateVertexShader succeeds.

If you pass a compiled shader to pShaderBytecode that uses any of the following instructions on a device that doesn’t support UAVs at every shader stage (including existing drivers that are not implemented to support UAVs at every shader stage), CreateVertexShader fails. CreateVertexShader also fails if the shader tries to use a UAV slot beyond the set of UAV slots that the hardware supports.

  • dcl_uav_typed
  • dcl_uav_raw
  • dcl_uav_structured
  • ld_raw
  • ld_structured
  • ld_uav_typed
  • store_raw
  • store_structured
  • store_uav_typed
  • sync_uglobal

All atomics and immediate atomics (for example, atomic_and and imm_atomic_and)


Create the layout of the vertex data

The next step is to create the layout of the vertex data that will be processed by the shader. As this shader uses a position and color vector we need to create both in the layout specifying the size of both. The semantic name is the first thing to fill out in the layout, this allows the shader to determine the usage of this element of the layout. As we have two different elements we use POSITION for the first one and COLOR for the second. The next important part of the layout is the Format. For the position vector we use DXGI_FORMAT_R32G32B32_FLOAT and for the color we use DXGI_FORMAT_R32G32B32A32_FLOAT. The final thing you need to pay attention to is the AlignedByteOffset which indicates how the data is spaced in the buffer. For this layout we are telling it the first 12 bytes are position and the next 16 bytes will be color, AlignedByteOffset shows where each element begins. You can use D3D11_APPEND_ALIGNED_ELEMENT instead of placing your own values in AlignedByteOffset and it will figure out the spacing for you. The other settings I‘ve made default for now as they are not needed in this tutorial.

    // Create the vertex input layout description.
    // This setup needs to match the VertexType stucture in the ModelClass and in the shader.
    polygonLayout[0].SemanticName = "POSITION";
    polygonLayout[0].SemanticIndex = 0;
    polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
    polygonLayout[0].InputSlot = 0;
    polygonLayout[0].AlignedByteOffset = 0;
    polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
    polygonLayout[0].InstanceDataStepRate = 0;

    polygonLayout[1].SemanticName = "COLOR";
    polygonLayout[1].SemanticIndex = 0;
    polygonLayout[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    polygonLayout[1].InputSlot = 0;
    polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
    polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
    polygonLayout[1].InstanceDataStepRate = 0;

D3D11_INPUT_ELEMENT_DESC structure

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

Syntax


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;

Members

SemanticName

Type: LPCSTR

The HLSL semantic associated with this element in a shader input-signature.

SemanticIndex

Type: UINT

The semantic index for the element. A semantic index modifies a semantic, with an integer index number. A semantic index is only needed in a case where there is more than one element with the same semantic. For example, a 4x4 matrix would have four components each with the semantic name

matrix

, however each of the four component would have different semantic indices (0, 1, 2, and 3).

Format

Type: DXGI_FORMAT

The data type of the element data. See DXGI_FORMAT.

InputSlot

Type: UINT

An integer value that identifies the input-assembler (see input slot). Valid values are between 0 and 15, defined in D3D11.h.

AlignedByteOffset

Type: UINT

Optional. Offset (in bytes) between each element. Use D3D11_APPEND_ALIGNED_ELEMENT for convenience to define the current element directly after the previous one, including any packing if necessary.

InputSlotClass

Type: D3D11_INPUT_CLASSIFICATION

Identifies the input data class for a single input slot (see D3D11_INPUT_CLASSIFICATION).

InstanceDataStepRate

Type: UINT

The number of instances to draw using the same per-instance data before advancing in the buffer by one element. This value must be 0 for an element that contains per-vertex data (the slot class is set to D3D11_INPUT_PER_VERTEX_DATA).


CreateInputLayout

Once the layout description has been setup we can get the size of it and then create the input layout using the D3D device. Also release the vertex and pixel shader buffers since they are no longer needed once the layout has been created.

// Get a count of the elements in the layout.
numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);

// Create the vertex input layout.
result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(),
                   vertexShaderBuffer->GetBufferSize(), &m_layout);
if(FAILED(result))
{
    return false;
}

// Release the vertex shader buffer and pixel shader buffer since they are no longer needed.
vertexShaderBuffer->Release();
vertexShaderBuffer = 0;

pixelShaderBuffer->Release();
pixelShaderBuffer = 0;

ID3D11Device::CreateInputLayout method

Create an input-layout object to describe the input-buffer data for the input-assembler stage.

Syntax


HRESULT CreateInputLayout(
  const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs,
  UINT                           NumElements,
  const void                     *pShaderBytecodeWithInputSignature,
  SIZE_T                         BytecodeLength,
  ID3D11InputLayout              **ppInputLayout
);

Parameters

pInputElementDescs

Type: const D3D11_INPUT_ELEMENT_DESC*

An array of the input-assembler stage input data types; each type is described by an element description (see D3D11_INPUT_ELEMENT_DESC).

NumElements

Type: UINT

The number of input-data types in the array of input-elements.

pShaderBytecodeWithInputSignature

Type: const void*

A pointer to the compiled shader. The compiled shader code contains a input signature which is validated against the array of elements. See remarks.

BytecodeLength

Type: SIZE_T

Size of the compiled shader.

ppInputLayout

Type: ID3D11InputLayout**

A pointer to the input-layout object created (see ID3D11InputLayout). To validate the other input parameters, set this pointer to be NULL and verify that the method returns S_FALSE.

constant buffer

The final thing that needs to be setup to utilize the shader is the constant buffer. As you saw in the vertex shader we currently have just one constant buffer so we only need to setup one here so we can interface with the shader. The buffer usage needs to be set to dynamic since we will be updating it each frame. The bind flags indicate that this buffer will be a constant buffer. The cpu access flags need to match up with the usage so it is set to D3D11_CPU_ACCESS_WRITE. Once we fill out the description we can then create the constant buffer interface and then use that to access the internal variables in the shader using the function SetShaderParameters.

// Setup the description of the dynamic matrix constant buffer that is in the vertex shader.
matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType);
matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
matrixBufferDesc.MiscFlags = 0;
matrixBufferDesc.StructureByteStride = 0;

// Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class.
result = device->CreateBuffer(&matrixBufferDesc, NULL, &m_matrixBuffer);
if(FAILED(result))
{
    return false;
}

return true;

}

ID3D11Device::CreateInputLayout method

Create an input-layout object to describe the input-buffer data for the input-assembler stage.

Syntax

C++

HRESULT CreateInputLayout(

const D3D11_INPUT_ELEMENT_DESC pInputElementDescs,

UINT NumElements,

const void pShaderBytecodeWithInputSignature,

SIZE_T BytecodeLength,

ID3D11InputLayout ppInputLayout

);

Parameters

pInputElementDescs**

Type: const D3D11_INPUT_ELEMENT_DESC*

An array of the input-assembler stage input data types; each type is described by an element description (see D3D11_INPUT_ELEMENT_DESC).

NumElements

Type: UINT

The number of input-data types in the array of input-elements.

pShaderBytecodeWithInputSignature

Type: const void*

A pointer to the compiled shader. The compiled shader code contains a input signature which is validated against the array of elements. See remarks.

BytecodeLength

Type: SIZE_T

Size of the compiled shader.

ppInputLayout

Type: ID3D11InputLayout**

A pointer to the input-layout object created (see ID3D11InputLayout). To validate the other input parameters, set this pointer to be NULL and verify that the method returns S_FALSE.

原文地址:https://www.cnblogs.com/CookieBox/p/10325279.html

时间: 2024-11-07 18:04:20

Initialize the shader的相关文章

ModelBatch(LibGDX)都做了什么

ModelBatch的通常用法: Batch batch = new ModelBatch(); batch.begin(camera); batch.render(renderable); batch.end(); 先来看ModelBatch.begin()函数: public void begin (final Camera cam) { if (camera != null) throw new GdxRuntimeException("Call end() first.");

PPAPI中使用OpenGL ES绘图

在PPAPI中使用Chromium的3D图形接口一文中我们介绍了怎么使用PPB_Graphics3D接口,提供了一个简单示例,单机鼠标可以变换插件颜色. foruok原创,如需转载请关注foruok的微信订阅号"程序视界"联系foruok. PPB_Graphics3D是Chromium暴露给PPAPI的3D图形接口,类似衔接Open GL和本地窗口系统的EGL.我们使用PPB_Graphics3D的Create方法来创建context,然后使用PPB_Instance的BindGra

webgl 模板缓冲

先思考个问题, 想实现遮罩怎么办? <!doctype html> <html> <head> <meta charset="utf-8" /> <title>Stencil Buffer</title> <script id="shader-vs" type="x-shader/x-vertex"> precision highp float; attribut

cocos2dx(3.X)中使用shader

原文链接:http://blog.csdn.net/xufeng0991/article/details/47256583 一 shader的基本概念 1 什么是shader shader即着色器,就是专门用来渲染3D图形的一种技术. 通过shader,可以自己编写显卡渲染画面的算法,使画面更漂亮.更逼真. 2 shader分类 shader又分两种,一种是顶点shader(3D图形是由三角形组成的,顶点shader就是计算顶点位置,并为后期像素渲染做准备的), 另一种是像素shader,就是以

【原创翻译】初识Unity中的Compute Shader

一直以来都想试着自己翻译一些东西,现在发现翻译真的很不容易,如果你直接把作者的原文按照英文的思维翻译过来,你会发现中国人读起来很是别扭,但是如果你想完全利用中国人的语言方式来翻译,又怕自己理解的不到位,反而与作者的愿意相悖.所以我想很多时候,国内的译者也是无奈吧,下次再看到译作也会抱着一些感同身受的态度去读.这是我第一次翻译整篇文章,能力有限,望见谅,翻译不好的地方也希望大家指出来. 其实ComputeShader在Unity中出现已经有蛮长的一段时间了,因为自己一直对Shader比较感兴趣,所

Unity2017程序化天空Shader实现

unity2017提供了一个程序化生成天空的Shader,程序化天空在实时昼夜变换和天气系统中都有必要性,所以简单来分析一下. 1 // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) 2 3 Shader "Skybox/Procedural" { 4 Properties { 5 [KeywordEnum(None, Simple,

Cesium原理篇:6 Render模块(3: Shader)

在介绍Renderer的第一篇,我就提到WebGL1.0对应的是OpenGL ES2.0,也就是可编程渲染管线.之所以单独强调这一点,算是为本篇埋下一个伏笔.通过前两篇,我们介绍了VBO和Texture两个比较核心的WebGL概念.假设生产一辆汽车,VBO就相当于这个车的骨架,纹理相当这个车漆,但有了骨架和车漆还不够,还需要一台机器人来加工,最终才能成产出这辆汽车.而Shader模块就是负责这个生产的过程,加工参数(VBO,Texture),执行渲染任务. 这里假设大家对Shader有一个基本的

unity3d 从零开始compute shader

开始用compute shader 我喜欢vertex/fragment shaders的简单,他们只是做一件事(把顶点和颜色输出到屏幕上去),他们做得非常好,但是有时这种简单限制了你,当你的cpu拼了命的循环那些矩阵,算出并储存在贴图上... Compute Shader 解决了这个问题,我将在今天说明它的基础,我将通过一个unity自己的例子告诉你,使用structured buffer的数据在compute shader中工作 Compute Shader能用来控制粒子群的位置 什么是co

shader实现灰度图

1.cocos主线程以及Auto-batching AppDelegate app;//封装用于智能分化,完成初始化,载入资源.构造场景.生成精灵 Application::getInstance()->run();//启动主线程 director->mainLoop();//分为场景渲染,和清理缓存池 glview->pollEvents(); drawScene: 1)优先处理输入事件(空实现,留接口) 2)默认定时器(负优先级,0,正优先级).自定义计时器 3)visit主渲染树(