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 //------------------------------------------------------------------------------