// draw draws the set of graphics primitives using the object's world // transformation and reflected colour // void Graphic::draw(const iObject* object, int i) { // if graphic is not setup, set it up if (!isSetup) setup(object); if (isSetup) { #if PIPELINE == FIXED_FUNCTION #elif PIPELINE == PROGRAMMABLE || PIPELINE == PROGRAMMABLE_EFFECT Display* disp = reinterpret_cast<Display*>(display); Matrix worldView = object->world() * disp->viewMatrix(); Matrix worldViewProjection = worldView * disp->projectionMatrix(); #endif #if PIPELINE == FIXED_FUNCTION d3dd->SetTransform(D3DTS_WORLD, (D3DXMATRIX*)(&object->world())); d3dd->SetMaterial(&mat); if (!strcmp(technique, "opaque") || !strcmp(technique, "skybox")) d3dd->SetRenderState(D3DRS_ALPHABLENDENABLE, false); else if (!strcmp(technique, "translucent")) d3dd->SetRenderState(D3DRS_ALPHABLENDENABLE, true); vertexList->draw(i); #elif PIPELINE == PROGRAMMABLE LPD3DXCONSTANTTABLE vertexTable = (LPD3DXCONSTANTTABLE)uniformVS; LPD3DXCONSTANTTABLE fragmentTable = (LPD3DXCONSTANTTABLE)uniformFS; vertexTable->SetMatrix(d3dd, "world", (D3DXMATRIX*)&object->world()); fragmentTable->SetFloatArray(d3dd, "material.ambient", (FLOAT*)&ambient, 4); fragmentTable->SetFloatArray(d3dd, "material.diffuse", (FLOAT*)&diffuse, 4); fragmentTable->SetFloatArray(d3dd, "material.specular", (FLOAT*)&specular, 4); fragmentTable->SetFloat(d3dd, "material.power", (FLOAT)power); if (!strcmp(technique, "opaque") || !strcmp(technique, "skybox")) d3dd->SetRenderState(D3DRS_ALPHABLENDENABLE, false); else if (!strcmp(technique, "translucent")) d3dd->SetRenderState(D3DRS_ALPHABLENDENABLE, true); #elif PIPELINE == PROGRAMMABLE_EFFECT effect->SetInt(stagesHandle, nStages); effect->SetMatrix(worldHandle, (D3DXMATRIX*)&object->world()); effect->SetVector(ambientHandle, (D3DXVECTOR4*)&ambient); effect->SetVector(diffuseHandle, (D3DXVECTOR4*)&diffuse); effect->SetVector(specularHandle, (D3DXVECTOR4*)&specular); effect->SetFloat(powerHandle, power); effect->SetFloat(roughnessHandle, object->getRoughness()); effect->SetFloat(refractionHandle,object->getIndexOfRefraction()); effect->SetInt(algorithmHandle, object->getAlgorithm()); effect->SetMatrix(worldViewHandle, (D3DXMATRIX*)&worldView); effect->SetMatrix(clipMatrixHandle, (D3DXMATRIX*)&worldViewProjection); effect->CommitChanges(); Matrix viewProjectionBak; effect->GetMatrix("viewProjection", (D3DXMATRIX*)&viewProjectionBak); effect->SetTechnique(techniqueHandle); unsigned nPasses; effect->Begin(&nPasses, 0); for (unsigned iPass = 0; iPass < nPasses; iPass++) { effect->BeginPass(iPass); vertexList->draw(i); effect->EndPass(); } effect->End(); #endif } }
bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, const c8* name, const f32* floats, int count) { LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable; if (!tbl) return false; // currently we only support top level parameters. // Should be enough for the beginning. (TODO) D3DXHANDLE hndl = tbl->GetConstantByName(NULL, name); if (!hndl) { core::stringc s = "HLSL Variable to set not found: '"; s += name; s += "'. Available variables are:"; os::Printer::log(s.c_str(), ELL_WARNING); printHLSLVariables(tbl); return false; } HRESULT hr = tbl->SetFloatArray(pID3DDevice, hndl, floats, count); if (FAILED(hr)) { os::Printer::log("Error setting float array for HLSL variable", ELL_WARNING); return false; } return true; }
bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, s32 index, const f32* floats, int count) { LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable; if (index < 0 || !tbl) return false; // currently we only support top level parameters. // Should be enough for the beginning. (TODO) D3DXHANDLE hndl = tbl->GetConstant(NULL, index); if (!hndl) return false; D3DXCONSTANT_DESC Description; UINT ucount = 1; tbl->GetConstantDesc(hndl, &Description, &ucount); if(Description.RegisterSet != D3DXRS_SAMPLER) { HRESULT hr = tbl->SetFloatArray(pID3DDevice, hndl, floats, count); if (FAILED(hr)) { os::Printer::log("Error setting float array for HLSL variable", ELL_WARNING); return false; } } return true; }
// Function for pixel shader that just needs material colour void PS_PlainColourFn( int method, CMatrix4x4* worldMatrix, CCamera* camera ) { // Ensure we have default render states SetDefaultStates(); LPD3DXCONSTANTTABLE shaderConsts = renderMethods[method].pixelConsts; shaderConsts->SetFloatArray( g_pd3dDevice, "MaterialColour", (FLOAT*)&m_DiffuseColour, 3 ); }
// Pass data to pixel shaders that perform pixel lighting (2 point lights) void PS_PixelLit2Fn( int method, CMatrix4x4* worldMatrix, CCamera* camera ) { // Ensure we have default render states SetDefaultStates(); LPD3DXCONSTANTTABLE shaderConsts = renderMethods[method].pixelConsts; D3DXVECTOR3 cameraPos = ToD3DXVECTOR( camera->Position() ); shaderConsts->SetFloatArray( g_pd3dDevice, "CameraPosition", (FLOAT*)&cameraPos, 3 ); shaderConsts->SetFloatArray( g_pd3dDevice, "AmbientLight", (FLOAT*)&m_AmbientLight, 3 ); shaderConsts->SetFloatArray( g_pd3dDevice, "Light1Position", (FLOAT*)&m_Lights[0]->GetPosition(), 3 ); shaderConsts->SetFloatArray( g_pd3dDevice, "Light1Colour", (FLOAT*)&m_Lights[0]->GetColour(), 3 ); shaderConsts->SetFloat( g_pd3dDevice, "Light1Brightness", m_Lights[0]->GetBrightness() ); shaderConsts->SetFloatArray( g_pd3dDevice, "Light2Position", (FLOAT*)&m_Lights[1]->GetPosition(), 3 ); shaderConsts->SetFloatArray( g_pd3dDevice, "Light2Colour", (FLOAT*)&m_Lights[1]->GetColour(), 3 ); shaderConsts->SetFloat( g_pd3dDevice, "Light2Brightness", m_Lights[1]->GetBrightness() ); shaderConsts->SetFloatArray( g_pd3dDevice, "MaterialColour", (FLOAT*)&m_DiffuseColour, 3 ); // If needed shaderConsts->SetFloatArray( g_pd3dDevice, "SpecularStrength", (FLOAT*)&m_SpecularColour, 3 ); // If needed shaderConsts->SetFloat( g_pd3dDevice, "SpecularPower", m_SpecularPower ); }
// Pass data to vertex shaders that perform vertex lighting (1 point light) // Passes full range of data - some shaders don't need all of it. This // reduces the number of these functions at the expense of redundancy void VS_VertLit1Fn( int method, CMatrix4x4* worldMatrix, CCamera* camera ) { LPD3DXCONSTANTTABLE shaderConsts = renderMethods[method].vertexConsts; D3DXMATRIXA16 matViewProj = ToD3DXMATRIX( camera->GetViewProjMatrix() ); shaderConsts->SetMatrix( g_pd3dDevice, "ViewProjMatrix", &matViewProj ); D3DXMATRIX* matWorld = ToD3DXMATRIXPtr( worldMatrix ); shaderConsts->SetMatrix( g_pd3dDevice, "WorldMatrix", matWorld ); D3DXVECTOR3 cameraPos = ToD3DXVECTOR( camera->Position() ); shaderConsts->SetFloatArray( g_pd3dDevice, "CameraPosition", (FLOAT*)&cameraPos, 3 ); // If needed shaderConsts->SetFloatArray( g_pd3dDevice, "AmbientLight", (FLOAT*)&m_AmbientLight, 3 ); shaderConsts->SetFloatArray( g_pd3dDevice, "LightPosition", (FLOAT*)&m_Lights[0]->GetPosition(), 3 ); shaderConsts->SetFloatArray( g_pd3dDevice, "LightColour", (FLOAT*)&m_Lights[0]->GetColour(), 3 ); shaderConsts->SetFloat( g_pd3dDevice, "LightBrightness", m_Lights[0]->GetBrightness() ); shaderConsts->SetFloatArray( g_pd3dDevice, "MaterialColour", (FLOAT*)&m_DiffuseColour, 3 ); // If needed shaderConsts->SetFloatArray( g_pd3dDevice, "SpecularStrength", (FLOAT*)&m_SpecularColour, 3 ); // If needed shaderConsts->SetFloat( g_pd3dDevice, "SpecularPower", m_SpecularPower ); // If needed }