灯光状态如何在DirectX的效果文件中工作

灯光状态如何在DirectX的效果文件中工作,directx,Directx,我正在学习DirectX效果,我知道所有固定的管线渲染状态都可以在.fx文件中设置,当我想在.fx文件中设置点光源时,如何计算最终像素颜色?光[0]从何而来?下面是.fx文件的代码,我不知道如何编写像素着色器部分(BasicPS)来计算最终颜色 // World, View and Projection Matrix uniform extern float4x4 gWVP; // Output Vertex structure struct Outpu

我正在学习DirectX效果,我知道所有固定的管线渲染状态都可以在.fx文件中设置,当我想在.fx文件中设置点光源时,如何计算最终像素颜色?光[0]从何而来?下面是.fx文件的代码,我不知道如何编写像素着色器部分(BasicPS)来计算最终颜色

    // World, View and Projection Matrix 
    uniform extern float4x4 gWVP;  

    // Output Vertex structure 
    struct OutputVS 
    { 
          float4 posH : POSITION0; 
    }; 

    OutputVS BasicVS(float4 posL : POSITION0) 
    { 

          // Zero out our output. 
          OutputVS outVS = (OutputVS)0; 

          // Transform to homogeneous clip space. 
          outVS.posH = mul(posL, gWVP); 

          // Done--return the output. 
          return outVS; 
    } 

    float4 BasicPS() : COLOR 
    { 
        //What to write here? 
    } 

    technique Tech1 
    { 
        pass p0 
        { 
            vertexShader = compile vs_2_0 BasicVS(); 
            pixelShader  = compile ps_2_0 BasicPS(); 

            Lighting = True; 
            LightEnable[0] = True; 
            LightType[0] = POINT; 

            // Light color is white 
            LightAmbient[0] = {0.6f, 0.6f, 0.6f, 0.0f}; 
            LightDiffuse[0] = {1.0f, 1.0f, 1.0f, 0.0f}; 
            LightSpecular[0] = {0.6f, 0.6f, 0.6f, 0.0f}; 

            // Light position 
            LightPosition[0] = {10.0f, 10.0f, -5.0f}; 

            // Light range 
            LightRange[0] = 1000.0f; 

            // Light falloff 
            LightFalloff[0] = 1.0f; 

            // Attenuations 
            LightAttenuation0[0] = 1.0f; 
            LightAttenuation1[0] = 0.0f; 
            LightAttenuation2[0] = 0.0f; 
        } 
    } 


