2014-01-21 95 views
0

我正在嘗試在DirectX 9中創建一個Cube Map,但由於某種原因它無法正常工作。我已經使用DirectX的紋理實用程序爲多維數據集創建了一個dds紋理文件,但是當我繪製它時,它只繪製一個純色。下面是我做的代碼:如何在DirectX 9中創建Cubemap 9

SkyBox.h

#pragma once 

#include<D3DX9Mesh.h> 
#include"DirectX.h" 

class SkyBox{ 
public: 
    SkyBox(LPCSTR textureFile); 
    ~SkyBox(); 

    void Draw(); 

protected: 
    IDirect3DCubeTexture9* texture; 
    LPD3DXMESH mesh; 
}; 

SkyBox.cpp

#include"SkyBox.h" 

SkyBox::SkyBox(LPCSTR textureFile) 
{ 
    D3DXCreateBox(DirectX::device, 1.0f, 1.0f, 1.0f, &mesh, NULL); 
    D3DXCreateCubeTextureFromFile(DirectX::device, textureFile, &texture); 
} 

SkyBox::~SkyBox() 
{ 
    mesh->Release(); 
    texture->Release(); 
} 

void SkyBox::Draw() 
{ 
    D3DXHANDLE textureHandle = DirectX::currentShaderEffect->GetParameterByName(0, "tex0"); 
    DirectX::currentShaderEffect->SetTexture(textureHandle, texture); 
    DirectX::currentShaderEffect->CommitChanges(); 

    UINT passNum = 5; 
    DirectX::currentShaderEffect->Begin(&passNum, 0); 
    DirectX::currentShaderEffect->BeginPass(5); 

    mesh->DrawSubset(0); 

    DirectX::currentShaderEffect->EndPass(); 
    DirectX::currentShaderEffect->End(); 
} 

,這是我的立方體貼圖着色器:

uniform extern float4x4 mvp; 
uniform extern texture tex0; 

struct SkyboxVS 
{ 

    float4 pos : POSITION0; 
    float3 uv0 : TEXCOORD0; 
}; 

sampler SkyBoxTex = sampler_state 
{ 
    Texture = <tex0>; 
    MinFilter = LINEAR; 
    MagFilter = LINEAR; 
    MipFilter = LINEAR; 
    AddressU = WRAP; 
    AddressV = WRAP; 
}; 

SkyboxVS VertexSkybox(float3 position : POSITION0, float3 texCoord : TEXCOORD0) 
{ 
    SkyboxVS skyVS = (SkyboxVS)0; 

    skyVS.pos = mul(float4(position, 1.0f), mvp); 
    skyVS.uv0 = texCoord; 

    return skyVS; 
} 

float4 PixelSkybox(float3 texCoord: TEXCOORD0) : COLOR 
{ 
    float4 color = texCUBE(SkyBoxTex, texCoord); 

    return color; 
} 

technique TransformTech 
{ 
    pass P5 
    { 
     vertexShader = compile vs_2_0 VertexSkybox(); 
     pixelShader = compile ps_2_0 PixelSkybox(); 

     ZFunc = Always; 
     StencilEnable = true; 
     StencilFunc = Always; 

     StencilPass = Replace; 
     StencilRef = 0; 
    } 
} 
+0

你設置視圖/世界/投影矩陣? – pauld

回答

1

這是一些示例鱈魚E:

