Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

RenderingDevice.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // Lamp : Open source game middleware
00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //------------------------------------------------------------------------------
00019 
00020 /** @file
00021  * レンダリングデバイス実装
00022  * @author Junpee
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     // アドレスモードU
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     // アドレスモードV
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     // Current * alphaTexture
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 // Zテスト
00458 //------------------------------------------------------------------------------
00459 // Zテストの設定
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(), // テクスチャ座標0
00548         D3DDECL_END(), // テクスチャ座標1
00549         D3DDECL_END(), // テクスチャ座標2
00550         D3DDECL_END(), // テクスチャ座標3
00551         D3DDECL_END(), // テクスチャ座標4
00552         D3DDECL_END(), // テクスチャ座標5
00553         D3DDECL_END(), // テクスチャ座標6
00554         D3DDECL_END(), // テクスチャ座標7
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 // D3Dベクトルの設定
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 // D3Dカラーの設定
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 // D3Dカラーの設定
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 } // End of namespace Lamp
00826 //------------------------------------------------------------------------------

Generated on Wed Mar 16 10:29:34 2005 for Lamp by doxygen 1.3.2