3.3应用程序

    技术2022-05-11  48

    3.3应用程序

           程序中我们首先创建一个四边形,然后使用像素着色器进行纹理混合后对其进行渲染。下面是应用程序代码:

    /*********************顶点格式定义*****************/

    struct CUSTOMVERTEX

    {

           //定点位置坐标

           float x,y,z;

           //两套纹理坐标;

           float tu0, tv0;

           float tu1, tv1;

    };

    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX2)

    /*********************声明变量*****************/

    //顶点着色器

    LPDIRECT3DPIXELSHADER9 pixelShader   = 0;

    //常量表

    ID3DXConstantTable* pixelConstTable  = 0;

     

    //常量句柄

    D3DXHANDLE ScalarHandle              = 0;

    D3DXHANDLE Samp0Handle                = 0;

    D3DXHANDLE Samp1Handle                = 0;

     

    //常量描述结构

    D3DXCONSTANT_DESC Samp0Desc;

    D3DXCONSTANT_DESC Samp1Desc;

     

    //四边形顶点缓存

    LPDIRECT3DVERTEXBUFFER9 quadVB  = NULL;

    //两个纹理

    LPDIRECT3DTEXTURE9 quadTexture0 = NULL;

    LPDIRECT3DTEXTURE9 quadTexture1 = NULL;

     

    /********************初始化应用程序*****************/

    //创建四边形顶点模型

    CUSTOMVERTEX quad[] =

    //  x      y      z    tu0   tv0   tu1   tv1

    {{-3.0f, -3.0f, 10.0f, 0.0f, 1.0f, 0.0f, 1.0f},

    { -3.0f,  3.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f},

    {  3.0f, -3.0f, 10.0f, 1.0f, 1.0f, 1.0f, 1.0f},

    {  3.0f,  3.0f, 10.0f, 1.0f, 0.0f, 1.0f, 0.0f}};

     

    //创建顶点缓存

    void *ptr = NULL;

    g_pd3dDevice->CreateVertexBuffer(sizeof(quad),

                                                             D3DUSAGE_WRITEONLY,

                                                             0,

                                                             D3DPOOL_MANAGED,

                                                             &quadVB,

                                                             NULL);

    quadVB->Lock(0, 0, (void**)&ptr, 0);

    memcpy((void*)ptr, (void*)quad, sizeof(quad));

    quadVB->Unlock();

     

    //创建纹理

    D3DXCreateTextureFromFile(g_pd3dDevice, "porpcart.jpg", &quadTexture0);

    D3DXCreateTextureFromFile(g_pd3dDevice, "luoqi.jpg", &quadTexture1);

     

    //检测系统是否支持像素着色器

    D3DCAPS9 caps;

    g_pd3dDevice->GetDeviceCaps(&caps);

    if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1))

    {

           MessageBox(0, "NotSupport Pixel Shader - FAILED", 0, 0);

           exit(0);

    }

     

    //创建像素着色器

    ID3DXBuffer* codeBuffer        = 0;

    ID3DXBuffer* errorBuffer       = 0;

     

    HRESULT hr = D3DXCompileShaderFromFile("ps.txt",

                                                                      0,

                                                                      0,

                                                                      "PS_Main", // entry point function name

                                                                      "ps_1_1",

                                                                      D3DXSHADER_DEBUG,

                                                                      &codeBuffer,

                                                                      &errorBuffer,

                                                                      &pixelConstTable);

     

    // output any error messages

    if(errorBuffer)

    {

           MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);

           ReleaseCOM(errorBuffer);

    }

     

    if(FAILED(hr))

    {

           MessageBox(0, "D3DXCompileShaderFromFile() - FAILED", 0, 0);

           return false;

    }

     

     

    hr = g_pd3dDevice->CreatePixelShader((DWORD*)codeBuffer->GetBufferPointer(), &pixelShader);

     

    if(FAILED(hr))

    {

           MessageBox(0, "CreatePixelShader - FAILED", 0, 0);

           return false;

    }

     

    ReleaseCOM(codeBuffer);

    ReleaseCOM(errorBuffer);

     

    //得到各常量句柄

    ScalarHandle = pixelConstTable->GetConstantByName(0, "Scalar");

    Samp0Handle = pixelConstTable->GetConstantByName(0, "Samp0");

    Samp1Handle = pixelConstTable->GetConstantByName(0, "Samp1");

     

    //得到对着色器变量Samp0Samp0的描述

    UINT count;

    pixelConstTable->GetConstantDesc(Samp0Handle, & Samp0Desc, &count);

    pixelConstTable->GetConstantDesc(Samp1Handle, & Samp1Desc, &count);

     

    //设定各着色器变量为初始值

    pixelConstTable->SetDefaults(g_pd3dDevice);

    /********************渲染*****************/

    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(153,153,153), 1.0f, 0 );

    g_pd3dDevice->BeginScene();

     

    //为着色器全局变量Scalar赋值

    D3DXVECTOR4 scalar(0.5f, 0.5f, 0.0f, 1.0f);

    pixelConstTable->SetVector(g_pd3dDevice, ScalarHandle, &scalar);

     

    //设置像素着色器

    g_pd3dDevice->SetPixelShader(pixelShader);

     

    //设置定点格式、绑定数据流

    g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);

    g_pd3dDevice->SetStreamSource(0, quadVB, 0, sizeof(CUSTOMVERTEX));

     

    //设置第一、二层纹理

    g_pd3dDevice->SetTexture(Samp0Desc.RegisterIndex, quadTexture0);

    g_pd3dDevice->SetTexture(Samp1Desc.RegisterIndex, quadTexture1);

     

    //绘制图形

    g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

     

    g_pd3dDevice->EndScene();

    g_pd3dDevice->Present(NULL, NULL, NULL, NULL);

     

           程序中像素着色器的使用和之前顶点着色器的使用无二,只是设置着色器中纹理采样器变量Samp0Samp1和设定着色器其他变量稍有不同:

        1. 首先通过变量名称得到变量句柄:

                  Tex0Handle = pixelConstTable->GetConstantByName(0, " Samp0");

                  Tex1Handle = pixelConstTable->GetConstantByName(0, " Samp1");

        2. 然后通过句柄得到对变量的描述:

                  UINT count;

                  pixelConstTable->GetConstantDesc(Samp0Handle, & Samp0Desc, &count);

                  pixelConstTable->GetConstantDesc(Samp1Handle, & Samp1Desc, &count);

        3.最后通过SetTexture配合所得到的描述信息设置纹理:

                  g_pd3dDevice->SetTexture(Samp0Desc.RegisterIndex, quadTexture0);

                  g_pd3dDevice->SetTexture(Samp1Desc.RegisterIndex, quadTexture1);

     

           编译运行程序,运行效果如图3.2,这里我们将颜色混合比例设置为0.5,如果读者在渲染过程中不断变换对着色器变量Scalar的赋值,你将会得到一个混合度不断变换的多纹理效果。

           D3DXVECTOR4 scalar(0.5f, 0.5f, 0.0f, 1.0f); //读者可以尝试改变混合采用的比例值

           pixelConstTable->SetVector(g_pd3dDevice, ScalarHandle, &scalar);

     

     

    纹理一

    纹理二

    混合后纹理三

    3.2


    最新回复(0)