00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "LampBasic.h"
00026 #include "Graphics/Renderer/Renderer.h"
00027 #include "Graphics/Renderer/DrawRequest.h"
00028 #include "Graphics/System/LampGraphics.h"
00029 #include "Graphics/Renderer/RenderingDevice.h"
00030 #include "Graphics/System/GraphicsDeviceCapacity.h"
00031 #include "Graphics/Camera/Camera.h"
00032 #include "Graphics/Light/LightManager.h"
00033 #include "Graphics/Mesh/Mesh.h"
00034 #include "Graphics/Material/Material.h"
00035
00036 namespace Lamp{
00037
00038
00039
00040
00041
00042 Renderer::Renderer() : meshList_(initialMeshListSize){
00043
00044 LampGraphics::addDeviceObjectHolder(this);
00045 buildRendererStateBlock();
00046 drawRequest_ = new DrawRequest();
00047 }
00048
00049
00050 Renderer::~Renderer(){
00051 SafeDelete(drawRequest_);
00052 SafeRelease(rendererStateBlock_);
00053
00054 LampGraphics::removeDeviceObjectHolder(this);
00055 }
00056
00057
00058
00059
00060 void Renderer::renderingSetup(Scene* scene){
00061 RenderingDevice* device = RenderingDevice::getInstance();
00062 scene_ = scene;
00063
00064 buildMeshList();
00065
00066 initializeDrawRequest();
00067 }
00068
00069
00070 void Renderer::rendering(){
00071 RenderingDevice* device = RenderingDevice::getInstance();
00072
00073 device->applyDefaultStateBlock();
00074
00075 device->applyStateBlock(rendererStateBlock_);
00076
00077 initializeGlobalSettings();
00078
00079 if(device->beginScene()){
00080 int meshCount = meshList_.getCount();
00081 for(int i = 0; i < meshCount; i++){
00082 Mesh* mesh = meshList_.get(i);
00083 Material* material = mesh->getMaterial();
00084 drawRequest_->setMesh(mesh);
00085
00086 if(drawRequest_->isBlendEnabled()){
00087 device->setBlending(true);
00088 device->setRenderState(
00089 D3DRS_ALPHAREF, blendingAlphaTestBorder_);
00090 }
00091
00092 if(material->useLight()){
00093 drawRequest_->clearLocalLights();
00094 scene_->getLocalLightList(mesh, drawRequest_);
00095 }
00096
00097 material->draw(drawRequest_);
00098 }
00099
00100 device->endScene();
00101 }
00102
00103 device->applyDefaultStateBlock();
00104 }
00105
00106
00107 void Renderer::buildMeshList(){
00108 meshList_.clear();
00109 Camera* camera = scene_->getCurrentCamera();
00110 scene_->getMeshList(&meshList_, camera);
00111 int meshCount = meshList_.getCount();
00112
00113 Vector3 cameraPosition = camera->getPosition();
00114 for(int i = 0; i < meshCount; i++){
00115 Mesh* mesh = meshList_.get(i);
00116 mesh->setRenderingTemporaryData(
00117 (cameraPosition - mesh->getWorldCenter()).getSquaredLength());
00118 }
00119
00120 meshList_.sort(sortMeshList);
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 }
00134
00135
00136 int Renderer::sortMeshList(Mesh* const* left, Mesh* const* right){
00137 const Mesh* leftMesh = (*left);
00138 const Mesh* rightMesh = (*right);
00139 const Material* leftMaterial = leftMesh->getMaterial();
00140 const Material* rightMaterial = rightMesh->getMaterial();
00141 if(!leftMaterial->isBlendEnabled()){
00142
00143 if(rightMaterial->isBlendEnabled()){ return -1; }
00144
00145
00146 int priority =
00147 rightMaterial->getPriority() - leftMaterial->getPriority();
00148 if(priority != 0){ return priority; }
00149
00150 int leftAddress = (int)((*(u_int*)&leftMaterial) & 0x8fffffff);
00151 int rightAddress = (int)((*(u_int*)&rightMaterial) & 0x8fffffff);
00152 int address = leftAddress - rightAddress;
00153 if(address != 0){ return address; }
00154
00155 float cameraSquaredDistance = rightMesh->getRenderingTemporaryData() -
00156 leftMesh->getRenderingTemporaryData();
00157 if(cameraSquaredDistance > 0.f){ return -1; }
00158 else{ return 1; }
00159 }else{
00160
00161 if(!rightMaterial->isBlendEnabled()){ return 1; }
00162
00163
00164 float cameraSquaredDistance = leftMesh->getRenderingTemporaryData() -
00165 rightMesh->getRenderingTemporaryData();
00166 if(cameraSquaredDistance > 0.f){ return -1; }
00167 else{ return 1; }
00168 }
00169 return 0;
00170 }
00171
00172
00173 void Renderer::initializeDrawRequest(){
00174 drawRequest_->clear();
00175 drawRequest_->setFog(scene_->getFog());
00176 drawRequest_->setCamera(scene_->getCurrentCamera());
00177
00178 LightManager* lightManager = scene_->getLightManager();
00179 int lightCount = lightManager->getCount();
00180 for(int i = 0; i < lightCount; i++){
00181 Light* light = lightManager->get(i);
00182
00183 if(!light->isGlobalEnabled()){ continue; }
00184 if(light->isAmbientLight()){
00185 drawRequest_->addAmbientLight(light->castAmbientLight());
00186 }else if(light->isDirectionalLight()){
00187 drawRequest_->addDirectionalLight(light->castDirectionalLight());
00188 }
00189 }
00190 }
00191
00192
00193 void Renderer::initializeGlobalSettings(){
00194
00195 RenderingDevice* device = RenderingDevice::getInstance();
00196
00197 Camera* camera = drawRequest_->getCamera();
00198 device->setProjectionMatrix(camera->getProjectionMatrix());
00199 device->setViewMatrix(camera->getViewMatrix());
00200
00201 device->setFog(drawRequest_->getFog());
00202 }
00203
00204
00205 void Renderer::buildRendererStateBlock(){
00206 RenderingDevice* device = RenderingDevice::getInstance();
00207 GraphicsDeviceCapacity* capacity = GraphicsDeviceCapacity::getInstance();
00208
00209 device->applyDefaultStateBlock();
00210
00211 device->beginStateBlock();
00212
00213
00214 device->setRenderState(D3DRS_CULLMODE, D3DCULL_CW);
00215
00216
00217 int textureStageCount = capacity->getMaxTextureBlendStages();
00218 for(int i = 0; i < textureStageCount; i++){
00219 device->setSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
00220 device->setSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
00221 device->setSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
00222 }
00223
00224
00225 device->setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
00226 device->setRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
00227 device->setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
00228
00229
00230
00231 device->setRenderState(D3DRS_ALPHATESTENABLE, true);
00232 device->setRenderState(D3DRS_ALPHAREF, alphaTestBorder_);
00233 device->setRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
00234
00235
00236 rendererStateBlock_ = device->endStateBlock();
00237
00238 device->applyDefaultStateBlock();
00239 }
00240
00241 }
00242