/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ #include "hsConfig.h" #include "hsWindows.h" #include #include #include "hsTypes.h" #include "plDXVertexShader.h" #include "../plSurface/plShader.h" #include "plGBufferGroup.h" #include "plDXPipeline.h" plDXVertexShader::plDXVertexShader(plShader* owner) : plDXShader(owner), fHandle(nil) { } plDXVertexShader::~plDXVertexShader() { Release(); } void plDXVertexShader::Release() { ReleaseObject(fHandle); fHandle = nil; fPipe = nil; ISetError(nil); } hsBool plDXVertexShader::VerifyFormat(UInt8 format) const { return (fOwner->GetInputFormat() & format) == fOwner->GetInputFormat(); } IDirect3DVertexShader9 *plDXVertexShader::GetShader(plDXPipeline* pipe) { HRESULT hr = S_OK; if ( !fHandle ) { if( FAILED(hr = ICreate(pipe)) ) return nil; } if( FAILED(hr = ISetConstants(pipe)) ) return nil; return fHandle; } HRESULT plDXVertexShader::ICreate(plDXPipeline* pipe) { fHandle = nil; // in case something goes wrong. fPipe = nil; ISetError(nil); #ifdef HS_DEBUGGING DWORD flags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION; #else // HS_DEBUGGING DWORD flags = 0; #endif // HS_DEBUGGING // We could store the compiled buffer and skip the assembly step // if we need to recreate the shader (e.g. on device lost). // But whatever. DWORD* shaderCodes = nil; HRESULT hr = S_OK; if( plShaderTable::LoadFromFile() || !fOwner->GetDecl()->GetCodes() ) { if( fOwner->GetDecl()->GetFileName() ) { LPD3DXBUFFER compiledShader = nil; LPD3DXBUFFER compilationErrors = nil; hr = D3DXAssembleShaderFromFile( fOwner->GetDecl()->GetFileName(), NULL, NULL, flags, &compiledShader, &compilationErrors); if( FAILED(hr) ) { return IOnError(hr, compilationErrors ? (char*)compilationErrors->GetBufferPointer() : "File not found"); } shaderCodes = (DWORD*)(compiledShader->GetBufferPointer()); } } if( !shaderCodes ) { shaderCodes = (DWORD*)(fOwner->GetDecl()->GetCodes()); } if( !shaderCodes ) return IOnError(-1, "No file and no compiled codes"); hr = pipe->GetD3DDevice()->CreateVertexShader(shaderCodes, &fHandle); if( FAILED(hr) ) return IOnError(hr, "Error on CreateVertexShader"); hsAssert(fHandle, "No error, but no vertex shader handle. Grrrr."); fPipe = pipe; return S_OK; } HRESULT plDXVertexShader::ISetConstants(plDXPipeline* pipe) { hsAssert(fHandle, "Vertex shader called to set constants without initialization"); if( fOwner->GetNumConsts() ) { HRESULT hr = pipe->GetD3DDevice()->SetVertexShaderConstantF(0, (float*)fOwner->GetConstBasePtr(), fOwner->GetNumConsts()); if( FAILED(hr) ) return IOnError(hr, "Failure setting vertex shader constants"); } return S_OK; }