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/RenderingDevice.h"
00027 #include "Graphics/Renderer/Renderer.h"
00028 #include "Graphics/System/GraphicsDeviceCapacity.h"
00029 #include "Graphics/Fog/Fog.h"
00030 #include "Graphics/Light/DirectionalLight.h"
00031 #include "Graphics/Light/PointLight.h"
00032 #include "Graphics/Material/Material.h"
00033 #include "Graphics/Texture/Texture.h"
00034
00035 namespace Lamp{
00036
00037
00038 RenderingDevice* RenderingDevice::instance_ = NULL;
00039
00040 const int RenderingDevice::maxActiveLightCount_ =
00041 Renderer::maxActiveLightCount_;
00042
00043
00044
00045
00046
00047 RenderingDevice::RenderingDevice(GraphicsDeviceCapacity* capacity) :
00048 capacity_(capacity), device_(NULL), defaultStateBlock_(NULL){
00049 Assert(instance_ == NULL);
00050 instance_ = this;
00051 resetCounter();
00052 }
00053
00054
00055 RenderingDevice::~RenderingDevice(){
00056
00057 invalidateDefaultStateBlock();
00058 Assert(instance_ == this);
00059 instance_ = NULL;
00060 }
00061
00062
00063
00064
00065 void RenderingDevice::setRenderState(D3DRENDERSTATETYPE type, u_int state){
00066 DirectXCheck(device_->SetRenderState(type, state));
00067 }
00068
00069
00070 void RenderingDevice::setTextureState(
00071 u_int stage, D3DTEXTURESTAGESTATETYPE type, u_int state){
00072 DirectXCheck(device_->SetTextureStageState(stage, type, state));
00073 }
00074
00075
00076 void RenderingDevice::setSamplerState(
00077 u_int stage, D3DSAMPLERSTATETYPE type, u_int state){
00078 DirectXCheck(device_->SetSamplerState(stage, type, state));
00079 }
00080
00081
00082
00083
00084 void RenderingDevice::beginStateBlock(){
00085 DirectXCheck(device_->BeginStateBlock());
00086 }
00087
00088
00089 Direct3DStateBlock* RenderingDevice::endStateBlock(){
00090 Direct3DStateBlock* stateBlock;
00091 DirectXCheck(device_->EndStateBlock(&stateBlock));
00092 return stateBlock;
00093 }
00094
00095
00096 void RenderingDevice::applyStateBlock(Direct3DStateBlock* stateBlock){
00097 Assert(stateBlock != NULL);
00098 DirectXCheck(stateBlock->Apply());
00099 }
00100
00101
00102 void RenderingDevice::restoreDefaultStateBlock(Direct3DDevice* direct3DDevice){
00103 device_ = direct3DDevice;
00104
00105 DirectXCheck(device_->CreateStateBlock(D3DSBT_ALL, &defaultStateBlock_));
00106 }
00107
00108
00109
00110
00111 DimensionI RenderingDevice::getRenderTargetSize(){
00112 Direct3DSurface* surface;
00113 DirectXCheck(device_->GetRenderTarget(0, &surface));
00114 D3DSurfaceDescription description;
00115 DirectXCheck(surface->GetDesc(&description));
00116 DimensionI result(description.Width, description.Height);
00117 SafeRelease(surface);
00118 return result;
00119 }
00120
00121
00122
00123
00124 bool RenderingDevice::beginScene(){
00125
00126 if(DirectXFailed(device_->BeginScene())){ return false; }
00127 return true;
00128 }
00129
00130
00131 void RenderingDevice::endScene(){
00132 DirectXCheck(device_->EndScene());
00133 }
00134
00135
00136
00137
00138 void RenderingDevice::setProjectionMatrix(const Matrix44& projectionMatrix){
00139 Matrix44 transposeMatrix = projectionMatrix;
00140 transposeMatrix.transpose();
00141 DirectXCheck(device_->SetTransform(
00142 D3DTS_PROJECTION, (const D3DMATRIX*)transposeMatrix.array));
00143 }
00144
00145
00146 void RenderingDevice::setViewMatrix(const Matrix44& viewMatrix){
00147 Matrix44 transposeMatrix = viewMatrix;
00148 transposeMatrix.transpose();
00149 DirectXCheck(device_->SetTransform(
00150 D3DTS_VIEW, (const D3DMATRIX*)transposeMatrix.array));
00151 }
00152
00153
00154 void RenderingDevice::setWorldMatrix(const Matrix34& worldMatrix){
00155 Matrix44 worldMatrix44(
00156 worldMatrix.m00, worldMatrix.m10, worldMatrix.m20, 0.f,
00157 worldMatrix.m01, worldMatrix.m11, worldMatrix.m21, 0.f,
00158 worldMatrix.m02, worldMatrix.m12, worldMatrix.m22, 0.f,
00159 worldMatrix.m03, worldMatrix.m13, worldMatrix.m23, 1.f);
00160 DirectXCheck(device_->SetTransform(
00161 D3DTS_WORLD, (D3DMATRIX*)worldMatrix44.array));
00162 }
00163
00164
00165 void RenderingDevice::setTextureTransform2(u_int stage,
00166 const TexCoord2& repeat, const TexCoord2& offset){
00167 if((repeat == TexCoord2(1.f, 1.f)) &&
00168 (offset == TexCoord2(0.f, 0.f))){
00169 setTextureState(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
00170 return;
00171 }
00172 Matrix44 textureMatrix(
00173 repeat.u, 0.f, 0.f, 0.f,
00174 0.f, repeat.v, 0.f, 0.f,
00175 offset.u, offset.v, 1.f, 0.f,
00176 0.f, 0.f, 0.f, 1.f);
00177 DirectXCheck(device_->SetTransform(
00178 (D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + stage),
00179 (const D3DMATRIX*)textureMatrix.array));
00180 setTextureState(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
00181 }
00182
00183
00184
00185
00186 void RenderingDevice::setViewport(const RectangleI& rectangle){
00187 D3DViewport viewport;
00188 viewport.X = rectangle.x;
00189 viewport.Y = rectangle.y;
00190 viewport.Width = rectangle.width;
00191 viewport.Height = rectangle.height;
00192 viewport.MinZ = 0.f;
00193 viewport.MaxZ = 1.f;
00194 DirectXCheck(device_->SetViewport(&viewport));
00195 }
00196
00197
00198 void RenderingDevice::resetViewport(){
00199 RectangleI rectangle;
00200 DimensionI size = getRenderTargetSize();
00201 rectangle.set(0, 0, size.width, size.height);
00202 setViewport(rectangle);
00203 }
00204
00205
00206
00207
00208 void RenderingDevice::setLighting(bool lighting){
00209 setRenderState(D3DRS_LIGHTING, lighting);
00210 }
00211
00212
00213 void RenderingDevice::setAmbientColor(const Color3f& ambientColor){
00214 Color4c color(ambientColor);
00215 setRenderState(D3DRS_AMBIENT, color.getARGB());
00216 }
00217
00218
00219 void RenderingDevice::enableDirectionalLight(
00220 int lightIndex, DirectionalLight* directionalLight){
00221 Assert((lightIndex >= 0) && (lightIndex < maxActiveLightCount_));
00222 D3DLight light;
00223 ::memset(&light, 0, sizeof(D3DLight));
00224 light.Type = D3DLIGHT_DIRECTIONAL;
00225 setD3DColor(light.Diffuse, directionalLight->getDiffuseColor());
00226 setD3DColor(light.Specular, directionalLight->getSpecularColor());
00227 setD3DVector(light.Direction, directionalLight->getWorldDirection());
00228 DirectXCheck(device_->LightEnable(lightIndex, true));
00229 DirectXCheck(device_->SetLight(lightIndex, &light));
00230 }
00231
00232
00233 void RenderingDevice::enablePointLight(
00234 int lightIndex, PointLight* pointLight){
00235 Assert((lightIndex >= 0) && (lightIndex < maxActiveLightCount_));
00236 D3DLight light;
00237 ::memset(&light, 0, sizeof(D3DLight));
00238 light.Type = D3DLIGHT_POINT;
00239 setD3DColor(light.Diffuse, pointLight->getDiffuseColor());
00240 setD3DColor(light.Specular, pointLight->getSpecularColor());
00241 setD3DVector(light.Position, pointLight->getWorldPosition());
00242 light.Range = pointLight->getGlobalRange();
00243 light.Attenuation0 = pointLight->getAttenuation0();
00244 light.Attenuation1 = pointLight->getAttenuation1();
00245 light.Attenuation2 = pointLight->getAttenuation2();
00246 DirectXCheck(device_->LightEnable(lightIndex, true));
00247 DirectXCheck(device_->SetLight(lightIndex, &light));
00248 }
00249
00250
00251 void RenderingDevice::closeLight(int lightIndex){
00252 for(int i = lightIndex; i < maxActiveLightCount_; i++){
00253 DirectXCheck(device_->LightEnable(i, false));
00254 }
00255 }
00256
00257
00258
00259
00260 void RenderingDevice::setMaterial(
00261 const Color3f& diffuseColor, const Color3f& specularColor,
00262 const Color3f& ambientColor, const Color3f& emissiveColor,
00263 float specularPower, float alpha){
00264
00265 if(specularColor == Color3f::black){
00266 setRenderState(D3DRS_SPECULARENABLE, false);
00267 }else{
00268 setRenderState(D3DRS_SPECULARENABLE, true);
00269 }
00270
00271 D3DMaterial material;
00272 setD3DColor(material.Diffuse, diffuseColor);
00273 material.Diffuse.a = alpha;
00274 setD3DColor(material.Specular, specularColor);
00275 material.Power = specularPower;
00276 setD3DColor(material.Ambient, ambientColor);
00277 setD3DColor(material.Emissive, emissiveColor);
00278 DirectXCheck(device_->SetMaterial(&material));
00279 }
00280
00281
00282 void RenderingDevice::setBlending(bool blendingFlag){
00283 setRenderState(D3DRS_ALPHABLENDENABLE, blendingFlag);
00284 }
00285
00286
00287 void RenderingDevice::setBlendMode(int mode, int source, int destination){
00288 Assert((mode > 0) && (mode < Material::blendModeMax));
00289 Assert((source >= 0) && (source < Material::blendStateMax));
00290 Assert((destination >= 0) && (destination < Material::blendStateMax));
00291
00292 D3DBLENDOP blendModeTable[] = {
00293 (D3DBLENDOP)0,
00294 D3DBLENDOP_ADD,
00295 D3DBLENDOP_SUBTRACT,
00296 D3DBLENDOP_REVSUBTRACT,
00297 D3DBLENDOP_MIN,
00298 D3DBLENDOP_MAX,
00299 };
00300 setRenderState(D3DRS_BLENDOP, blendModeTable[mode]);
00301
00302 D3DBLEND blendStateTable[] = {
00303 D3DBLEND_ZERO,
00304 D3DBLEND_ONE,
00305 D3DBLEND_SRCCOLOR,
00306 D3DBLEND_INVSRCCOLOR,
00307 D3DBLEND_SRCALPHA,
00308 D3DBLEND_INVSRCALPHA,
00309 D3DBLEND_SRCALPHASAT,
00310 D3DBLEND_DESTCOLOR,
00311 D3DBLEND_INVDESTCOLOR,
00312 D3DBLEND_DESTALPHA,
00313 D3DBLEND_INVDESTALPHA,
00314 };
00315 setRenderState(D3DRS_SRCBLEND, blendStateTable[source]);
00316 setRenderState(D3DRS_DESTBLEND, blendStateTable[destination]);
00317 }
00318
00319
00320
00321
00322 void RenderingDevice::setTexture(int textureStage, Texture* texture){
00323 DirectXCheck(device_->SetTexture(textureStage, texture->getD3DTexture()));
00324 }
00325
00326
00327 void RenderingDevice::setTexture(int textureStage, Direct3DTexture* texture){
00328 DirectXCheck(device_->SetTexture(textureStage, texture));
00329 }
00330
00331
00332 void RenderingDevice::setTextureAddressMode2(int textureStage,
00333 int addressModeU, int addressModeV){
00334
00335 if(addressModeU == Texture::addressModeWrap){
00336 setSamplerState(textureStage, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
00337 }else if(addressModeU == Texture::addressModeClamp){
00338 setSamplerState(textureStage, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
00339 }else{
00340 Assert(addressModeU == Texture::addressModeMirror);
00341 setSamplerState(textureStage, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
00342 }
00343
00344 if(addressModeV == Texture::addressModeWrap){
00345 setSamplerState(textureStage, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
00346 }else if(addressModeV == Texture::addressModeClamp){
00347 setSamplerState(textureStage, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
00348 }else{
00349 Assert(addressModeV == Texture::addressModeMirror);
00350 setSamplerState(textureStage, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
00351 }
00352 }
00353
00354
00355 Direct3DTexture* RenderingDevice::createTexture(
00356 D3DFORMAT format, int width, int height){
00357 Direct3DTexture* texture;
00358 DirectXCheck(device_->CreateTexture(width, height, 0, 0,
00359 format, D3DPOOL_MANAGED, &texture, NULL));
00360 return texture;
00361 }
00362
00363
00364 D3DLOCKED_RECT RenderingDevice::lockTexture(
00365 Direct3DTexture* texture, int mipmapLevel){
00366 D3DLOCKED_RECT lockedRect;
00367 DirectXCheck(texture->LockRect(mipmapLevel, &lockedRect, NULL, 0));
00368 return lockedRect;
00369 }
00370
00371
00372 void RenderingDevice::unlockTexture(Direct3DTexture* texture, int mipmapLevel){
00373 DirectXCheck(texture->UnlockRect(mipmapLevel));
00374 }
00375
00376
00377
00378
00379 void RenderingDevice::setColorTextureStage(int colorStage,
00380 D3DTEXTUREOP operation, u_int arg1, u_int arg2, int uvIndex){
00381 setTextureState(colorStage, D3DTSS_COLOROP, operation);
00382 setTextureState(colorStage, D3DTSS_COLORARG1, arg1);
00383 setTextureState(colorStage, D3DTSS_COLORARG2, arg2);
00384 setTextureState(colorStage, D3DTSS_TEXCOORDINDEX, uvIndex);
00385 }
00386
00387
00388 void RenderingDevice::closeColorTextureStage(int colorStage){
00389 if(colorStage == 0){
00390
00391 setColorTextureStage(colorStage,
00392 D3DTOP_SELECTARG1, D3DTA_CURRENT, D3DTA_CURRENT, 0);
00393 colorStage++;
00394 }
00395
00396 setTextureState(colorStage, D3DTSS_COLOROP, D3DTOP_DISABLE);
00397 }
00398
00399
00400 void RenderingDevice::setAlphaTextureStage(int alphaTextureStage){
00401 if(alphaTextureStage == -1){
00402
00403 setTextureState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
00404 setTextureState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
00405
00406 setTextureState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
00407 return;
00408 }
00409
00410 for(int i = 0; i < alphaTextureStage; i++){
00411 setTextureState(i, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
00412 setTextureState(i, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
00413 }
00414
00415 setTextureState(alphaTextureStage, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
00416 setTextureState(alphaTextureStage, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
00417 setTextureState(alphaTextureStage, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
00418
00419 alphaTextureStage++;
00420 setTextureState(alphaTextureStage, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
00421 }
00422
00423
00424
00425
00426 void RenderingDevice::setFog(Fog* fog){
00427 if(fog->isEnabled()){
00428 setRenderState(D3DRS_FOGENABLE, true);
00429 setRenderState(D3DRS_FOGCOLOR, fog->getColor().getARGB());
00430
00431 setRenderState(D3DRS_RANGEFOGENABLE, true);
00432
00433 Fog::Mode fogMode = fog->getMode();
00434 if(fogMode == Fog::modeLinear){
00435
00436 setRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
00437 float fogNear = fog->getNear();
00438 setRenderState(D3DRS_FOGSTART, *(u_int*)&fogNear);
00439 float fogFar = fog->getFar();
00440 setRenderState(D3DRS_FOGEND, *(u_int*)&fogFar);
00441 }else if(fogMode == Fog::modeExponent){
00442
00443 setRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP);
00444 float fogDensity = fog->getDensity();
00445 setRenderState(D3DRS_FOGDENSITY , *(u_int*)&fogDensity);
00446 }else if(fogMode == Fog::modeExponent2){
00447
00448 setRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP2);
00449 float fogDensity = fog->getDensity();
00450 setRenderState(D3DRS_FOGDENSITY , *(u_int*)&fogDensity);
00451 }
00452 }else{
00453 setRenderState(D3DRS_FOGENABLE, false);
00454 }
00455 }
00456
00457
00458
00459
00460 void RenderingDevice::setZTest(bool zTest){
00461 if(zTest){ setRenderState(D3DRS_ZENABLE, D3DZB_TRUE); }
00462 else{ setRenderState(D3DRS_ZENABLE, D3DZB_FALSE); }
00463 }
00464
00465
00466
00467
00468 Direct3DIndexBuffer* RenderingDevice::createStaticIndexBuffer(int bufferSize){
00469 Assert(bufferSize > 0);
00470 Direct3DIndexBuffer* indexBuffer;
00471 DirectXCheck(device_->CreateIndexBuffer(
00472 bufferSize, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,
00473 D3DPOOL_MANAGED, &indexBuffer, NULL));
00474 Assert(indexBuffer != NULL);
00475 return indexBuffer;
00476 }
00477
00478
00479 u_char* RenderingDevice::lockStaticIndexBuffer(
00480 Direct3DIndexBuffer* indexBuffer, int offset, int size){
00481 Assert((indexBuffer != NULL) && (offset >= 0) && (size > 0));
00482 u_char* lockAddress;
00483 DirectXCheck(indexBuffer->Lock(offset, size, (void**)&lockAddress, 0));
00484 return lockAddress;
00485 }
00486
00487
00488 void RenderingDevice::unlockStaticIndexBuffer(
00489 Direct3DIndexBuffer* indexBuffer){
00490 Assert(indexBuffer != NULL);
00491 DirectXCheck(indexBuffer->Unlock());
00492 }
00493
00494
00495 void RenderingDevice::writeStaticIndexBuffer(
00496 Direct3DIndexBuffer* indexBuffer, const void* data, int dataSize){
00497 Assert(data != NULL);
00498 u_char* lockAddress = lockStaticIndexBuffer(indexBuffer, 0, dataSize);
00499 ::memcpy(lockAddress, data, dataSize);
00500 unlockStaticIndexBuffer(indexBuffer);
00501 }
00502
00503
00504 Direct3DIndexBuffer* RenderingDevice::createDynamicIndexBuffer(int bufferSize){
00505 Assert(bufferSize > 0);
00506 Direct3DIndexBuffer* indexBuffer;
00507 DirectXCheck(device_->CreateIndexBuffer(
00508 bufferSize, (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY), D3DFMT_INDEX16,
00509 D3DPOOL_DEFAULT, &indexBuffer, NULL));
00510 Assert(indexBuffer != NULL);
00511 return indexBuffer;
00512 }
00513
00514
00515 void RenderingDevice::writeDynamicIndexBuffer(
00516 Direct3DIndexBuffer* indexBuffer, const void* data, int dataSize){
00517 Assert(indexBuffer != NULL);
00518 Assert(data != NULL);
00519 Assert(dataSize > 0);
00520 u_char* lockAddress;
00521 DirectXCheck(indexBuffer->Lock(
00522 0, dataSize, (void**)&lockAddress, D3DLOCK_DISCARD));
00523 ::memcpy(lockAddress, data, dataSize);
00524 DirectXCheck(indexBuffer->Unlock());
00525 }
00526
00527
00528 void RenderingDevice::setIndexBuffer(Direct3DIndexBuffer* indexBuffer){
00529 DirectXCheck(device_->SetIndices(indexBuffer));
00530 }
00531
00532
00533
00534
00535 int RenderingDevice::createVertexDeclaration(
00536 Direct3DVertexDeclaration** vertexDeclaration, bool hasPosition,
00537 int weightsPerVertex, int bonesPerVertex, bool hasNormal,
00538 bool hasColor, int texCoordSetCount,
00539 const TexCoord::Type* texCoordTypeArray){
00540
00541 D3DVertexElement declarationArray[] = {
00542 D3DDECL_END(),
00543 D3DDECL_END(),
00544 D3DDECL_END(),
00545 D3DDECL_END(),
00546 D3DDECL_END(),
00547 D3DDECL_END(),
00548 D3DDECL_END(),
00549 D3DDECL_END(),
00550 D3DDECL_END(),
00551 D3DDECL_END(),
00552 D3DDECL_END(),
00553 D3DDECL_END(),
00554 D3DDECL_END(),
00555 D3DDECL_END()
00556 };
00557 int vertexSize = 0;
00558 int declarationIndex = 0;
00559
00560
00561 if(hasPosition){
00562 D3DVertexElement element = { 0, vertexSize, D3DDECLTYPE_FLOAT3,
00563 D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0};
00564 declarationArray[declarationIndex] = element;
00565 declarationIndex++;
00566 vertexSize += sizeof(float) * 3;
00567 }
00568
00569
00570 if(weightsPerVertex != 0){
00571 Assert(false);
00572 }
00573
00574
00575 if(bonesPerVertex != 0){
00576 Assert(false);
00577 }
00578
00579
00580 if(hasNormal){
00581 D3DVertexElement element = {
00582 0, vertexSize, D3DDECLTYPE_FLOAT3,
00583 D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0};
00584 declarationArray[declarationIndex] = element;
00585 declarationIndex++;
00586 vertexSize += sizeof(float) * 3;
00587 }
00588
00589
00590 if(hasColor){
00591 D3DVertexElement element = {
00592 0, vertexSize, D3DDECLTYPE_D3DCOLOR,
00593 D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0};
00594 declarationArray[declarationIndex] = element;
00595 declarationIndex++;
00596 vertexSize += sizeof(u_int);
00597 }
00598
00599
00600 D3DDECLTYPE texCoordTypeTable[] = {
00601 D3DDECLTYPE_FLOAT1,
00602 D3DDECLTYPE_FLOAT1,
00603 D3DDECLTYPE_FLOAT2,
00604 D3DDECLTYPE_FLOAT3,
00605 D3DDECLTYPE_FLOAT4
00606 };
00607 for(int i = 0; i < texCoordSetCount; i++){
00608 int texCoordCount = texCoordTypeArray[i];
00609 Assert((texCoordCount > 0) && (texCoordCount <= 4));
00610 D3DVertexElement element = {
00611 0, vertexSize, texCoordTypeTable[texCoordCount],
00612 D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, i};
00613 declarationArray[declarationIndex] = element;
00614 declarationIndex++;
00615 vertexSize += sizeof(float) * texCoordCount;
00616 }
00617
00618 DirectXCheck(device_->CreateVertexDeclaration(
00619 declarationArray, vertexDeclaration));
00620 Assert((*vertexDeclaration) != NULL);
00621 Assert(vertexSize != 0);
00622 return vertexSize;
00623 }
00624
00625
00626 void RenderingDevice::setVertexDeclaration(
00627 Direct3DVertexDeclaration* vertexDeclaration){
00628 DirectXCheck(device_->SetVertexDeclaration(vertexDeclaration));
00629 }
00630
00631
00632
00633
00634 Direct3DVertexBuffer* RenderingDevice::createStaticVertexBuffer(int bufferSize){
00635 Assert(bufferSize > 0);
00636 Direct3DVertexBuffer* vertexBuffer;
00637 DirectXCheck(device_->CreateVertexBuffer(
00638 bufferSize, D3DUSAGE_WRITEONLY, 0,
00639 D3DPOOL_MANAGED, &vertexBuffer, NULL));
00640 Assert(vertexBuffer != NULL);
00641 return vertexBuffer;
00642 }
00643
00644
00645 void RenderingDevice::writeStaticVertexBuffer(
00646 Direct3DVertexBuffer* vertexBuffer, int bufferSize, int vertexCount,
00647 const Vector3* positions, int weightsPerVertex, const float* weights,
00648 int bonesBerVertex, const u_char* boneIndices, const Vector3* normals,
00649 const Color4c* colors, int texCoordSetCount,
00650 const TexCoord::Type* texCoordTypeArray, const float* const* texCoords){
00651 u_char* lockAddress;
00652 DirectXCheck(vertexBuffer->Lock(0, bufferSize, (void**)&lockAddress, 0));
00653 writeVertices(lockAddress, bufferSize, vertexCount, positions,
00654 weightsPerVertex, weights, bonesBerVertex, boneIndices, normals,
00655 colors, texCoordSetCount, texCoordTypeArray, texCoords);
00656 DirectXCheck(vertexBuffer->Unlock());
00657 }
00658
00659
00660 Direct3DVertexBuffer* RenderingDevice::createDynamicVertexBuffer(
00661 int bufferSize){
00662 Assert(bufferSize > 0);
00663 Direct3DVertexBuffer* vertexBuffer;
00664 DirectXCheck(device_->CreateVertexBuffer(
00665 bufferSize, (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY), 0,
00666 D3DPOOL_DEFAULT, &vertexBuffer, NULL));
00667 Assert(vertexBuffer != NULL);
00668 return vertexBuffer;
00669 }
00670
00671
00672 u_char* RenderingDevice::lockDynamicVertexBuffer(
00673 Direct3DVertexBuffer* vertexBuffer, int offset, int size){
00674 u_int flag;
00675 if(offset == 0){ flag = D3DLOCK_DISCARD; }
00676 else{ flag = D3DLOCK_NOOVERWRITE; }
00677 u_char* lockAddress;
00678 DirectXCheck(vertexBuffer->Lock(offset, size, (void**)&lockAddress, flag));
00679 return lockAddress;
00680 }
00681
00682
00683 void RenderingDevice::unlockDynamicVertexBuffer(
00684 Direct3DVertexBuffer* vertexBuffer){
00685 DirectXCheck(vertexBuffer->Unlock());
00686 }
00687
00688
00689 void RenderingDevice::writeDynamicVertexBuffer(
00690 Direct3DVertexBuffer* vertexBuffer, int bufferSize, int vertexCount,
00691 const Vector3* positions, int weightsPerVertex, const float* weights,
00692 int bonesBerVertex, const u_char* boneIndices, const Vector3* normals,
00693 const Color4c* colors, int texCoordSetCount,
00694 const TexCoord::Type* texCoordTypeArray, const float* const* texCoords){
00695 u_char* lockAddress = lockDynamicVertexBuffer(vertexBuffer, 0, bufferSize);
00696 writeVertices(lockAddress, bufferSize, vertexCount, positions,
00697 weightsPerVertex, weights, bonesBerVertex, boneIndices, normals,
00698 colors, texCoordSetCount, texCoordTypeArray, texCoords);
00699 unlockDynamicVertexBuffer(vertexBuffer);
00700 }
00701
00702
00703 void RenderingDevice::setVertexBuffer(
00704 Direct3DVertexBuffer* vertexBuffer, int vertexSize){
00705 DirectXCheck(device_->SetStreamSource(0, vertexBuffer, 0, vertexSize));
00706 }
00707
00708
00709
00710
00711 void RenderingDevice::drawTriangleList(int primitiveCount){
00712 DirectXCheck(device_->DrawPrimitive(D3DPT_TRIANGLELIST, 0, primitiveCount));
00713 }
00714
00715
00716 void RenderingDevice::drawIndexedTriangleList(
00717 int vertexCount, int primitiveCount){
00718 DirectXCheck(device_->DrawIndexedPrimitive(
00719 D3DPT_TRIANGLELIST, 0, 0, vertexCount, 0, primitiveCount));
00720 }
00721
00722
00723 void RenderingDevice::drawIndexedTriangleList(int baseVertexIndex,
00724 int minIndex, int vertexCount, int startIndex, int primitiveCount){
00725 DirectXCheck(device_->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
00726 baseVertexIndex, minIndex, vertexCount, startIndex, primitiveCount));
00727 }
00728
00729
00730 void RenderingDevice::drawLineList(int primitiveCount){
00731 DirectXCheck(device_->DrawPrimitive(D3DPT_LINELIST, 0, primitiveCount));
00732 }
00733
00734
00735 void RenderingDevice::drawIndexedLineList(
00736 int vertexCount, int primitiveCount){
00737 DirectXCheck(device_->DrawIndexedPrimitive(
00738 D3DPT_LINELIST, 0, 0, vertexCount, 0, primitiveCount));
00739 }
00740
00741
00742
00743
00744 void RenderingDevice::writeVertices(
00745 u_char* buffer, int bufferSize, int vertexCount,
00746 const Vector3* positions, int weightsPerVertex, const float* weights,
00747 int bonesBerVertex, const u_char* boneIndices, const Vector3* normals,
00748 const Color4c* colors, int texCoordSetCount,
00749 const TexCoord::Type* texCoordTypeArray, const float* const* texCoords){
00750 Assert(buffer != NULL);
00751 Assert(bufferSize != 0);
00752 Assert(vertexCount != 0);
00753 bool hasPosition = (positions != NULL);
00754 bool hasWeights = (weightsPerVertex > 0);
00755 Assert(!hasWeights);
00756 bool hasBoneIndices = (bonesBerVertex > 0);
00757 Assert(!hasBoneIndices);
00758 bool hasNormal = (normals != NULL);
00759 bool hasColors = (colors != NULL);
00760 u_char* startAddress = buffer;
00761 for(int i = 0; i < vertexCount; i++){
00762
00763 if(hasPosition){
00764 (*(Vector3*)buffer) = (*positions);
00765 buffer += sizeof(Vector3);
00766 positions++;
00767 }
00768
00769 if(hasWeights){
00770 }
00771
00772 if(hasBoneIndices){
00773 }
00774
00775 if(hasNormal){
00776 (*(Vector3*)buffer) = (*normals);
00777 buffer += sizeof(Vector3);
00778 normals++;
00779 }
00780
00781 if(hasColors){
00782 (*(u_int*)buffer) = (*colors).getARGB();
00783 colors++;
00784 buffer += sizeof(u_int);
00785 }
00786
00787
00788 for(int j = 0; j < texCoordSetCount; j++){
00789 int numFloat = texCoordTypeArray[j];
00790 int copySize = sizeof(float) * numFloat;
00791 ::memcpy(buffer, texCoords[j] + (numFloat * i), copySize);
00792 buffer += copySize;
00793 }
00794
00795 }
00796 Assert((buffer - startAddress) == bufferSize);
00797 }
00798
00799
00800 void RenderingDevice::setD3DVector(
00801 D3DVECTOR& destination, const Vector3& source){
00802 destination.x = source.x;
00803 destination.y = source.y;
00804 destination.z = source.z;
00805 }
00806
00807
00808 void RenderingDevice::setD3DColor(
00809 D3DCOLORVALUE& destination, const Color4f& source){
00810 destination.r = source.r;
00811 destination.g = source.g;
00812 destination.b = source.b;
00813 destination.a = source.a;
00814 }
00815
00816
00817 void RenderingDevice::setD3DColor(
00818 D3DCOLORVALUE& destination, const Color3f& source){
00819 destination.r = source.r;
00820 destination.g = source.g;
00821 destination.b = source.b;
00822 destination.a = 0.f;
00823 }
00824
00825 }
00826