Sky::Sky(const std::string& envmapFilename, float skyRadius) 
: mRadius(skyRadius) 
{ 
    HR(D3DXCreateSphere(gd3dDevice, skyRadius, 30, 30, &mSphere, 0)); 
    HR(D3DXCreateCubeTextureFromFile(gd3dDevice, envmapFilename.c_str(), &mEnvMap)); 

    ID3DXBuffer* errors = 0; 
    HR(D3DXCreateEffectFromFile(gd3dDevice, "sky.fx", 0, 0, 0, 
     0, &mFX, &errors)); 
    if(errors) 
     MessageBox(0, (char*)errors->GetBufferPointer(), 0, 0); 

    mhTech = mFX->GetTechniqueByName("SkyTech"); 
    mhWVP = mFX->GetParameterByName(0, "gWVP"); 
    mhEnvMap = mFX->GetParameterByName(0, "gEnvMap"); 

    // Set effect parameters that do not vary. 
    HR(mFX->SetTechnique(mhTech)); 
    HR(mFX->SetTexture(mhEnvMap, mEnvMap)); 
} 


void Sky::draw() 
{ 
    // Sky always centered about camera's position. 
    D3DXMATRIX W; 
    D3DXVECTOR3 p = gCamera->pos(); 
    D3DXMatrixTranslation(&W, p.x, p.y, p.z); 
    HR(mFX->SetMatrix(mhWVP, &(W*gCamera->viewProj()))); 

    UINT numPasses = 0; 
    HR(mFX->Begin(&numPasses, 0)); 
    HR(mFX->BeginPass(0)); 
    HR(mSphere->DrawSubset(0)); 
    HR(mFX->EndPass()); 
    HR(mFX->End()); 
} 

和Shader代碼:

OutputVS EnvMapVS(float3 posL : POSITION0, float3 normalL : NORMAL0, float2 tex0: TEXCOORD0) 
{ 
    // Zero out our output. 
    OutputVS outVS = (OutputVS)0; 

    // Transform normal to world space. 
    outVS.normalW = mul(float4(normalL, 0.0f), gWorldInvTrans).xyz; 

    // Transform vertex position to world space. 
    float3 posW = mul(float4(posL, 1.0f), gWorld).xyz; 

    // Compute the unit vector from the vertex to the eye. 
    outVS.toEyeW = gEyePosW - posW; 

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

    // Pass on texture coordinates to be interpolated in rasterization. 
    outVS.tex0 = tex0; 

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

float4 EnvMapPS(float3 normalW : TEXCOORD0, 
       float3 toEyeW : TEXCOORD1, 
       float2 tex0 : TEXCOORD2) : COLOR 
{ 
    // Interpolated normals can become unnormal--so normalize. 
    normalW = normalize(normalW); 
    toEyeW = normalize(toEyeW); 

    // Light vector is opposite the direction of the light. 
    float3 lightVecW = -gLight.dirW; 

    // Compute the reflection vector. 
    float3 r = reflect(-lightVecW, normalW); 

    // Determine how much (if any) specular light makes it into the eye. 
    float t = pow(max(dot(r, toEyeW), 0.0f), gMtrl.specPower); 

    // Determine the diffuse light intensity that strikes the vertex. 
    float s = max(dot(lightVecW, normalW), 0.0f); 

    // Get the texture color. 
    float4 texColor = tex2D(TexS, tex0); 

    // Get the reflected color. 
    float3 envMapTex = reflect(-toEyeW, normalW); 
    float3 reflectedColor = texCUBE(EnvMapS, envMapTex); 

    // Weighted average between the reflected color, and usual 
    // diffuse/ambient material color modulated with the texture color. 
    float3 ambientMtrl = gReflectivity*reflectedColor + (1.0f-gReflectivity)*(gMtrl.ambient*texColor); 
    float3 diffuseMtrl = gReflectivity*reflectedColor + (1.0f-gReflectivity)*(gMtrl.diffuse*texColor); 

    // Compute the ambient, diffuse and specular terms separately. 
    float3 spec = t*(gMtrl.spec*gLight.spec).rgb; 
    float3 diffuse = s*(diffuseMtrl*gLight.diffuse.rgb); 
    float3 ambient = ambientMtrl*gLight.ambient; 

    float3 final = ambient + diffuse + spec; 

    // Output the color and the alpha. 
    return float4(final, gMtrl.diffuse.a*texColor.a); 
}