the cpp file of this program as below

    #include <d3dx9.h>
    #include <MMSystem.h>

    LPDIRECT3D9             g_pD3D              = NULL ; // Used to create the D3DDevice
    LPDIRECT3DDEVICE9       g_pd3dDevice        = NULL ; // Our rendering device
    ID3DXMesh*              g_pTeapotMesh       = NULL ; // Hold the teapot
    ID3DXEffect*            g_pEffect           = NULL ; // Effect interface
    bool                    g_bActive           = true ; // Is window active?

    // Handles for effects
    D3DXHANDLE g_hWVP;      // world, view and projection matrix handle.
    D3DXHANDLE g_hTech;     // Technique handle

    #define SAFE_RELEASE(P) if(P){ P->Release(); P = NULL;}

    HRESULT BuildEffect()
    {
        char* effectFile = "./PointLight.fx";

        ID3DXBuffer* errors = 0;

        // Create Effect from file
        HRESULT hr = D3DXCreateEffectFromFile(
            g_pd3dDevice,
            effectFile, 
            NULL,
            NULL,
            D3DXSHADER_DEBUG,
            NULL,
            &g_pEffect,
            &errors);
        if( errors )
            MessageBox(0, (char*)errors->GetBufferPointer(), 0, 0);

        g_hWVP  = g_pEffect->GetParameterByName(0, "gWVP");
        g_hTech = g_pEffect->GetTechniqueByName("Tech1");

        return D3D_OK;
    }

    HRESULT SetupPointLight()
    {
        D3DLIGHT9 pointLight;
        ZeroMemory(&pointLight, sizeof(pointLight));

        // Set light
        g_pd3dDevice->SetLight(0, &pointLight);

        return D3D_OK;
    }

    HRESULT SetupMaterial()
    {
    D3DMATERIAL9 material;
    ZeroMemory(&material, sizeof(material));

    D3DXCOLOR red = D3DCOLOR_XRGB(255, 0, 0);
    material.Ambient = red;
    material.Diffuse = red;
    material.Specular = red;
    material.Emissive = D3DXCOLOR(0, 0, 0, 0);
    material.Power = 2.0f; // only affect specular color

    g_pd3dDevice->SetMaterial(&material);

    return D3D_OK;
    }

    HRESULT InitD3D( HWND hWnd )
    {
        // Create the D3D object, which is needed to create the D3DDevice.
        if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        {
            MessageBoxA(NULL, "Create D3D9 object failed!", "Error", 0) ;
            return E_FAIL;
        }

        D3DPRESENT_PARAMETERS d3dpp; 
        ZeroMemory( &d3dpp, sizeof(d3dpp) );

        d3dpp.Windowed = TRUE; // use window mode, not full screen
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
        d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

        // Create device
        if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
            D3DCREATE_SOFTWARE_VERTEXPROCESSING,
            &d3dpp, &g_pd3dDevice ) ) )
        {
            MessageBoxA(NULL, "Create D3D9 device failed!", "Error", 0) ;
            return E_FAIL;
        }

        // Create teapot
        D3DXCreateTeapot(g_pd3dDevice, &g_pTeapotMesh, NULL) ;

        // Build effect
        BuildEffect();

        return S_OK;
    }

    void DrawTeapot()
    {
        // translate model to origin
        D3DXMATRIX world ;
        D3DXMatrixTranslation(&world, 0.0f, 0.0f, 0.0f) ;
        g_pd3dDevice->SetTransform(D3DTS_WORLD, &world) ;

        // set view
        D3DXVECTOR3 eyePt(0.0f, 0.0f, -10.0f) ;
        D3DXVECTOR3 upVec(0.0f, 1.0f, 0.0f) ;
        D3DXVECTOR3 lookCenter(0.0f, 0.0f, 0.0f) ;

        D3DXMATRIX view ;
        D3DXMatrixLookAtLH(&view, &eyePt, &lookCenter, &upVec) ;
        g_pd3dDevice->SetTransform(D3DTS_VIEW, &view) ;

        // set projection
        D3DXMATRIX proj ;
        D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI / 4, 1.0f, 1.0f, 1000.0f) ;
        g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj) ;

        D3DXMATRIX worldviewproj = world * view * proj;

        // Set matrix
        g_pEffect->SetMatrix(g_hWVP, &worldviewproj);

        // Set technique
        g_pEffect->SetTechnique(g_hTech);

        // Render pass
        UINT numPass = 0;
        g_pEffect->Begin(&numPass, 0);
        g_pEffect->BeginPass(0);
        g_pTeapotMesh->DrawSubset(0);
        g_pEffect->EndPass();
        g_pEffect->End();
    }

    VOID Cleanup()
    {
        SAFE_RELEASE(g_pTeapotMesh) ;
        SAFE_RELEASE(g_pd3dDevice) ;
        SAFE_RELEASE(g_pD3D) ;
    }

    void Render(float timeDelta)
    {
        if (!g_bActive)
        {
            Sleep(50) ;
        }

        SetupMaterial();

        SetupPointLight();

        // Clear the back-buffer to a RED color
        g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );

        // Begin the scene
        if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
        {
            // Draw teapot 
            DrawTeapot();

            // End the scene
            g_pd3dDevice->EndScene();
        }

        // Present the back-buffer contents to the display
        g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
    }

    LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
    {
        switch( msg )
        {
        case WM_KEYDOWN:
            {
                switch( wParam )
                {
                case VK_ESCAPE:
                    SendMessage( hWnd, WM_CLOSE, 0, 0 );
                    break ;
                default:
                    break ;
                }
            }
            return 0 ;

        case WM_SIZE:
            if(wParam == SIZE_MAXHIDE || wParam == SIZE_MINIMIZED)
                g_bActive = false;
            else
                g_bActive = true;
            return 0;

        case WM_ACTIVATEAPP:
            if(wParam == TRUE)
                g_bActive = true ;
            else
                g_bActive = false ;
            return 0 ;

        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
        }

        return DefWindowProc( hWnd, msg, wParam, lParam );
    }

    INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR szCmdLine, int iCmdShow)
    {
        WNDCLASSEX winClass ;

        winClass.lpszClassName = "Teapot";
        winClass.cbSize        = sizeof(WNDCLASSEX);
        winClass.style         = CS_HREDRAW | CS_VREDRAW;
        winClass.lpfnWndProc   = MsgProc;
        winClass.hInstance     = hInstance;
        winClass.hIcon         = NULL ;
        winClass.hIconSm       = NULL ;
        winClass.hCursor       = LoadCursor(NULL, IDC_ARROW) ;
        winClass.hbrBackground = NULL ;
        winClass.lpszMenuName  = NULL ;
        winClass.cbClsExtra    = 0;
        winClass.cbWndExtra    = 0;

        RegisterClassEx (&winClass) ;  

        HWND hWnd = CreateWindowEx(NULL,  
            winClass.lpszClassName,     // window class name
            "Teapot",                   // window caption
            WS_OVERLAPPEDWINDOW,        // window style
            32,                         // initial x position
            32,                         // initial y position
            600,                        // initial window width
            600,                        // initial window height
            NULL,                       // parent window handle
            NULL,                       // window menu handle
            hInstance,                  // program instance handle
            NULL) ;                     // creation parameters

        // Create window failed
        if(hWnd == NULL)
        {
            MessageBoxA(hWnd, "Create Window failed!", "Error", 0) ;
            return -1 ;
        }

        // Initialize Direct3D
        if( SUCCEEDED(InitD3D(hWnd)))
        { 
            // Show the window
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );

            MSG msg ; 
            ZeroMemory( &msg, sizeof(msg) );
            PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );

            // Get last time
            static DWORD lastTime = timeGetTime();

            while (msg.message != WM_QUIT)  
            {
                if(PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0)
                {
                    TranslateMessage (&msg) ;
                    DispatchMessage (&msg) ;
                }
                else // Render the game if there is no message to process
                {
                    // Get current time
                    DWORD currTime  = timeGetTime();

                    // Calculate time elapsed
                    float timeDelta = (currTime - lastTime) * 0.001f;

                    // Render
                    Render(timeDelta) ;

                    // Update last time to current time for next loop
                    lastTime = currTime;
                }
            }
        }

        UnregisterClass(winClass.lpszClassName, hInstance) ;
        return 0;
    }
//世界、视图和投影矩阵
统一外部浮动4x4 gWVP;
//输出顶点结构
结构输出
{ 
浮动4豪华:位置0;
}; 
输出VS基本CV(浮动4位置:位置0)
{ 
//把我们的产量归零。
OutputVS-outVS=(OutputVS)0;
//变换到齐次剪辑空间。
outVS.posH=mul(posL,gWVP);
//完成——返回输出。
返回outVS;
} 
float4 BasicPS():颜色
{ 
//在这里写什么?
} 
技术技术1
{ 
通过p0
{ 
vertexShader=编译vs_2_0 BasicVS();
pixelShader=编译ps_2_0 BasicPS();
照明=真实;
可减轻的[0]=真;
LightType[0]=点;
//浅色是白色的
光环境[0]={0.6f,0.6f,0.6f,0.0f};
光漫反射[0]={1.0f,1.0f,1.0f,0.0f};
光反射[0]={0.6f,0.6f,0.6f,0.0f};
//灯位
光位置[0]={10.0f,10.0f,-5.0f};
//光范围
光照范围[0]=1000.0f;
//光衰减
光衰减[0]=1.0f;
//衰减
光衰减0[0]=1.0f;
光衰减1[0]=0.0f;
光衰减2[0]=0.0f;
} 
} 
该程序的cpp文件如下所示
#包括
#包括
LPDIRECT3D9 g_pD3D=NULL;//用于创建D3DDevice
LPDIRECT3DDEVICE9 g_pd3dDevice=NULL;//我们的渲染设备
ID3DXMesh*g_pTeapotMesh=NULL;//拿着茶壶
ID3DXEffect*g_peeffect=NULL;//效果界面
bool g_bActive=true;//窗口是否处于活动状态?
//效果句柄
D3DXHANDLE g_hWVP;//世界、视图和投影矩阵控制柄。
D3DXHANDLE g_hTech;//技术手柄
#如果(P){P->RELEASE();P=NULL;}
HRESULT BuildEffect()
{
char*effectFile=“./PointLight.fx”;
ID3DXBuffer*错误=0;
//从文件创建效果
HRESULT hr=D3DXCreateEffectFromFile(
g_PD3D设备,
效应文件,
无效的
无效的
D3DXU调试,
无效的
&g_pEffect,
&错误);
如果(错误)
MessageBox(0,(char*)错误->GetBufferPointer(),0,0);
g_hWVP=g_pEffect->GetParameterByName(0,“gWVP”);
g_hTech=g_pEffect->GetTechniqueByName(“Tech1”);
返回D3D_OK;
}
HRESULT设置点光源()
{
D3DLIGHT9点光源;
零内存(&pointLight,sizeof(pointLight));
//点燃
g_pd3dDevice->SetLight(0和pointLight);
返回D3D_OK;
}
HRESULT SetupMaterial()
{
D3D材料9材料;
零内存(&material,sizeof(material));
D3DXCOLOR red=D3DCOLOR_XRGB(255,0,0);
材料。环境温度=红色;
材质:漫反射=红色;
材料:镜面反射=红色;
材料.发射=D3DXCOLOR(0,0,0,0);
material.Power=2.0f;//仅影响镜面反射颜色
g_pd3dDevice->SetMaterial(&material);
返回D3D_OK;
}
HRESULT InitD3D(HWND HWND)
{
//创建创建D3D设备所需的D3D对象。
如果(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_版本)))
{
MessageBoxA(NULL,“创建D3D9对象失败!”,“错误”,0);
返回E_失败;
}
D3D当前参数d3dpp;
零内存(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;//使用窗口模式,而不是全屏模式
d3dpp.SwapEffect=d3dswapeeffect_DISCARD;
d3dpp.BackBufferFormat=D3DFMT_未知;
//创建设备
如果(失败)(g_pD3D->CreateDevice(D3DAAPTER_默认值,D3DDEVTYPE_HAL,hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp和g_PD3D设备)
{
MessageBoxA(NULL,“创建D3D9设备失败!”,“错误”,0);
返回E_失败;
}
//制作茶壶
D3DXCreateTeapot(g_pd3dDevice和g_pTeapotMesh,空);
//建筑效应
BuildEffect();
返回S_OK;
}
空茶壶()
{
//将模型转换为原点
d3dx矩阵世界;
D3DX矩阵翻译(和世界,0.0f,0.0f,0.0f);
g_pd3dDevice->SetTransform(D3DTS_WORLD和WORLD);
//设置视图
D3DXVECTOR3眼点(0.0f,0.0f,-10.0f);
D3DXVECTOR3 upVec(0.0f、1.0f、0.0f);
D3DXVECTOR3 lookCenter(0.0f、0.0f、0.0f);
d3dx矩阵视图;
D3DXMatrixLookAtLH(视图、眼睛、注视中心和upVec);
g_pd3dDevice->SetTransform(D3DTS_视图和视图);
//集合投影
d3dx矩阵项目;
D3DX矩阵透视图(和项目,D3DX_PI/4,1.0f,1.0f,1000.0f);
g_pd3dDevice->SetTransform(D3DTS_投影和项目);
D3DXMATRIX worldviewproj=世界*视图*项目;
//集合矩阵
g_pEffect->SetMatrix(g_hWVP和worldviewproj);
//成套技术
g_pEffect->SetTechnique(g_hTech);
//渲染过程
UINT numPass=0;
g_pEffect->Begin(&numPass,0);
g_pEffect->BeginPass(0);
g_pTeapotMesh->DrawSubset(0);
g_pEffect->EndPass();
g_pEffect->End();
}
空洞清理()
{
安全释放(g_pTeapotMesh);
安全释放(g\U pd)
pixelShader = null;
pixelShader = null;