diff options
Diffstat (limited to 'src/old/d3dengine.cpp')
-rw-r--r-- | src/old/d3dengine.cpp | 5825 |
1 files changed, 0 insertions, 5825 deletions
diff --git a/src/old/d3dengine.cpp b/src/old/d3dengine.cpp deleted file mode 100644 index f9e953d..0000000 --- a/src/old/d3dengine.cpp +++ /dev/null @@ -1,5825 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -// d3dengine.cpp - - -#include <stdio.h> -#include <math.h> - -#include "common/struct.h" -#include "math/const.h" -#include "math/geometry.h" -#include "math/conv.h" -#include "old/d3dapp.h" -#include "old/d3dtextr.h" -#include "old/d3dutil.h" -#include "old/d3dmath.h" -#include "old/d3dengine.h" -#include "common/language.h" -#include "common/iman.h" -#include "common/event.h" -#include "common/profile.h" -#include "old/math3d.h" -#include "object/object.h" -#include "ui/interface.h" -#include "old/light.h" -#include "old/text.h" -#include "old/particule.h" -#include "old/terrain.h" -#include "old/water.h" -#include "old/cloud.h" -#include "old/blitz.h" -#include "old/planet.h" -#include "old/sound.h" - - - -const int SIZEBLOC_TEXTURE = 50; -const int SIZEBLOC_TRANSFORM = 100; -const int SIZEBLOC_MINMAX = 5; -const int SIZEBLOC_LIGHT = 10; -const int SIZEBLOC_MATERIAL = 100; -const int SIZEBLOC_TRIANGLE = 200; - - - -#if 0 -static int debug_blend1 = 1; -static int debug_blend2 = 3; -static int debug_blend3 = 8; -static int debug_blend4 = 0; - -static int table_blend[13] = -{ - D3DBLEND_ZERO, // 0 - D3DBLEND_ONE, // 1 - D3DBLEND_SRCCOLOR, // 2 - D3DBLEND_INVSRCCOLOR, // 3 - D3DBLEND_SRCALPHA, // 4 - D3DBLEND_INVSRCALPHA, // 5 - D3DBLEND_DESTALPHA, // 6 - D3DBLEND_INVDESTALPHA, // 7 - D3DBLEND_DESTCOLOR, // 8 - D3DBLEND_INVDESTCOLOR, // 9 - D3DBLEND_SRCALPHASAT, // 10 - D3DBLEND_BOTHSRCALPHA, // 11 - D3DBLEND_BOTHINVSRCALPHA, // 12 -}; -#endif - -static int s_resol = 0; - - - -// Converts a FLOAT to a DWORD for use in SetRenderState() calls. - -inline DWORD F2DW( FLOAT f ) -{ - return *((DWORD*)&f); -} - - - - -// Application constructor. Sets attributes for the app. - -CD3DEngine::CD3DEngine(CInstanceManager *iMan, CD3DApplication *app) -{ - int i; - - m_iMan = iMan; - m_iMan->AddInstance(CLASS_ENGINE, this); - m_app = app; - - m_light = new CLight(m_iMan, this); - m_text = new CText(m_iMan, this); - m_particule = new CParticule(m_iMan, this); - m_water = new CWater(m_iMan, this); - m_cloud = new CCloud(m_iMan, this); - m_blitz = new CBlitz(m_iMan, this); - m_planet = new CPlanet(m_iMan, this); - m_pD3DDevice = 0; - m_sound = 0; - m_terrain = 0; - - m_dim.x = 640; - m_dim.y = 480; - m_lastDim = m_dim; - m_focus = 0.75f; - m_baseTime = 0; - m_lastTime = 0; - m_absTime = 0.0f; - m_rankView = 0; - m_ambiantColor[0] = 0x80808080; - m_ambiantColor[1] = 0x80808080; - m_fogColor[0] = 0xffffffff; // white - m_fogColor[1] = 0xffffffff; // white - m_deepView[0] = 1000.0f; - m_deepView[1] = 1000.0f; - m_fogStart[0] = 0.75f; - m_fogStart[1] = 0.75f; - m_waterAddColor.r = 0.0f; - m_waterAddColor.g = 0.0f; - m_waterAddColor.b = 0.0f; - m_waterAddColor.a = 0.0f; - m_bPause = false; - m_bRender = true; - m_bMovieLock = false; - m_bShadow = true; - m_bGroundSpot = true; - m_bDirty = true; - m_bFog = true; - m_speed = 1.0f; - m_secondTexNum = 0; - m_eyeDirH = 0.0f; - m_eyeDirV = 0.0f; - m_backgroundName[0] = 0; // no background image - m_backgroundColorUp = 0; - m_backgroundColorDown = 0; - m_backgroundCloudUp = 0; - m_backgroundCloudDown = 0; - m_bBackgroundFull = false; - m_bBackgroundQuarter = false; - m_bOverFront = true; - m_overColor = 0; - m_overMode = D3DSTATETCb; - m_frontsizeName[0] = 0; // no front image - m_hiliteRank[0] = -1; // empty list - m_mousePos = Math::Point(0.5f, 0.5f); - m_mouseType = D3DMOUSENORM; - m_bMouseHide = false; - m_imageSurface = 0; - m_imageCopy = 0; - m_eyePt = Math::Vector(0.0f, 0.0f, 0.0f); - m_lookatPt = Math::Vector(0.0f, 0.0f, 1.0f); - m_bDrawWorld = true; - m_bDrawFront = false; - m_limitLOD[0] = 100.0f; - m_limitLOD[1] = 200.0f; - m_particuleDensity = 1.0f; - m_clippingDistance = 1.0f; - m_lastClippingDistance = m_clippingDistance; - m_objectDetail = 1.0f; - m_lastObjectDetail = m_objectDetail; - m_terrainVision = 1000.0f; - m_gadgetQuantity = 1.0f; - m_textureQuality = 1; - m_bTotoMode = true; - m_bLensMode = true; - m_bWaterMode = true; - m_bSkyMode = true; - m_bBackForce = true; - m_bPlanetMode = true; - m_bLightMode = true; - m_bEditIndentMode = true; - m_editIndentValue = 4; - m_tracePrecision = 1.0f; - - m_alphaMode = 1; - if ( GetProfileInt("Engine", "AlphaMode", i) ) - { - m_alphaMode = i; - } - - if ( GetProfileInt("Engine", "StateColor", i) && i != -1 ) - { - m_bForceStateColor = true; - m_bStateColor = i; - } - else - { - m_bForceStateColor = false; - m_bStateColor = false; - } - - m_blackSrcBlend[0] = 0; - m_blackDestBlend[0] = 0; - m_whiteSrcBlend[0] = 0; - m_whiteDestBlend[0] = 0; - m_diffuseSrcBlend[0] = 0; - m_diffuseDestBlend[0] = 0; - m_alphaSrcBlend[0] = 0; - m_alphaDestBlend[0] = 0; - - if ( GetProfileInt("Engine", "BlackSrcBlend", i) ) m_blackSrcBlend[0] = i; - if ( GetProfileInt("Engine", "BlackDestBlend", i) ) m_blackDestBlend[0] = i; - if ( GetProfileInt("Engine", "WhiteSrcBlend", i) ) m_whiteSrcBlend[0] = i; - if ( GetProfileInt("Engine", "WhiteDestBlend", i) ) m_whiteDestBlend[0] = i; - if ( GetProfileInt("Engine", "DiffuseSrcBlend", i) ) m_diffuseSrcBlend[0] = i; - if ( GetProfileInt("Engine", "DiffuseDestBlend", i) ) m_diffuseDestBlend[0] = i; - if ( GetProfileInt("Engine", "AlphaSrcBlend", i) ) m_alphaSrcBlend[0] = i; - if ( GetProfileInt("Engine", "AlphaDestBlend", i) ) m_alphaDestBlend[0] = i; - - m_bUpdateGeometry = false; - - for ( i=0 ; i<10 ; i++ ) - { - m_infoText[i][0] = 0; - } - - m_objectPointer = 0; - MemSpace1(m_objectPointer, 0); - - m_objectParam = (D3DObject*)malloc(sizeof(D3DObject)*D3DMAXOBJECT); - ZeroMemory(m_objectParam, sizeof(D3DObject)*D3DMAXOBJECT); - m_objectParamTotal = 0; - - m_shadow = (D3DShadow*)malloc(sizeof(D3DShadow)*D3DMAXSHADOW); - ZeroMemory(m_shadow, sizeof(D3DShadow)*D3DMAXSHADOW); - m_shadowTotal = 0; - - m_groundSpot = (D3DGroundSpot*)malloc(sizeof(D3DGroundSpot)*D3DMAXGROUNDSPOT); - ZeroMemory(m_groundSpot, sizeof(D3DGroundSpot)*D3DMAXGROUNDSPOT); - - ZeroMemory(&m_groundMark, sizeof(D3DGroundMark)); - - D3DTextr_SetTexturePath("textures\\"); -} - -// Application destructor. Free memory. - -CD3DEngine::~CD3DEngine() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int l1, l2, l3, l4, l5; - - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - free(p6); - } - free(p5); - } - free(p4); - } - free(p3); - } - free(p2); - } - free(p1); - - delete m_light; - delete m_particule; - delete m_water; - delete m_cloud; - delete m_blitz; - delete m_planet; -} - - - -void CD3DEngine::SetD3DDevice(LPDIRECT3DDEVICE7 device) -{ - D3DDEVICEDESC7 ddDesc; - - m_pD3DDevice = device; - m_light->SetD3DDevice(device); - m_text->SetD3DDevice(device); - m_particule->SetD3DDevice(device); - - if ( !m_bForceStateColor ) - { - m_pD3DDevice->GetCaps(&ddDesc); - if( ddDesc.dpcTriCaps.dwTextureBlendCaps & D3DPTBLENDCAPS_ADD ) - { - m_bStateColor = true; - } - else - { - m_bStateColor = false; - } - } - - m_blackSrcBlend[1] = D3DBLEND_ONE; // = 2 - m_blackDestBlend[1] = D3DBLEND_INVSRCCOLOR; // = 4 - m_whiteSrcBlend[1] = D3DBLEND_DESTCOLOR; // = 9 - m_whiteDestBlend[1] = D3DBLEND_ZERO; // = 1 - m_diffuseSrcBlend[1] = D3DBLEND_SRCALPHA; // = 5 - m_diffuseDestBlend[1] = D3DBLEND_DESTALPHA; // = 7 - m_alphaSrcBlend[1] = D3DBLEND_ONE; // = 2 - m_alphaDestBlend[1] = D3DBLEND_INVSRCCOLOR; // = 4 - -//? if ( !m_bStateColor ) m_whiteDestBlend[1] = D3DBLEND_INVSRCALPHA; // = 6 - -// Fix for the graphics bug: - //if ( m_blackSrcBlend[0] ) m_blackSrcBlend[1] = m_blackSrcBlend[0]; - //if ( m_blackDestBlend[0] ) m_blackDestBlend[1] = m_blackDestBlend[0]; - //if ( m_whiteSrcBlend[0] ) m_whiteSrcBlend[1] = m_whiteSrcBlend[0]; - //if ( m_whiteDestBlend[0] ) m_whiteDestBlend[1] = m_whiteDestBlend[0]; - - if ( m_diffuseSrcBlend[0] ) m_diffuseSrcBlend[1] = m_diffuseSrcBlend[0]; - if ( m_diffuseDestBlend[0] ) m_diffuseDestBlend[1] = m_diffuseDestBlend[0]; - if ( m_alphaSrcBlend[0] ) m_alphaSrcBlend[1] = m_alphaSrcBlend[0]; - if ( m_alphaDestBlend[0] ) m_alphaDestBlend[1] = m_alphaDestBlend[0]; - -#if 0 - DWORD pass; - m_pD3DDevice->ValidateDevice(&pass); - char s[100]; - sprintf(s, "NbPass=%d", pass); - SetInfoText(3, s); -#endif -} - -LPDIRECT3DDEVICE7 CD3DEngine::RetD3DDevice() -{ - return m_pD3DDevice; -} - - -// Gives the pointer to the existing terrain. - -void CD3DEngine::SetTerrain(CTerrain* terrain) -{ - m_terrain = terrain; -} - - -// Saving the state of the graphics engine in COLOBOT.INI. - -bool CD3DEngine::WriteProfile() -{ - SetProfileInt("Engine", "AlphaMode", m_alphaMode); - - if ( m_bForceStateColor ) - { - SetProfileInt("Engine", "StateColor", m_bStateColor); - } - else - { - SetProfileInt("Engine", "StateColor", -1); - } - - SetProfileInt("Engine", "BlackSrcBlend", m_blackSrcBlend[0]); - SetProfileInt("Engine", "BlackDestBlend", m_blackDestBlend[0]); - SetProfileInt("Engine", "WhiteSrcBlend", m_whiteSrcBlend[0]); - SetProfileInt("Engine", "WhiteDestBlend", m_whiteDestBlend[0]); - SetProfileInt("Engine", "DiffuseSrcBlend", m_diffuseSrcBlend[0]); - SetProfileInt("Engine", "DiffuseDestBlend", m_diffuseDestBlend[0]); - SetProfileInt("Engine", "AlphaSrcBlend", m_alphaSrcBlend[0]); - SetProfileInt("Engine", "AlphaDestBlend", m_alphaDestBlend[0]); - - return true; -} - - -// Setup the app so it can support single-stepping. - -void CD3DEngine::TimeInit() -{ - m_baseTime = timeGetTime(); - m_lastTime = 0; - m_absTime = 0.0f; -} - -void CD3DEngine::TimeEnterGel() -{ - m_stopTime = timeGetTime(); -} - -void CD3DEngine::TimeExitGel() -{ - m_baseTime += timeGetTime() - m_stopTime; -} - -float CD3DEngine::TimeGet() -{ - float aTime, rTime; - - aTime = (timeGetTime()-m_baseTime)*0.001f; // in ms - rTime = (aTime - m_lastTime)*m_speed; - m_absTime += rTime; - m_lastTime = aTime; - - return rTime; -} - - -void CD3DEngine::SetPause(bool bPause) -{ - m_bPause = bPause; -} - -bool CD3DEngine::RetPause() -{ - return m_bPause; -} - - -void CD3DEngine::SetMovieLock(bool bLock) -{ - m_bMovieLock = bLock; -} - -bool CD3DEngine::RetMovieLock() -{ - return m_bMovieLock; -} - - -void CD3DEngine::SetShowStat(bool bShow) -{ - m_app->SetShowStat(bShow); -} - -bool CD3DEngine::RetShowStat() -{ - return m_app->RetShowStat(); -} - - -void CD3DEngine::SetRenderEnable(bool bEnable) -{ - m_bRender = bEnable; -} - - -// Prepare a structure to add D3DObjLevel6 -// qq D3DVERTEX2 elements. - -void CD3DEngine::MemSpace6(D3DObjLevel6 *&p, int nb) -{ - D3DObjLevel6* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_TRIANGLE+nb; - size = sizeof(D3DObjLevel6)+sizeof(D3DVERTEX2)*(total-1); - p = (D3DObjLevel6*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_TRIANGLE+nb; - size = sizeof(D3DObjLevel6)+sizeof(D3DVERTEX2)*(total-1); - pp = (D3DObjLevel6*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel6)+sizeof(D3DVERTEX2)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - -// Prepare a structure to add D3DObjLevel5 -// qq elements D3DObjLevel6. - -void CD3DEngine::MemSpace5(D3DObjLevel5 *&p, int nb) -{ - D3DObjLevel5* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_MATERIAL+nb; - size = sizeof(D3DObjLevel5)+sizeof(D3DObjLevel6*)*(total-1); - p = (D3DObjLevel5*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_MATERIAL+nb; - size = sizeof(D3DObjLevel5)+sizeof(D3DObjLevel6*)*(total-1); - pp = (D3DObjLevel5*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel5)+sizeof(D3DObjLevel6*)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - -// Prepare a structure to add D3DObjLevel4 -// qq D3DObjLevel5 elements. - -void CD3DEngine::MemSpace4(D3DObjLevel4 *&p, int nb) -{ - D3DObjLevel4* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_LIGHT+nb; - size = sizeof(D3DObjLevel4)+sizeof(D3DObjLevel5*)*(total-1); - p = (D3DObjLevel4*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_LIGHT+nb; - size = sizeof(D3DObjLevel4)+sizeof(D3DObjLevel5*)*(total-1); - pp = (D3DObjLevel4*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel4)+sizeof(D3DObjLevel5*)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - -// Prepare a structure to add D3DObjLevel3 -// qq D3DObjLevel4 elements. - -void CD3DEngine::MemSpace3(D3DObjLevel3 *&p, int nb) -{ - D3DObjLevel3* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_MINMAX+nb; - size = sizeof(D3DObjLevel3)+sizeof(D3DObjLevel4*)*(total-1); - p = (D3DObjLevel3*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_MINMAX+nb; - size = sizeof(D3DObjLevel3)+sizeof(D3DObjLevel4*)*(total-1); - pp = (D3DObjLevel3*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel3)+sizeof(D3DObjLevel4*)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - -// Prepare a structure to add D3DObjLevel2 -// qq D3DObjLevel3 elements. - -void CD3DEngine::MemSpace2(D3DObjLevel2 *&p, int nb) -{ - D3DObjLevel2* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_TRANSFORM+nb; - size = sizeof(D3DObjLevel2)+sizeof(D3DObjLevel3*)*(total-1); - p = (D3DObjLevel2*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_TRANSFORM+nb; - size = sizeof(D3DObjLevel2)+sizeof(D3DObjLevel3*)*(total-1); - pp = (D3DObjLevel2*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel2)+sizeof(D3DObjLevel3*)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - -// Prepare a structure to add D3DObjLevel1 -// qq D3DObjLevel2 elements. - -void CD3DEngine::MemSpace1(D3DObjLevel1 *&p, int nb) -{ - D3DObjLevel1* pp; - int total, size; - - if ( p == 0 ) - { - total = SIZEBLOC_TEXTURE+nb; - size = sizeof(D3DObjLevel1)+sizeof(D3DObjLevel2*)*(total-1); - p = (D3DObjLevel1*)malloc(size); - ZeroMemory(p, size); - p->totalPossible = total; - return; - } - - if ( p->totalUsed+nb > p->totalPossible ) - { - total = p->totalPossible+SIZEBLOC_TEXTURE+nb; - size = sizeof(D3DObjLevel1)+sizeof(D3DObjLevel2*)*(total-1); - pp = (D3DObjLevel1*)malloc(size); - ZeroMemory(pp, size); - CopyMemory(pp, p, sizeof(D3DObjLevel1)+sizeof(D3DObjLevel2*)*(p->totalPossible-1)); - pp->totalPossible = total; - free(p); - p = pp; - } -} - - -// Returns the number of objects that can still be created. - -int CD3DEngine::RetRestCreate() -{ - return D3DMAXOBJECT-m_objectParamTotal-2; -} - -// Creates a new object. Returns its rank or -1 on error. - -int CD3DEngine::CreateObject() -{ - Math::Matrix mat; - int i; - - for ( i=0 ; i<D3DMAXOBJECT ; i++ ) - { - if ( m_objectParam[i].bUsed == false ) - { - ZeroMemory(&m_objectParam[i], sizeof(D3DObject)); - m_objectParam[i].bUsed = true; - - mat.LoadIdentity(); - SetObjectTransform(i, mat); - - m_objectParam[i].bDrawWorld = true; - m_objectParam[i].distance = 0.0f; - m_objectParam[i].bboxMin = Math::Vector(0.0f, 0.0f, 0.0f); - m_objectParam[i].bboxMax = Math::Vector(0.0f, 0.0f, 0.0f); - m_objectParam[i].shadowRank = -1; - - if ( i >= m_objectParamTotal ) - { - m_objectParamTotal = i+1; - } - return i; - } - } - OutputDebugString("CD3DEngine::CreateObject() -> Too many object\n"); - return -1; -} - - -// Removes all objects. - -void CD3DEngine::FlushObject() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int l1, l2, l3, l4, l5, i; - - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - free(p6); - } - free(p5); - } - free(p4); - } - free(p3); - } - free(p2); - p1->table[l1] = 0; - } - p1->totalUsed = 0; - - for ( i=0 ; i<D3DMAXOBJECT ; i++ ) - { - m_objectParam[i].bUsed = false; - } - m_objectParamTotal = 0; - - ZeroMemory(m_shadow, sizeof(D3DShadow)*D3DMAXSHADOW); - m_shadowTotal = 0; - - GroundSpotFlush(); -} - -// Destroys an existing object. - -bool CD3DEngine::DeleteObject(int objRank) -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int l1, l2, l3, l4, l5, i; - - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - if ( p3->objRank != objRank ) continue; - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - free(p6); - } - free(p5); - } - free(p4); - } - free(p3); - p2->table[l2] = 0; - } - } - - ShadowDelete(objRank); // removes the shadow - - m_objectParam[objRank].bUsed = false; - - m_objectParamTotal = 0; - for ( i=0 ; i<D3DMAXOBJECT ; i++ ) - { - if ( m_objectParam[i].bUsed ) - { - m_objectParamTotal = i+1; - } - } - - return true; -} - - -// Indicates whether an object should be drawn underneath the interface. - -bool CD3DEngine::SetDrawWorld(int objRank, bool bDraw) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - m_objectParam[objRank].bDrawWorld = bDraw; - return true; -} - -// Indicates whether an object should be drawn over the interface. - -bool CD3DEngine::SetDrawFront(int objRank, bool bDraw) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - m_objectParam[objRank].bDrawFront = bDraw; - return true; -} - - -// Prepare Level 1 to add a triangle. - -D3DObjLevel2* CD3DEngine::AddLevel1(D3DObjLevel1 *&p1, char* texName1, char* texName2) -{ - D3DObjLevel2* p2; - int l1; - - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - if ( strcmp(p2->texName1, texName1) == 0 && - strcmp(p2->texName2, texName2) == 0 ) - { - MemSpace2(p1->table[l1], 1); - return p1->table[l1]; - } - } - - MemSpace1(p1, 1); - l1 = p1->totalUsed++; - p1->table[l1] = 0; - - MemSpace2(p1->table[l1], 1); - strcpy(p1->table[l1]->texName1, texName1); - strcpy(p1->table[l1]->texName2, texName2); - return p1->table[l1]; -} - -// Prepare Level 2 to add a triangle. - -D3DObjLevel3* CD3DEngine::AddLevel2(D3DObjLevel2 *&p2, int objRank) -{ - D3DObjLevel3* p3; - int l2; - - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - if ( p3->objRank == objRank ) - { - MemSpace3(p2->table[l2], 1); - return p2->table[l2]; - } - } - - MemSpace2(p2, 1); - l2 = p2->totalUsed++; - p2->table[l2] = 0; - - MemSpace3(p2->table[l2], 1); - p2->table[l2]->objRank = objRank; - return p2->table[l2]; -} - -// Prepare Level 3 to add a triangle. - -D3DObjLevel4* CD3DEngine::AddLevel3(D3DObjLevel3 *&p3, float min, float max) -{ - D3DObjLevel4* p4; - int l3; - - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( p4->min == min && p4->max == max ) - { - MemSpace4(p3->table[l3], 1); - return p3->table[l3]; - } - } - - MemSpace3(p3, 1); - l3 = p3->totalUsed++; - p3->table[l3] = 0; - - MemSpace4(p3->table[l3], 1); - p3->table[l3]->min = min; - p3->table[l3]->max = max; - return p3->table[l3]; -} - -// Prepare Level 4 to add a triangle. - -D3DObjLevel5* CD3DEngine::AddLevel4(D3DObjLevel4 *&p4, int reserve) -{ - D3DObjLevel5* p5; - int l4; - - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - if ( p5->reserve == reserve ) - { - MemSpace5(p4->table[l4], 1); - return p4->table[l4]; - } - } - - MemSpace4(p4, 1); - l4 = p4->totalUsed++; - p4->table[l4] = 0; - - MemSpace5(p4->table[l4], 1); - p4->table[l4]->reserve = reserve; - return p4->table[l4]; -} - -// Prepares Level 5 to add vertices. - -D3DObjLevel6* CD3DEngine::AddLevel5(D3DObjLevel5 *&p5, D3DTypeTri type, - const D3DMATERIAL7 &mat, int state, - int nb) -{ - D3DObjLevel6* p6; - int l5; - - if ( type == D3DTYPE6T ) - { - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - if ( p6->type == type && - memcmp(&p6->material, &mat, sizeof(D3DMATERIAL7)) == 0 && - p6->state == state ) - { - MemSpace6(p5->table[l5], nb); - return p5->table[l5]; - } - } - } - - MemSpace5(p5, 1); - l5 = p5->totalUsed++; - p5->table[l5] = 0; - - MemSpace6(p5->table[l5], nb); - p5->table[l5]->type = type; - p5->table[l5]->material = mat; - p5->table[l5]->state = state; - return p5->table[l5]; -} - -// Adds one or more triangles to an existing object. -// The number must be divisible by 3. - -bool CD3DEngine::AddTriangle(int objRank, D3DVERTEX2* vertex, int nb, - const D3DMATERIAL7 &mat, int state, - char* texName1, char* texName2, - float min, float max, bool bGlobalUpdate) -{ - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int i; - - m_lastDim = m_dim; - m_lastObjectDetail = m_objectDetail; - m_lastClippingDistance = m_clippingDistance; - - p2 = AddLevel1(m_objectPointer, texName1, texName2); - p3 = AddLevel2(p2, objRank); - p4 = AddLevel3(p3, min, max); - p5 = AddLevel4(p4, 0); - p6 = AddLevel5(p5, D3DTYPE6T, mat, state, nb); // place for number of vertex - - CopyMemory(&p6->vertex[p6->totalUsed], vertex, sizeof(D3DVERTEX2)*nb); - p6->totalUsed += nb; - - if ( bGlobalUpdate ) - { - m_bUpdateGeometry = true; - } - else - { - for ( i=0 ; i<nb ; i++ ) - { - m_objectParam[objRank].bboxMin.x = Math::Min(vertex[i].x, m_objectParam[objRank].bboxMin.x); - m_objectParam[objRank].bboxMin.y = Math::Min(vertex[i].y, m_objectParam[objRank].bboxMin.y); - m_objectParam[objRank].bboxMin.z = Math::Min(vertex[i].z, m_objectParam[objRank].bboxMin.z); - m_objectParam[objRank].bboxMax.x = Math::Max(vertex[i].x, m_objectParam[objRank].bboxMax.x); - m_objectParam[objRank].bboxMax.y = Math::Max(vertex[i].y, m_objectParam[objRank].bboxMax.y); - m_objectParam[objRank].bboxMax.z = Math::Max(vertex[i].z, m_objectParam[objRank].bboxMax.z); - } - - m_objectParam[objRank].radius = Math::Max(m_objectParam[objRank].bboxMin.Length(), - m_objectParam[objRank].bboxMax.Length()); - } - m_objectParam[objRank].totalTriangle += nb/3; - - return true; -} - -// Adds a surface consisting of triangles joined. - -bool CD3DEngine::AddSurface(int objRank, D3DVERTEX2* vertex, int nb, - const D3DMATERIAL7 &mat, int state, - char* texName1, char* texName2, - float min, float max, bool bGlobalUpdate) -{ - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int i; - - p2 = AddLevel1(m_objectPointer, texName1, texName2); - p3 = AddLevel2(p2, objRank); - p4 = AddLevel3(p3, min, max); - p5 = AddLevel4(p4, 0); - p6 = AddLevel5(p5, D3DTYPE6S, mat, state, nb); // place for number of vertex - - CopyMemory(&p6->vertex[p6->totalUsed], vertex, sizeof(D3DVERTEX2)*nb); - p6->totalUsed += nb; - - if ( bGlobalUpdate ) - { - m_bUpdateGeometry = true; - } - else - { - for ( i=0 ; i<nb ; i++ ) - { - m_objectParam[objRank].bboxMin.x = Math::Min(vertex[i].x, m_objectParam[objRank].bboxMin.x); - m_objectParam[objRank].bboxMin.y = Math::Min(vertex[i].y, m_objectParam[objRank].bboxMin.y); - m_objectParam[objRank].bboxMin.z = Math::Min(vertex[i].z, m_objectParam[objRank].bboxMin.z); - m_objectParam[objRank].bboxMax.x = Math::Max(vertex[i].x, m_objectParam[objRank].bboxMax.x); - m_objectParam[objRank].bboxMax.y = Math::Max(vertex[i].y, m_objectParam[objRank].bboxMax.y); - m_objectParam[objRank].bboxMax.z = Math::Max(vertex[i].z, m_objectParam[objRank].bboxMax.z); - } - - m_objectParam[objRank].radius = Math::Max(m_objectParam[objRank].bboxMin.Length(), - m_objectParam[objRank].bboxMax.Length()); - } - m_objectParam[objRank].totalTriangle += nb-2; - - return true; -} - -// Adds a surface consisting of triangles joined. -// The buffer is not copied. - -bool CD3DEngine::AddQuick(int objRank, D3DObjLevel6* buffer, - char* texName1, char* texName2, - float min, float max, bool bGlobalUpdate) -{ - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - int l5, i; - - p2 = AddLevel1(m_objectPointer, texName1, texName2); - p3 = AddLevel2(p2, objRank); - p4 = AddLevel3(p3, min, max); - p5 = AddLevel4(p4, 0); - - MemSpace5(p5, 1); - l5 = p5->totalUsed++; - p5->table[l5] = buffer; - - if ( bGlobalUpdate ) - { - m_bUpdateGeometry = true; - } - else - { - for ( i=0 ; i<buffer->totalUsed ; i++ ) - { - m_objectParam[objRank].bboxMin.x = Math::Min(buffer->vertex[i].x, m_objectParam[objRank].bboxMin.x); - m_objectParam[objRank].bboxMin.y = Math::Min(buffer->vertex[i].y, m_objectParam[objRank].bboxMin.y); - m_objectParam[objRank].bboxMin.z = Math::Min(buffer->vertex[i].z, m_objectParam[objRank].bboxMin.z); - m_objectParam[objRank].bboxMax.x = Math::Max(buffer->vertex[i].x, m_objectParam[objRank].bboxMax.x); - m_objectParam[objRank].bboxMax.y = Math::Max(buffer->vertex[i].y, m_objectParam[objRank].bboxMax.y); - m_objectParam[objRank].bboxMax.z = Math::Max(buffer->vertex[i].z, m_objectParam[objRank].bboxMax.z); - } - - m_objectParam[objRank].radius = Math::Max(m_objectParam[objRank].bboxMin.Length(), - m_objectParam[objRank].bboxMax.Length()); - } - m_objectParam[objRank].totalTriangle += buffer->totalUsed-2; - - return true; -} - - -// Looking for a list of triangles. - -void CD3DEngine::ChangeLOD() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - int l1, l2, l3; - float oldLimit[2], newLimit[2]; - float oldTerrain, newTerrain; - - oldLimit[0] = RetLimitLOD(0, true); - oldLimit[1] = RetLimitLOD(1, true); - - newLimit[0] = RetLimitLOD(0, false); - newLimit[1] = RetLimitLOD(1, false); - - oldTerrain = m_terrainVision*m_lastClippingDistance; - newTerrain = m_terrainVision*m_clippingDistance; - - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - - if ( Math::IsEqual(p4->min, 0.0f ) && - Math::IsEqual(p4->max, oldLimit[0]) ) - { - p4->max = newLimit[0]; - } - else if ( Math::IsEqual(p4->min, oldLimit[0]) && - Math::IsEqual(p4->max, oldLimit[1]) ) - { - p4->min = newLimit[0]; - p4->max = newLimit[1]; - } - else if ( Math::IsEqual(p4->min, oldLimit[1]) && - Math::IsEqual(p4->max, 1000000.0f ) ) - { - p4->min = newLimit[1]; - } - else if ( Math::IsEqual(p4->min, 0.0f ) && - Math::IsEqual(p4->max, oldTerrain) ) - { - p4->max = newTerrain; - } - } - } - } - - m_lastDim = m_dim; - m_lastObjectDetail = m_objectDetail; - m_lastClippingDistance = m_clippingDistance; -} - -// Looking for a list of triangles. - -D3DObjLevel6* CD3DEngine::SearchTriangle(int objRank, - const D3DMATERIAL7 &mat, int state, - char* texName1, char* texName2, - float min, float max) -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int l1, l2, l3, l4, l5; - - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; -//? if ( strcmp(p2->texName1, texName1) != 0 || -//? strcmp(p2->texName2, texName2) != 0 ) continue; - if ( strcmp(p2->texName1, texName1) != 0 ) continue; - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - if ( p3->objRank != objRank ) continue; - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( p4->min != min || - p4->max != max ) continue; - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; -//? if ( p6->state != state || - if ( (p6->state&(~(D3DSTATEDUALb|D3DSTATEDUALw))) != state || - memcmp(&p6->material, &mat, sizeof(D3DMATERIAL7)) != 0 ) continue; - return p6; - } - } - } - } - } - return 0; -} - -// Secondary changes the texture of an object. - -bool CD3DEngine::ChangeSecondTexture(int objRank, char* texName2) -{ - D3DObjLevel2* newp2; - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - int l1, l2; - - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - if ( strcmp(p2->texName2, texName2) == 0 ) continue; // already new - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - if ( p3->objRank != objRank ) continue; - - newp2 = AddLevel1(m_objectPointer, p2->texName1, texName2); - - if ( newp2->totalUsed >= newp2->totalPossible ) continue; // to do better!!! - newp2->table[newp2->totalUsed++] = p3; - - p2->table[l2] = 0; - } - } - return true; -} - - -// Returns the number of triangles of the object. - -int CD3DEngine::RetTotalTriangles(int objRank) -{ - return m_objectParam[objRank].totalTriangle; -} - -// Return qq triangles of an object. -// qq triangles used to extract an object that explodes. -// "Percent" is between 0 and 1. - -int CD3DEngine::GetTriangles(int objRank, float min, float max, - D3DTriangle* buffer, int size, float percent) -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - D3DVERTEX2* pv; - int l1, l2, l3, l4, l5, l6, i, rank; - - rank = 0; - i = 0; - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; -//? if ( p2->texName[0] == 0 ) continue; - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - if ( p3->objRank != objRank ) continue; - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( p4->min != min || - p4->max != max ) continue; - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - for ( l6=0 ; l6<p6->totalUsed/3 ; l6++ ) - { - if ( (float)i/rank <= percent ) - { - if ( i >= size ) break; - buffer[i].triangle[0] = pv[0]; - buffer[i].triangle[1] = pv[1]; - buffer[i].triangle[2] = pv[2]; - buffer[i].material = p6->material; - buffer[i].state = p6->state; - strcpy(buffer[i].texName1, p2->texName1); - strcpy(buffer[i].texName2, p2->texName2); - i ++; - } - rank ++; - pv += 3; - } - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - for ( l6=0 ; l6<p6->totalUsed-2 ; l6++ ) - { - if ( (float)i/rank <= percent ) - { - if ( i >= size ) break; - buffer[i].triangle[0] = pv[0]; - buffer[i].triangle[1] = pv[1]; - buffer[i].triangle[2] = pv[2]; - buffer[i].material = p6->material; - buffer[i].state = p6->state; - strcpy(buffer[i].texName1, p2->texName1); - strcpy(buffer[i].texName2, p2->texName2); - i ++; - } - rank ++; - pv += 1; - } - } - } - } - } - } - } - return i; -} - -// Give the box of an object. - -bool CD3DEngine::GetBBox(int objRank, Math::Vector &min, Math::Vector &max) -{ - min = m_objectParam[objRank].bboxMin; - max = m_objectParam[objRank].bboxMax; - return true; -} - - -// Change the texture mapping for a list of triangles. - -bool CD3DEngine::ChangeTextureMapping(int objRank, - const D3DMATERIAL7 &mat, int state, - char* texName1, char* texName2, - float min, float max, - D3DMaping mode, - float au, float bu, - float av, float bv) -{ - D3DObjLevel6* p6; - D3DVERTEX2* pv; - int l6, nb; - - p6 = SearchTriangle(objRank, mat, state, texName1, texName2, min, max); - if ( p6 == 0 ) return false; - - pv = &p6->vertex[0]; - nb = p6->totalUsed; - - if ( mode == D3DMAPPINGX ) - { - for ( l6=0 ; l6<nb ; l6++ ) - { - pv->tu = pv->z*au+bu; - pv->tv = pv->y*av+bv; - pv ++; - } - } - - if ( mode == D3DMAPPINGY ) - { - for ( l6=0 ; l6<nb ; l6++ ) - { - pv->tu = pv->x*au+bu; - pv->tv = pv->z*av+bv; - pv ++; - } - } - - if ( mode == D3DMAPPINGZ ) - { - for ( l6=0 ; l6<nb ; l6++ ) - { - pv->tu = pv->x*au+bu; - pv->tv = pv->y*av+bv; - pv ++; - } - } - - if ( mode == D3DMAPPING1X ) - { - for ( l6=0 ; l6<nb ; l6++ ) - { - pv->tu = pv->x*au+bu; - pv ++; - } - } - - if ( mode == D3DMAPPING1Y ) - { - for ( l6=0 ; l6<nb ; l6++ ) - { - pv->tv = pv->y*au+bu; - pv ++; - } - } - - if ( mode == D3DMAPPING1Z ) - { - for ( l6=0 ; l6<nb ; l6++ ) - { - pv->tu = pv->z*au+bu; - pv ++; - } - } - - return true; -} - -// Change the texture mapping for a list of triangles -// to simulate a caterpillar that turns. -// Only the mapping as "u" is changed. -// -// pos: position on the periphery [p] -// tl: length repetitive element of the texture [t] -// ts: beginning of the texture[t] -// tt: total width of the texture [t] -// -// [p] = distance in the 3D world -// [t] = position in the texture (pixels) - -// ^ y 5 -// | 6 o---------o 4 -// | / \ -// | o o -// | 7 | | 3 -// | o current o -// | \ | / -// | 0 o---------o 2 -// | 1 -// -o-----------------------> x -// | -// -// Quand l6=1 : -// 0 1 2 3 4 ... 7 -// o--o---------o--o--o--o-//-o--o development track -// |ps| | -// <--> pe | -// <------------> -// -// Texture : -// o---------------o -// | | -// | o-o-o-o-o | -// | | | | | |<--- texture of the track -// | o-o-o-o-o | -// | | | tl | -// | ->|-|<--- | -// | | | -// o-----|---------o--> u -// | ts | | -// <-----> tt | -// <---------------> - -bool CD3DEngine::TrackTextureMapping(int objRank, - const D3DMATERIAL7 &mat, int state, - char* texName1, char* texName2, - float min, float max, - D3DMaping mode, float pos, float factor, - float tl, float ts, float tt) -{ - D3DObjLevel6* p6; - D3DVERTEX2* pv; - Math::Vector current; - float ps, pe, pps, ppe, offset; - int l6, nb, i, j, s, e; - int is[6], ie[6]; - - p6 = SearchTriangle(objRank, mat, state, texName1, texName2, min, max); - if ( p6 == 0 ) return false; - - pv = &p6->vertex[0]; - nb = p6->totalUsed; - - if ( nb < 12 || nb%6 != 0 ) return false; - - while ( pos < 0.0f ) - { - pos += 1000000.0f; // never negative! - } - - for ( i=0 ; i<6 ; i++ ) - { - for ( j=0 ; j<6 ; j++ ) - { - if ( pv[i].x == pv[j+6].x && - pv[i].y == pv[j+6].y ) - { - current.x = pv[i].x; // position end link - current.y = pv[i].y; - break; - } - } - } - - ps = 0.0f; // start position on the periphery - for ( l6=0 ; l6<nb/6 ; l6++ ) - { - s = e = 0; - for ( i=0 ; i<6 ; i++ ) - { - if ( fabs(pv[i].x-current.x) < 0.0001f && - fabs(pv[i].y-current.y) < 0.0001f ) - { - ie[e++] = i; - } - else - { - is[s++] = i; - } - } - if ( s == 3 && e == 3 ) - { - pe = ps+Math::Point(pv[is[0]].x-pv[ie[0]].x, - pv[is[0]].y-pv[ie[0]].y).Length() / factor; // end position on the periphery - - pps = ps+pos; - ppe = pe+pos; - offset = (float)((int)pps); - pps -= offset; - ppe -= offset; - - for ( i=0 ; i<3 ; i++ ) - { - pv[is[i]].tu = ((pps*tl)+ts)/tt; - pv[ie[i]].tu = ((ppe*tl)+ts)/tt; - } - } - - if ( l6 >= (nb/6)-1 ) break; - for ( i=0 ; i<6 ; i++ ) - { - if ( fabs(pv[i+6].x-current.x) > 0.0001f || - fabs(pv[i+6].y-current.y) > 0.0001f ) - { - current.x = pv[i+6].x; // end next link - current.y = pv[i+6].y; - break; - } - } - ps = pe; // following start position on the periphery - pv += 6; - } - - return true; -} - - -// Updates all the geometric parameters of objects. - -void CD3DEngine::UpdateGeometry() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - int l1, l2, l3, l4, l5, objRank, i; - - if ( !m_bUpdateGeometry ) return; - - for ( i=0 ; i<m_objectParamTotal ; i++ ) - { - m_objectParam[i].bboxMin.x = 0; - m_objectParam[i].bboxMin.y = 0; - m_objectParam[i].bboxMin.z = 0; - m_objectParam[i].bboxMax.x = 0; - m_objectParam[i].bboxMax.y = 0; - m_objectParam[i].bboxMax.z = 0; - m_objectParam[i].radius = 0; - } - - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - - for ( i=0 ; i<p6->totalUsed ; i++ ) - { - m_objectParam[objRank].bboxMin.x = Math::Min(p6->vertex[i].x, m_objectParam[objRank].bboxMin.x); - m_objectParam[objRank].bboxMin.y = Math::Min(p6->vertex[i].y, m_objectParam[objRank].bboxMin.y); - m_objectParam[objRank].bboxMin.z = Math::Min(p6->vertex[i].z, m_objectParam[objRank].bboxMin.z); - m_objectParam[objRank].bboxMax.x = Math::Max(p6->vertex[i].x, m_objectParam[objRank].bboxMax.x); - m_objectParam[objRank].bboxMax.y = Math::Max(p6->vertex[i].y, m_objectParam[objRank].bboxMax.y); - m_objectParam[objRank].bboxMax.z = Math::Max(p6->vertex[i].z, m_objectParam[objRank].bboxMax.z); - } - - m_objectParam[objRank].radius = Math::Max(m_objectParam[objRank].bboxMin.Length(), - m_objectParam[objRank].bboxMax.Length()); - } - } - } - } - } - - m_bUpdateGeometry = false; -} - - -// Determines whether an object is visible, even partially. -// Transformation of "world" must be done​​! - -bool CD3DEngine::IsVisible(int objRank) -{ - Math::Vector center; - DWORD flags; - float radius; - - radius = m_objectParam[objRank].radius; - center = Math::Vector(0.0f, 0.0f, 0.0f); - { - D3DVECTOR centerD3D = VEC_TO_D3DVEC(center); - m_pD3DDevice->ComputeSphereVisibility(¢erD3D, &radius, 1, 0, &flags); - } - - if ( flags & D3DSTATUS_CLIPINTERSECTIONALL ) - { - m_objectParam[objRank].bVisible = false; - return false; - } - m_objectParam[objRank].bVisible = true; - return true; -} - - -// Detects the target object with the mouse. -// Returns the rank of the object or -1. - -int CD3DEngine::DetectObject(Math::Point mouse) -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - D3DVERTEX2* pv; - int l1, l2, l3, l4, l5, i, objRank, nearest; - float dist, min; - - min = 1000000.0f; - nearest = -1; - - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - if ( m_objectParam[objRank].type == TYPETERRAIN ) continue; - if ( !DetectBBox(objRank, mouse) ) continue; - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( p4->min != 0.0f ) continue; // LOD B or C? - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - for ( i=0 ; i<p6->totalUsed/3 ; i++ ) - { - if ( DetectTriangle(mouse, pv, objRank, dist) && - dist < min ) - { - min = dist; - nearest = objRank; - } - pv += 3; - } - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - for ( i=0 ; i<p6->totalUsed-2 ; i++ ) - { - if ( DetectTriangle(mouse, pv, objRank, dist) && - dist < min ) - { - min = dist; - nearest = objRank; - } - pv += 1; - } - } - } - } - } - } - } - return nearest; -} - -// Detects whether the mouse is in a triangle. - -bool CD3DEngine::DetectTriangle(Math::Point mouse, D3DVERTEX2 *triangle, - int objRank, float &dist) -{ - Math::Vector p2D[3], p3D; - Math::Point a, b, c; - int i; - - for ( i=0 ; i<3 ; i++ ) - { - p3D.x = triangle[i].x; - p3D.y = triangle[i].y; - p3D.z = triangle[i].z; - if ( !TransformPoint(p2D[i], objRank, p3D) ) return false; - } - - if ( mouse.x < p2D[0].x && - mouse.x < p2D[1].x && - mouse.x < p2D[2].x ) return false; - if ( mouse.x > p2D[0].x && - mouse.x > p2D[1].x && - mouse.x > p2D[2].x ) return false; - if ( mouse.y < p2D[0].y && - mouse.y < p2D[1].y && - mouse.y < p2D[2].y ) return false; - if ( mouse.y > p2D[0].y && - mouse.y > p2D[1].y && - mouse.y > p2D[2].y ) return false; - - a.x = p2D[0].x; - a.y = p2D[0].y; - b.x = p2D[1].x; - b.y = p2D[1].y; - c.x = p2D[2].x; - c.y = p2D[2].y; - if ( !Math::IsInsideTriangle(a, b, c, mouse) ) return false; - - dist = (p2D[0].z+p2D[1].z+p2D[2].z)/3.0f; - return true; -} - -// Detects whether an object is affected by the mouse. - -bool CD3DEngine::DetectBBox(int objRank, Math::Point mouse) -{ - Math::Vector p, pp; - Math::Point min, max; - int i; - - min.x = 1000000.0f; - min.y = 1000000.0f; - max.x = -1000000.0f; - max.y = -1000000.0f; - - for ( i=0 ; i<8 ; i++ ) - { - if ( i & (1<<0) ) p.x = m_objectParam[objRank].bboxMin.x; - else p.x = m_objectParam[objRank].bboxMax.x; - if ( i & (1<<1) ) p.y = m_objectParam[objRank].bboxMin.y; - else p.y = m_objectParam[objRank].bboxMax.y; - if ( i & (1<<2) ) p.z = m_objectParam[objRank].bboxMin.z; - else p.z = m_objectParam[objRank].bboxMax.z; - if ( TransformPoint(pp, objRank, p) ) - { - if ( pp.x < min.x ) min.x = pp.x; - if ( pp.x > max.x ) max.x = pp.x; - if ( pp.y < min.y ) min.y = pp.y; - if ( pp.y > max.y ) max.y = pp.y; - } - } - - return ( mouse.x >= min.x && - mouse.x <= max.x && - mouse.y >= min.y && - mouse.y <= max.y ); -} - -// Transforms a 3D point (x, y, z) in 2D space (x, y, -) of the window. -// The coordinated p2D.z gives the distance. - -bool CD3DEngine::TransformPoint(Math::Vector &p2D, int objRank, Math::Vector p3D) -{ - p3D = Math::Transform(m_objectParam[objRank].transform, p3D); - p3D = Math::Transform(m_matView, p3D); - - if ( p3D.z < 2.0f ) return false; // behind? - - p2D.x = (p3D.x/p3D.z)*m_matProj.Get(1,1); - p2D.y = (p3D.y/p3D.z)*m_matProj.Get(2,2); - p2D.z = p3D.z; - - p2D.x = (p2D.x+1.0f)/2.0f; // [-1..1] -> [0..1] - p2D.y = (p2D.y+1.0f)/2.0f; - - return true; -} - - -// Calculating the distances between the viewpoint and the origin -// of different objects. - -void CD3DEngine::ComputeDistance() -{ - Math::Vector v; - int i; - float distance; - - if ( s_resol == 0 ) - { - for ( i=0 ; i<m_objectParamTotal ; i++ ) - { - if ( m_objectParam[i].bUsed == false ) continue; - - v.x = m_eyePt.x - m_objectParam[i].transform.Get(1,4); - v.y = m_eyePt.y - m_objectParam[i].transform.Get(2,4); - v.z = m_eyePt.z - m_objectParam[i].transform.Get(3,4); - m_objectParam[i].distance = v.Length(); - } - } - else - { - if ( s_resol == 1 ) - { - distance = 100000.0f; - } - if ( s_resol == 2 ) - { - distance = (RetLimitLOD(0)+RetLimitLOD(1))/2.0f; - } - if ( s_resol == 3 ) - { - distance = 0.0f; - } - - for ( i=0 ; i<m_objectParamTotal ; i++ ) - { - if ( m_objectParam[i].bUsed == false ) continue; - - if ( m_objectParam[i].type == TYPETERRAIN ) - { - v.x = m_eyePt.x - m_objectParam[i].transform.Get(1,4); - v.y = m_eyePt.y - m_objectParam[i].transform.Get(2,4); - v.z = m_eyePt.z - m_objectParam[i].transform.Get(3,4); - m_objectParam[i].distance = v.Length(); - } - else - { - m_objectParam[i].distance = distance; - } - } - } -} - - -// Adjusts settings when first run. - -void CD3DEngine::FirstExecuteAdapt(bool bFirst) -{ - if ( m_app->IsVideo8MB() ) - { - SetGroundSpot(false); - SetSkyMode(false); - } - - if ( m_app->IsVideo32MB() && bFirst ) - { - SetObjectDetail(2.0f); - } -} - -// Returns the total amount of video memory for textures. - -int CD3DEngine::GetVidMemTotal() -{ - return m_app->GetVidMemTotal(); -} - -bool CD3DEngine::IsVideo8MB() -{ - return m_app->IsVideo8MB(); -} - -bool CD3DEngine::IsVideo32MB() -{ - return m_app->IsVideo32MB(); -} - - -// Perform the list of all graphics devices available. - -bool CD3DEngine::EnumDevices(char *bufDevices, int lenDevices, - char *bufModes, int lenModes, - int &totalDevices, int &selectDevices, - int &totalModes, int &selectModes) -{ - return m_app->EnumDevices(bufDevices, lenDevices, - bufModes, lenModes, - totalDevices, selectDevices, - totalModes, selectModes); -} - -bool CD3DEngine::RetFullScreen() -{ - return m_app->RetFullScreen(); -} - -bool CD3DEngine::ChangeDevice(char *device, char *mode, bool bFull) -{ - return m_app->ChangeDevice(device, mode, bFull); -} - - - -Math::Matrix* CD3DEngine::RetMatView() -{ - return &m_matView; -} - -Math::Matrix* CD3DEngine::RetMatLeftView() -{ - return &m_matLeftView; -} - -Math::Matrix* CD3DEngine::RetMatRightView() -{ - return &m_matRightView; -} - - -// Specifies the location and direction of view. - -void CD3DEngine::SetViewParams(const Math::Vector &vEyePt, - const Math::Vector &vLookatPt, - const Math::Vector &vUpVec, - FLOAT fEyeDistance) -{ -#if 0 - m_eyePt = vEyePt; - - // Adjust camera position for left or right eye along the axis - // perpendicular to the view direction vector and the up vector. - Math::Vector vView = (vLookatPt) - (vEyePt); - vView = CrossProduct( vView, (vUpVec) ); - vView = Normalize( vView ) * fEyeDistance; - - Math::Vector vLeftEyePt = (vEyePt) + vView; - Math::Vector vRightEyePt = (vEyePt) - vView; - - // Set the view matrices - Math::LoadViewMatrix( m_matLeftView, (Math::Vector)vLeftEyePt, (Math::Vector)vLookatPt, (Math::Vector)vUpVec ); - Math::LoadViewMatrix( m_matRightView, (Math::Vector)vRightEyePt, (Math::Vector)vLookatPt, (Math::Vector)vUpVec ); - Math::LoadViewMatrix( m_matView, (Math::Vector)vEyePt, (Math::Vector)vLookatPt, (Math::Vector)vUpVec ); -#else - m_eyePt = vEyePt; - m_lookatPt = vLookatPt; - m_eyeDirH = Math::RotateAngle(vEyePt.x-vLookatPt.x, vEyePt.z-vLookatPt.z); - m_eyeDirV = Math::RotateAngle(Math::DistanceProjected(vEyePt, vLookatPt), vEyePt.y-vLookatPt.y); - - Math::LoadViewMatrix(m_matView, vEyePt, vLookatPt, vUpVec); - - if ( m_sound == 0 ) - { - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - } - m_sound->SetListener(vEyePt, vLookatPt); -#endif -} - - -// Specifies the transformation matrix of an object. - -bool CD3DEngine::SetObjectTransform(int objRank, const Math::Matrix &transform) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - m_objectParam[objRank].transform = transform; - return true; -} - -// Gives the transformation matrix of an object. - -bool CD3DEngine::GetObjectTransform(int objRank, Math::Matrix &transform) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - transform = m_objectParam[objRank].transform; - return true; -} - -// Specifies the type of an object. - -bool CD3DEngine::SetObjectType(int objRank, D3DTypeObj type) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - m_objectParam[objRank].type = type; - return true; -} - -// Returns the type of an object. - -D3DTypeObj CD3DEngine::RetObjectType(int objRank) -{ - return m_objectParam[objRank].type; -} - -// Specifies the transparency of an object. - -bool CD3DEngine::SetObjectTransparency(int objRank, float value) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - m_objectParam[objRank].transparency = value; - return true; -} - - -// Allocates a table for shade, if necessary. - -bool CD3DEngine::ShadowCreate(int objRank) -{ - int i; - - // Already allocated? - if ( m_objectParam[objRank].shadowRank != -1 ) return true; - - for ( i=0 ; i<D3DMAXSHADOW ; i++ ) - { - if ( m_shadow[i].bUsed == false ) // Free? - { - ZeroMemory(&m_shadow[i], sizeof(D3DShadow)); - - m_shadow[i].bUsed = true; - m_shadow[i].objRank = objRank; - m_shadow[i].height = 0.0f; - - m_objectParam[objRank].shadowRank = i; - - if ( m_shadowTotal < i+1 ) - { - m_shadowTotal = i+1; - } - return true; - } - } - return false; // not found -} - -// Removes the shadow associated with an object. - -void CD3DEngine::ShadowDelete(int objRank) -{ - int i; - - if ( objRank == -1 ) return; - - i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return; - - m_shadow[i].bUsed = false; - m_shadow[i].objRank = -1; - m_shadow[i].pos = Math::Vector(0.0f, 0.0f, 0.0f); - m_shadow[i].type = D3DSHADOWNORM; - - m_objectParam[objRank].shadowRank = -1; - - m_shadowTotal = 0; - for ( i=0 ; i<D3DMAXSHADOW ; i++ ) - { - if ( m_shadow[i].bUsed ) m_shadowTotal = i+1; - } -} - -// Specifies if the shadow is visible. -// For example, when an object is carried, he has no shadow. - -bool CD3DEngine::SetObjectShadowHide(int objRank, bool bHide) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return false; - - m_shadow[i].bHide = bHide; - return true; -} - -// Specifies the type of the shadow of the object. - -bool CD3DEngine::SetObjectShadowType(int objRank, D3DShadowType type) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return false; - - m_shadow[i].type = type; - return true; -} - -// Specifies the position of the shadow of the object. - -bool CD3DEngine::SetObjectShadowPos(int objRank, const Math::Vector &pos) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return false; - - m_shadow[i].pos = pos; - return true; -} - -// Specifies the normal shadow to the field of the object. - -bool CD3DEngine::SetObjectShadowNormal(int objRank, const Math::Vector &n) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return false; - - m_shadow[i].normal = n; - return true; -} - -// Specifies the angle of the shadow of the object. - -bool CD3DEngine::SetObjectShadowAngle(int objRank, float angle) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return false; - - m_shadow[i].angle = angle; - return true; -} - -// Specifies the radius of the shadow of the object. - -bool CD3DEngine::SetObjectShadowRadius(int objRank, float radius) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return false; - - m_shadow[i].radius = radius; - return true; -} - -// Returns the radius of the shadow of the object. - -float CD3DEngine::RetObjectShadowRadius(int objRank) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return 0.0f; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return false; - - return m_shadow[i].radius; -} - -// Specifies the intensity of the shadow of the object. - -bool CD3DEngine::SetObjectShadowIntensity(int objRank, float intensity) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return false; - - m_shadow[i].intensity = intensity; - return true; -} - -// Specifies the height of the shadow of the object. - -bool CD3DEngine::SetObjectShadowHeight(int objRank, float h) -{ - if ( objRank < 0 || objRank >= D3DMAXOBJECT ) return false; - - int i = m_objectParam[objRank].shadowRank; - if ( i == -1 ) return false; - - m_shadow[i].height = h; - return true; -} - - -// Clears all marks on the ground. - -void CD3DEngine::GroundSpotFlush() -{ - LPDIRECTDRAWSURFACE7 surface; - DDSURFACEDESC2 ddsd; - WORD* pbSurf; - char texName[20]; - int s, y; - - ZeroMemory(m_groundSpot, sizeof(D3DGroundSpot)*D3DMAXGROUNDSPOT); - m_bFirstGroundSpot = true; // drawing power first - - for ( s=0 ; s<16 ; s++ ) - { - sprintf(texName, "shadow%.2d.tga", s); - surface = D3DTextr_GetSurface(texName); - if ( surface == 0 ) continue; - - ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(DDSURFACEDESC2); - if ( surface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != DD_OK ) continue; - - if ( ddsd.ddpfPixelFormat.dwRGBBitCount != 16 ) continue; - - for ( y=0 ; y<(int)ddsd.dwHeight ; y++ ) - { - pbSurf = (WORD*)ddsd.lpSurface; - pbSurf += ddsd.lPitch*y/2; - memset(pbSurf, -1, ddsd.lPitch); // all blank - } - - surface->Unlock(NULL); - } -} - -// Allocates a table for a mark on the ground, if necessary. - -int CD3DEngine::GroundSpotCreate() -{ - int i; - - for ( i=0 ; i<D3DMAXGROUNDSPOT ; i++ ) - { - if ( m_groundSpot[i].bUsed == false ) // free? - { - ZeroMemory(&m_groundSpot[i], sizeof(D3DGroundSpot)); - m_groundSpot[i].bUsed = true; - m_groundSpot[i].smooth = 1.0f; - return i; - } - } - return -1; // not found -} - -// Removes a mark on the ground. - -void CD3DEngine::GroundSpotDelete(int rank) -{ - m_groundSpot[rank].bUsed = false; - m_groundSpot[rank].pos = Math::Vector(0.0f, 0.0f, 0.0f); -} - -// Specifies the position of surface marking of the object. - -bool CD3DEngine::SetObjectGroundSpotPos(int rank, const Math::Vector &pos) -{ - m_groundSpot[rank].pos = pos; - return true; -} - -// Specifies the radius of surface marking of the object. - -bool CD3DEngine::SetObjectGroundSpotRadius(int rank, float radius) -{ - m_groundSpot[rank].radius = radius; - return true; -} - -// Specifies the color of a mark on the ground. - -bool CD3DEngine::SetObjectGroundSpotColor(int rank, D3DCOLORVALUE color) -{ - m_groundSpot[rank].color = color; - return true; -} - -// Specifies the height min / max. - -bool CD3DEngine::SetObjectGroundSpotMinMax(int rank, float min, float max) -{ - m_groundSpot[rank].min = min; - m_groundSpot[rank].max = max; - return true; -} - -// Specifies the transition factor. - -bool CD3DEngine::SetObjectGroundSpotSmooth(int rank, float smooth) -{ - m_groundSpot[rank].smooth = smooth; - return true; -} - - -// Creates ground marks. - -int CD3DEngine::GroundMarkCreate(Math::Vector pos, float radius, - float delay1, float delay2, float delay3, - int dx, int dy, char* table) -{ - ZeroMemory(&m_groundMark, sizeof(D3DGroundMark)); - m_groundMark.bUsed = true; - m_groundMark.phase = 1; - m_groundMark.delay[0] = delay1; - m_groundMark.delay[1] = delay2; - m_groundMark.delay[2] = delay3; - m_groundMark.pos = pos; - m_groundMark.radius = radius; - m_groundMark.intensity = 0.0f; - m_groundMark.dx = dx; - m_groundMark.dy = dy; - m_groundMark.table = table; - return 0; -} - -// Clears the ground. - -bool CD3DEngine::GroundMarkDelete(int rank) -{ - ZeroMemory(&m_groundMark, sizeof(D3DGroundMark)); - return true; -} - - -// Border management (distance limits) depends of the resolution. -// LOD = level-of-detail. - -void CD3DEngine::SetLimitLOD(int rank, float limit) -{ - m_limitLOD[rank] = limit; -} - -float CD3DEngine::RetLimitLOD(int rank, bool bLast) -{ - float limit; - - if ( bLast ) - { - limit = m_limitLOD[rank]; - limit *= m_lastDim.x/640.0f; // limit further if large window! -//? limit += m_limitLOD[0]*(m_lastObjectDetail*2.0f-1.0f); - limit += m_limitLOD[0]*(m_lastObjectDetail*2.0f); - } - else - { - limit = m_limitLOD[rank]; - limit *= m_dim.x/640.0f; // limit further if large window! -//? limit += m_limitLOD[0]*(m_objectDetail*2.0f-1.0f); - limit += m_limitLOD[0]*(m_objectDetail*2.0f); - } - if ( limit < 0.0f ) limit = 0.0f; - - return limit; -} - - -// Definition of the distance field of vision. - -void CD3DEngine::SetTerrainVision(float vision) -{ - m_terrainVision = vision; -} - - -// Management of the global mode of shading. - -void CD3DEngine::SetShadow(bool bMode) -{ - m_bShadow = bMode; -} - -bool CD3DEngine::RetShadow() -{ - return m_bShadow; -} - - -// Management of the global mode of marking. - -void CD3DEngine::SetGroundSpot(bool bMode) -{ - m_bGroundSpot = bMode; -} - -bool CD3DEngine::RetGroundSpot() -{ - return m_bGroundSpot; -} - - -// Management of the global mode of contamination. - -void CD3DEngine::SetDirty(bool bMode) -{ - m_bDirty = bMode; -} - -bool CD3DEngine::RetDirty() -{ - return m_bDirty; -} - - -// Management of the global mode of horizontal fog patches. - -void CD3DEngine::SetFog(bool bMode) -{ - m_bFog = bMode; -} - -bool CD3DEngine::RetFog() -{ - return m_bFog; -} - - -// ndicates whether it is possible to give a color SetState. - -bool CD3DEngine::RetStateColor() -{ - return m_bStateColor; -} - - -// Management of the global mode of secondary texturing. - -void CD3DEngine::SetSecondTexture(int texNum) -{ - m_secondTexNum = texNum; -} - -int CD3DEngine::RetSecondTexture() -{ - return m_secondTexNum; -} - - -// Choice of the rank of the active view. - -void CD3DEngine::SetRankView(int rank) -{ - if ( rank < 0 ) rank = 0; - if ( rank > 1 ) rank = 1; - - if ( m_rankView == 0 && rank == 1 ) // enters the water? - { - m_light->AdaptLightColor(m_waterAddColor, +1.0f); - } - - if ( m_rankView == 1 && rank == 0 ) // out of the water? - { - m_light->AdaptLightColor(m_waterAddColor, -1.0f); - } - - m_rankView = rank; -} - -int CD3DEngine::RetRankView() -{ - return m_rankView; -} - -// Whether to draw the world from the interface. - -void CD3DEngine::SetDrawWorld(bool bDraw) -{ - m_bDrawWorld = bDraw; -} - -// Whether to draw the world on the interface. - -void CD3DEngine::SetDrawFront(bool bDraw) -{ - m_bDrawFront = bDraw; -} - -// Color management ambient. -// color = 0x00rrggbb -// rr: red -// gg: green -// bb: blue - -void CD3DEngine::SetAmbiantColor(D3DCOLOR color, int rank) -{ - m_ambiantColor[rank] = color; -} - -D3DCOLOR CD3DEngine::RetAmbiantColor(int rank) -{ - return m_ambiantColor[rank]; -} - - -// Color management under water. - -void CD3DEngine::SetWaterAddColor(D3DCOLORVALUE color) -{ - m_waterAddColor = color; -} - -D3DCOLORVALUE CD3DEngine::RetWaterAddColor() -{ - return m_waterAddColor; -} - - -// Management of the fog color. - -void CD3DEngine::SetFogColor(D3DCOLOR color, int rank) -{ - m_fogColor[rank] = color; -} - -D3DCOLOR CD3DEngine::RetFogColor(int rank) -{ - return m_fogColor[rank]; -} - - -// Management of the depth of field. -// Beyond this distance, nothing is visible. -// Shortly (according SetFogStart), one enters the fog. - -void CD3DEngine::SetDeepView(float length, int rank, bool bRef) -{ - if ( bRef ) - { - length *= m_clippingDistance; - } - - m_deepView[rank] = length; -} - -float CD3DEngine::RetDeepView(int rank) -{ - return m_deepView[rank]; -} - - -// Management the start of fog. -// With 0.0, the fog from the point of view (fog max). -// With 1.0, the fog from the depth of field (no fog). - -void CD3DEngine::SetFogStart(float start, int rank) -{ - m_fogStart[rank] = start; -} - -float CD3DEngine::RetFogStart(int rank) -{ - return m_fogStart[rank]; -} - - -// Gives the background image to use. - -void CD3DEngine::SetBackground(char *name, D3DCOLOR up, D3DCOLOR down, - D3DCOLOR cloudUp, D3DCOLOR cloudDown, - bool bFull, bool bQuarter) -{ - strcpy(m_backgroundName, name); - m_backgroundColorUp = up; - m_backgroundColorDown = down; - m_backgroundCloudUp = cloudUp; - m_backgroundCloudDown = cloudDown; - m_bBackgroundFull = bFull; - m_bBackgroundQuarter = bQuarter; -} - -// Gives the background image used. - -void CD3DEngine::RetBackground(char *name, D3DCOLOR &up, D3DCOLOR &down, - D3DCOLOR &cloudUp, D3DCOLOR &cloudDown, - bool &bFull, bool &bQuarter) -{ - strcpy(name, m_backgroundName); - up = m_backgroundColorUp; - down = m_backgroundColorDown; - cloudUp = m_backgroundCloudUp; - cloudDown = m_backgroundCloudDown; - bFull = m_bBackgroundFull; - bQuarter = m_bBackgroundQuarter; -} - -// Gives the foreground image to use. - -void CD3DEngine::SetFrontsizeName(char *name) -{ - if ( m_frontsizeName[0] != 0 ) - { - FreeTexture(m_frontsizeName); - } - - strcpy(m_frontsizeName, name); -} - -// Specifies whether to draw the foreground. - -void CD3DEngine::SetOverFront(bool bFront) -{ - m_bOverFront = bFront; -} - -// Gives color to the foreground. - -void CD3DEngine::SetOverColor(D3DCOLOR color, int mode) -{ - m_overColor = color; - m_overMode = mode; -} - - - -// Management of the particle density. - -void CD3DEngine::SetParticuleDensity(float value) -{ - if ( value < 0.0f ) value = 0.0f; - if ( value > 2.0f ) value = 2.0f; - m_particuleDensity = value; -} - -float CD3DEngine::RetParticuleDensity() -{ - return m_particuleDensity; -} - -float CD3DEngine::ParticuleAdapt(float factor) -{ - if ( m_particuleDensity == 0.0f ) - { - return 1000000.0f; - } - return factor/m_particuleDensity; -} - -// Management of the distance of clipping. - -void CD3DEngine::SetClippingDistance(float value) -{ - if ( value < 0.5f ) value = 0.5f; - if ( value > 2.0f ) value = 2.0f; - m_clippingDistance = value; -} - -float CD3DEngine::RetClippingDistance() -{ - return m_clippingDistance; -} - -// Management of objects detals. - -void CD3DEngine::SetObjectDetail(float value) -{ - if ( value < 0.0f ) value = 0.0f; - if ( value > 2.0f ) value = 2.0f; - m_objectDetail = value; -} - -float CD3DEngine::RetObjectDetail() -{ - return m_objectDetail; -} - -// The amount of management objects gadgets. - -void CD3DEngine::SetGadgetQuantity(float value) -{ - if ( value < 0.0f ) value = 0.0f; - if ( value > 1.0f ) value = 1.0f; - - m_gadgetQuantity = value; -} - -float CD3DEngine::RetGadgetQuantity() -{ - return m_gadgetQuantity; -} - -// Managing the quality of textures. - -void CD3DEngine::SetTextureQuality(int value) -{ - if ( value < 0 ) value = 0; - if ( value > 2 ) value = 2; - - if ( value != m_textureQuality ) - { - m_textureQuality = value; - LoadAllTexture(); - } -} - -int CD3DEngine::RetTextureQuality() -{ - return m_textureQuality; -} - - -// Management mode of toto. - -void CD3DEngine::SetTotoMode(bool bPresent) -{ - m_bTotoMode = bPresent; -} - -bool CD3DEngine::RetTotoMode() -{ - return m_bTotoMode; -} - - -// Managing the mode of foreground. - -void CD3DEngine::SetLensMode(bool bPresent) -{ - m_bLensMode = bPresent; -} - -bool CD3DEngine::RetLensMode() -{ - return m_bLensMode; -} - - -// Managing the mode of water. - -void CD3DEngine::SetWaterMode(bool bPresent) -{ - m_bWaterMode = bPresent; -} - -bool CD3DEngine::RetWaterMode() -{ - return m_bWaterMode; -} - - -// Managing the mode of sky. - -void CD3DEngine::SetSkyMode(bool bPresent) -{ - m_bSkyMode = bPresent; -} - -bool CD3DEngine::RetSkyMode() -{ - return m_bSkyMode; -} - - -// Managing the mode of background. - -void CD3DEngine::SetBackForce(bool bPresent) -{ - m_bBackForce = bPresent; -} - -bool CD3DEngine::RetBackForce() -{ - return m_bBackForce; -} - - -// Managing the mode of planets. - -void CD3DEngine::SetPlanetMode(bool bPresent) -{ - m_bPlanetMode = bPresent; -} - -bool CD3DEngine::RetPlanetMode() -{ - return m_bPlanetMode; -} - - -// Managing the mode of dymanic lights. - -void CD3DEngine::SetLightMode(bool bPresent) -{ - m_bLightMode = bPresent; -} - -bool CD3DEngine::RetLightMode() -{ - return m_bLightMode; -} - - -// Management of the indentation mode while editing (CEdit). - -void CD3DEngine::SetEditIndentMode(bool bAuto) -{ - m_bEditIndentMode = bAuto; -} - -bool CD3DEngine::RetEditIndentMode() -{ - return m_bEditIndentMode; -} - - -// Management in advance of a tab when editing (CEdit). - -void CD3DEngine::SetEditIndentValue(int value) -{ - m_editIndentValue = value; -} - -int CD3DEngine::RetEditIndentValue() -{ - return m_editIndentValue; -} - - -void CD3DEngine::SetSpeed(float speed) -{ - m_speed = speed; -} - -float CD3DEngine::RetSpeed() -{ - return m_speed; -} - - -void CD3DEngine::SetTracePrecision(float factor) -{ - m_tracePrecision = factor; -} - -float CD3DEngine::RetTracePrecision() -{ - return m_tracePrecision; -} - - -// Updates the scene after a change of parameters. - -void CD3DEngine::ApplyChange() -{ - m_deepView[0] /= m_lastClippingDistance; - m_deepView[1] /= m_lastClippingDistance; - - SetFocus(m_focus); - ChangeLOD(); - - m_deepView[0] *= m_clippingDistance; - m_deepView[1] *= m_clippingDistance; -} - - - -// Returns the point of view of the user. - -Math::Vector CD3DEngine::RetEyePt() -{ - return m_eyePt; -} - -Math::Vector CD3DEngine::RetLookatPt() -{ - return m_lookatPt; -} - -float CD3DEngine::RetEyeDirH() -{ - return m_eyeDirH; -} - -float CD3DEngine::RetEyeDirV() -{ - return m_eyeDirV; -} - -POINT CD3DEngine::RetDim() -{ - return m_dim; -} - - -// Generates an image name of the watch. - -void QuarterName(char *buffer, char *name, int quarter) -{ - while ( *name != 0 ) - { - if ( *name == '.' ) - { - *buffer++ = 'a'+quarter; - } - *buffer++ = *name++; - } - *buffer++ = 0; -} - -// Frees texture. - -bool CD3DEngine::FreeTexture(char* name) -{ - if ( name[0] == 0 ) return true; - - if ( D3DTextr_DestroyTexture(name) != S_OK ) - { - return false; - } - return true; -} - -// Load a texture. - -bool CD3DEngine::LoadTexture(char* name, int stage) -{ - DWORD mode; - - if ( name[0] == 0 ) return true; - - if ( D3DTextr_GetSurface(name) == NULL ) - { - if ( strstr(name, ".tga") == 0 ) - { - mode = 0; - } - else - { - mode = D3DTEXTR_CREATEWITHALPHA; - } - - if ( D3DTextr_CreateTextureFromFile(name, stage, mode) != S_OK ) - { - return false; - } - - if ( D3DTextr_Restore(name, m_pD3DDevice) != S_OK ) - { - return false; - } - } - return true; -} - -// Load all the textures of the scene. - -bool CD3DEngine::LoadAllTexture() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - int l1, i; - char name[50]; - bool bOK = true; - -#if _POLISH - LoadTexture("textp.tga"); -#else - LoadTexture("text.tga"); -#endif - LoadTexture("mouse.tga"); - LoadTexture("button1.tga"); - LoadTexture("button2.tga"); - LoadTexture("button3.tga"); - LoadTexture("effect00.tga"); - LoadTexture("effect01.tga"); - LoadTexture("effect02.tga"); - LoadTexture("map.tga"); - - if ( m_backgroundName[0] != 0 ) - { - if ( m_bBackgroundQuarter ) // image into 4 pieces? - { - for ( i=0 ; i<4 ; i++ ) - { - QuarterName(name, m_backgroundName, i); - LoadTexture(name); - } - } - else - { - LoadTexture(m_backgroundName); - } - } - if ( m_frontsizeName[0] != 0 ) - { - LoadTexture(m_frontsizeName); - } - - m_planet->LoadTexture(); - - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - - if ( p2 == 0 || p2->texName1[0] != 0 ) - { - if ( !LoadTexture(p2->texName1, 0) ) bOK = false; - } - - if ( p2 == 0 || p2->texName2[0] != 0 ) - { - if ( !LoadTexture(p2->texName2, 1) ) bOK = false; - } - } - return bOK; -} - - -// Called during initial app startup, this function performs all the -// permanent initialization. - -HRESULT CD3DEngine::OneTimeSceneInit() -{ - return S_OK; -} - - -// Updated after creating objects. - -void CD3DEngine::Update() -{ - ComputeDistance(); - UpdateGeometry(); -} - -// Called once per frame, the call is the entry point for animating -// the scene. - -HRESULT CD3DEngine::FrameMove(float rTime) -{ - m_light->FrameLight(rTime); - m_particule->FrameParticule(rTime); - ComputeDistance(); - UpdateGeometry(); - - if ( m_groundMark.bUsed ) - { - if ( m_groundMark.phase == 1 ) // growing? - { - m_groundMark.intensity += rTime*(1.0f/m_groundMark.delay[0]); - if ( m_groundMark.intensity >= 1.0f ) - { - m_groundMark.intensity = 1.0f; - m_groundMark.fix = 0.0f; - m_groundMark.phase = 2; - } - } - else if ( m_groundMark.phase == 2 ) // fixed? - { - m_groundMark.fix += rTime*(1.0f/m_groundMark.delay[1]); - if ( m_groundMark.fix >= 1.0f ) - { - m_groundMark.phase = 3; - } - } - else if ( m_groundMark.phase == 3 ) // decay? - { - m_groundMark.intensity -= rTime*(1.0f/m_groundMark.delay[2]); - if ( m_groundMark.intensity < 0.0f ) - { - m_groundMark.intensity = 0.0f; - m_groundMark.phase = 0; - m_groundMark.bUsed = false; - } - } - } - - if ( m_sound == 0 ) - { - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - } - m_sound->FrameMove(rTime); - - return S_OK; -} - -// Evolved throughout the game - -void CD3DEngine::StepSimul(float rTime) -{ - m_app->StepSimul(rTime); -} - - - -// Changes the state associated with a material. -// (*) Does not work without this instruction, mystery! - -void CD3DEngine::SetState(int state, D3DCOLOR color) -{ - bool bSecond; - - if ( state == m_lastState && - color == m_lastColor ) return; - m_lastState = state; - m_lastColor = color; - - if ( m_alphaMode != 1 && (state & D3DSTATEALPHA) ) - { - state &= ~D3DSTATEALPHA; - - if ( m_alphaMode == 2 ) - { - state |= D3DSTATETTb; - } - } - - if ( state & D3DSTATETTb ) // The transparent black texture? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_blackSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_blackDestBlend[1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend2]); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); // (*) - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - else if ( state & D3DSTATETTw ) // The transparent white texture? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_whiteSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_whiteDestBlend[1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend3]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend4]); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, ~color); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); // (*) - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - else if ( state & D3DSTATETCb ) // The transparent black color? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_blackSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_blackDestBlend[1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend2]); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - else if ( state & D3DSTATETCw ) // The transparent white color? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_whiteSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_whiteDestBlend[1]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, table_blend[debug_blend3]); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, table_blend[debug_blend4]); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, ~color); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - else if ( state & D3DSTATETD ) // diffuse color as transparent? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_diffuseSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_diffuseDestBlend[1]); - - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - else if ( state & D3DSTATEALPHA ) // image with alpha channel? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATER); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAREF, (DWORD)(128)); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_alphaSrcBlend[1]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_alphaSrcBlend[1]); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - } - else // normal ? - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false); - - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - - if ( state & D3DSTATEFOG ) - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, true); - } - - bSecond = m_bGroundSpot|m_bDirty; - if ( !m_bGroundSpot && (state & D3DSTATESECOND) != 0 ) bSecond = false; - if ( !m_bDirty && (state & D3DSTATESECOND) == 0 ) bSecond = false; - - if ( (state & D3DSTATEDUALb) && bSecond ) - { - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - } - else if ( (state & D3DSTATEDUALw) && bSecond ) - { - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - } - else - { - m_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - - if ( state & D3DSTATEWRAP ) - { -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_WRAP0, D3DWRAP_U|D3DWRAP_V); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); - } - else if ( state & D3DSTATECLAMP ) - { -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_WRAP0, 0); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); - } - else - { -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_WRAP0, 0); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); - } - - if ( state & D3DSTATE2FACE ) - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); - } - else - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW); - } - - if ( state & D3DSTATELIGHT ) - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - } - else - { - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, m_ambiantColor[m_rankView]); - } -} - -// Specifies a texture to use. - -void CD3DEngine::SetTexture(char *name, int stage) -{ -//? if ( stage == 1 && !m_bDirty ) return; -//? if ( stage == 1 && !m_bShadow ) return; - - if ( strcmp(name, m_lastTexture[stage]) == 0 ) return; - strcpy(m_lastTexture[stage], name); - - m_pD3DDevice->SetTexture(stage, D3DTextr_GetSurface(name)); -} - -// Specifies the material to use. - -void CD3DEngine::SetMaterial(const D3DMATERIAL7 &mat) -{ - if ( memcmp(&mat, &m_lastMaterial, sizeof(D3DMATERIAL7)) == 0 ) return; - m_lastMaterial = mat; - - m_pD3DDevice->SetMaterial(&m_lastMaterial); -} - - -// Deletes a point in a surface (draw in white). - -inline void ClearDot(DDSURFACEDESC2* ddsd, int x, int y) -{ - WORD* pbSurf; - - if ( ddsd->ddpfPixelFormat.dwRGBBitCount != 16 ) return; - - pbSurf = (WORD*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/2; - pbSurf += x; - - *pbSurf = 0xffff; // white -} - -// Deletes a point in a surface (draw in white) - -void AddDot(DDSURFACEDESC2* ddsd, int x, int y, D3DCOLORVALUE color) -{ - WORD* pbSurf; - WORD r,g,b, w; - - if ( ddsd->ddpfPixelFormat.dwRGBBitCount != 16 ) return; - - if ( color.r < 0.0f ) color.r = 0.0f; - if ( color.r > 1.0f ) color.r = 1.0f; - r = (int)(color.r*32.0f); - if ( r >= 32 ) r = 31; // 5 bits - - if ( color.g < 0.0f ) color.g = 0.0f; - if ( color.g > 1.0f ) color.g = 1.0f; - g = (int)(color.g*32.0f); - if ( g >= 32 ) g = 31; // 5 bits - - if ( color.b < 0.0f ) color.b = 0.0f; - if ( color.b > 1.0f ) color.b = 1.0f; - b = (int)(color.b*32.0f); - if ( b >= 32 ) b = 31; // 5 bits - - if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? - { - w = (r<<11)|(g<<6)|b; - } - else if ( ddsd->ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? - { - w = (r<<10)|(g<<5)|b; - } - else - { - w = -1; // blank - } - - pbSurf = (WORD*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/2; - pbSurf += x; - - *pbSurf &= w; -} - -// Displays a point in a surface. - -void SetDot(DDSURFACEDESC2* ddsd, int x, int y, D3DCOLORVALUE color) -{ - if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 16 ) - { - WORD* pbSurf; - WORD r,g,b, w; - - if ( color.r < 0.0f ) color.r = 0.0f; - if ( color.r > 1.0f ) color.r = 1.0f; - if ( color.g < 0.0f ) color.g = 0.0f; - if ( color.g > 1.0f ) color.g = 1.0f; - if ( color.b < 0.0f ) color.b = 0.0f; - if ( color.b > 1.0f ) color.b = 1.0f; - - r = (int)(color.r*32.0f); - g = (int)(color.g*32.0f); - b = (int)(color.b*32.0f); - - if ( r >= 32 ) r = 31; // 5 bits - if ( g >= 32 ) g = 31; // 5 bits - if ( b >= 32 ) b = 31; // 5 bits - - if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? - { - w = (r<<11)|(g<<6)|b; - } - else if ( ddsd->ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? - { - w = (r<<10)|(g<<5)|b; - } - else - { - w = -1; // blank - } - - pbSurf = (WORD*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/2; - pbSurf += x; - - *pbSurf = w; - } - - if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 32 ) // image .tga ? - { - LONG* pbSurf; - LONG r,g,b, w; - - if ( color.r < 0.0f ) color.r = 0.0f; - if ( color.r > 1.0f ) color.r = 1.0f; - if ( color.g < 0.0f ) color.g = 0.0f; - if ( color.g > 1.0f ) color.g = 1.0f; - if ( color.b < 0.0f ) color.b = 0.0f; - if ( color.b > 1.0f ) color.b = 1.0f; - - r = (int)(color.r*256.0f); - g = (int)(color.g*256.0f); - b = (int)(color.b*256.0f); - - if ( r >= 256 ) r = 255; // 8 bits - if ( g >= 256 ) g = 255; // 8 bits - if ( b >= 256 ) b = 255; // 8 bits - - if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xff0000 ) - { - w = (r<<16)|(g<<8)|b; - - pbSurf = (LONG*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/4; - pbSurf += x; - - *pbSurf &= 0xff000000; // keeps alpha channel - *pbSurf |= w; - } - } -} - -// Gives a point in a surface. - -D3DCOLORVALUE GetDot(DDSURFACEDESC2* ddsd, int x, int y) -{ - D3DCOLORVALUE color; - - if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 16 ) - { - WORD* pbSurf; - WORD r,g,b, w; - - pbSurf = (WORD*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/2; - pbSurf += x; - - w = *pbSurf; - - if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? - { - r = (w>>10)&0x003e; - g = (w>> 5)&0x003f; - b = (w<< 1)&0x003e; - } - else if ( ddsd->ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? - { - r = (w>> 9)&0x003e; - g = (w>> 4)&0x003e; - b = (w<< 1)&0x003e; - } - else - { - r = 0; - g = 0; - b = 0; // black - } - - color.r = (float)r/63.0f; - color.g = (float)g/63.0f; - color.b = (float)b/63.0f; - color.a = 0.0f; - return color; - } - - if ( ddsd->ddpfPixelFormat.dwRGBBitCount == 32 ) // image .tga ? - { - LONG* pbSurf; - LONG r,g,b, w; - - pbSurf = (LONG*)ddsd->lpSurface; - pbSurf += ddsd->lPitch*y/4; - pbSurf += x; - - w = *pbSurf; - - if ( ddsd->ddpfPixelFormat.dwRBitMask == 0xff0000 ) - { - r = (w>>16)&0x00ff; - g = (w>> 8)&0x00ff; - b = (w<< 0)&0x00ff; - } - else - { - r = 0; - g = 0; - b = 0; // black - } - - color.r = (float)r/255.0f; - color.g = (float)g/255.0f; - color.b = (float)b/255.0f; - color.a = 0.0f; - return color; - } - - color.r = 0.0f; - color.g = 0.0f; - color.b = 0.0f; - color.a = 0.0f; // black - return color; -} - -// Draw all the shadows. - -// There is a pixel collection around each of the 16 surfaces: -// -// |<----------------------->|<----------------------->|<---- ... -// 0 | 1 2 253 254|255 | -// |---|---|---|-- ... --|---|---|---| | -// 0 | 1 2 253 254|255 -// |---|---|---|-- ... --|---|---|---| -// -// So we draw in 254x254 pixels surfaces. -// The pixel margin around it is drawn twice (in two adjacent surfaces), -// so that the filter produces the same results! - -void CD3DEngine::RenderGroundSpot() -{ - LPDIRECTDRAWSURFACE7 surface; - DDSURFACEDESC2 ddsd; - WORD* pbSurf; - D3DCOLORVALUE color; - Math::Vector pos; - Math::Point min, max; - int s, i, j, dot, ix, iy, y; - float tu, tv, cx, cy, px, py, ppx, ppy; - float intensity, level; - char texName[20]; - bool bClear, bSet; - - if ( !m_bFirstGroundSpot && - m_groundMark.drawPos.x == m_groundMark.pos.x && - m_groundMark.drawPos.z == m_groundMark.pos.z && - m_groundMark.drawRadius == m_groundMark.radius && - m_groundMark.drawIntensity == m_groundMark.intensity ) return; - - for ( s=0 ; s<16 ; s++ ) - { - min.x = (s%4)*254.0f-1.0f; // 1 pixel cover - min.y = (s/4)*254.0f-1.0f; - max.x = min.x+254.0f+2.0f; - max.y = min.y+254.0f+2.0f; - - bClear = false; - bSet = false; - - // Calculate the area to be erased. - dot = (int)(m_groundMark.drawRadius/2.0f); - - tu = (m_groundMark.drawPos.x+1600.0f)/3200.0f; - tv = (m_groundMark.drawPos.z+1600.0f)/3200.0f; // 0..1 - - cx = (tu*254.0f*4.0f)-0.5f; - cy = (tv*254.0f*4.0f)-0.5f; - - if ( dot == 0 ) - { - cx += 0.5f; - cy += 0.5f; - } - - px = cx-Math::Mod(cx, 1.0f); - py = cy-Math::Mod(cy, 1.0f); // multiple of 1 - - if ( m_bFirstGroundSpot || - ( m_groundMark.drawRadius != 0.0f && - px+dot >= min.x && py+dot >= min.y && - px-dot <= max.x && py-dot <= max.y ) ) - { - bClear = true; - } - - // Calculate the area to draw. - dot = (int)(m_groundMark.radius/2.0f); - - tu = (m_groundMark.pos.x+1600.0f)/3200.0f; - tv = (m_groundMark.pos.z+1600.0f)/3200.0f; // 0..1 - - cx = (tu*254.0f*4.0f)-0.5f; - cy = (tv*254.0f*4.0f)-0.5f; - - if ( dot == 0 ) - { - cx += 0.5f; - cy += 0.5f; - } - - px = cx-Math::Mod(cx, 1.0f); - py = cy-Math::Mod(cy, 1.0f); // multiple of 1 - - if ( m_groundMark.bUsed && - px+dot >= min.x && py+dot >= min.y && - px-dot <= max.x && py-dot <= max.y ) - { - bSet = true; - } - - if ( bClear || bSet ) - { - // Load the song. - sprintf(texName, "shadow%.2d.tga", s); - surface = D3DTextr_GetSurface(texName); - if ( surface == 0 ) continue; - - ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(DDSURFACEDESC2); - if ( surface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != DD_OK ) continue; - - // Clears in blank whole piece. - if ( ddsd.ddpfPixelFormat.dwRGBBitCount == 16 ) - { - for ( y=0 ; y<(int)ddsd.dwHeight ; y++ ) - { - pbSurf = (WORD*)ddsd.lpSurface; - pbSurf += ddsd.lPitch*y/2; - memset(pbSurf, -1, ddsd.lPitch); // all blank - } - } - - // Draw the new shadows. - for ( i=0 ; i<D3DMAXGROUNDSPOT ; i++ ) - { - if ( m_groundSpot[i].bUsed == false || - m_groundSpot[i].radius == 0.0f ) continue; - - if ( m_groundSpot[i].min == 0.0f && - m_groundSpot[i].max == 0.0f ) - { - dot = (int)(m_groundSpot[i].radius/2.0f); - - tu = (m_groundSpot[i].pos.x+1600.0f)/3200.0f; - tv = (m_groundSpot[i].pos.z+1600.0f)/3200.0f; // 0..1 - - cx = (tu*254.0f*4.0f)-0.5f; - cy = (tv*254.0f*4.0f)-0.5f; - - if ( dot == 0 ) - { - cx += 0.5f; - cy += 0.5f; - } - - px = cx-Math::Mod(cx, 1.0f); - py = cy-Math::Mod(cy, 1.0f); // multiple of 1 - - if ( px+dot < min.x || py+dot < min.y || - px-dot > max.x || py-dot > max.y ) continue; - - for ( iy=-dot ; iy<=dot ; iy++ ) - { - for ( ix=-dot ; ix<=dot ; ix++ ) - { - ppx = px+ix; - ppy = py+iy; - - if ( ppx < min.x || ppy < min.y || - ppx >= max.x || ppy >= max.y ) continue; - - if ( dot == 0 ) - { - intensity = 0.0f; - } - else - { - intensity = Math::Point(ppx-cx, ppy-cy).Length()/dot; - //? intensity = powf(intensity, m_groundSpot[i].smooth); - } - - color.r = m_groundSpot[i].color.r+intensity; - color.g = m_groundSpot[i].color.g+intensity; - color.b = m_groundSpot[i].color.b+intensity; - - ppx -= min.x; // on the texture - ppy -= min.y; - AddDot(&ddsd, (int)ppx, (int)ppy, color); - } - } - } - else - { - for ( iy=0 ; iy<256 ; iy++ ) - { - for ( ix=0 ; ix<256 ; ix++ ) - { - pos.x = (256.0f*(s%4)+ix)*3200.0f/1024.0f - 1600.0f; - pos.z = (256.0f*(s/4)+iy)*3200.0f/1024.0f - 1600.0f; - pos.y = 0.0f; - level = m_terrain->RetFloorLevel(pos, true); - if ( level < m_groundSpot[i].min || - level > m_groundSpot[i].max ) continue; - - if ( level > (m_groundSpot[i].max+m_groundSpot[i].min)/2.0f ) - { - intensity = 1.0f-(m_groundSpot[i].max-level)/m_groundSpot[i].smooth; - } - else - { - intensity = 1.0f-(level-m_groundSpot[i].min)/m_groundSpot[i].smooth; - } - if ( intensity < 0.0f ) intensity = 0.0f; - - color.r = m_groundSpot[i].color.r+intensity; - color.g = m_groundSpot[i].color.g+intensity; - color.b = m_groundSpot[i].color.b+intensity; - - AddDot(&ddsd, ix, iy, color); - } - } - } - } - - if ( bSet ) - { - dot = (int)(m_groundMark.radius/2.0f); - - tu = (m_groundMark.pos.x+1600.0f)/3200.0f; - tv = (m_groundMark.pos.z+1600.0f)/3200.0f; // 0..1 - - cx = (tu*254.0f*4.0f)-0.5f; - cy = (tv*254.0f*4.0f)-0.5f; - - if ( dot == 0 ) - { - cx += 0.5f; - cy += 0.5f; - } - - px = cx-Math::Mod(cx, 1.0f); - py = cy-Math::Mod(cy, 1.0f); // multiple of 1 - - for ( iy=-dot ; iy<=dot ; iy++ ) - { - for ( ix=-dot ; ix<=dot ; ix++ ) - { - ppx = px+ix; - ppy = py+iy; - - if ( ppx < min.x || ppy < min.y || - ppx >= max.x || ppy >= max.y ) continue; - - ppx -= min.x; // on the texture - ppy -= min.y; - - intensity = 1.0f-Math::Point((float)ix, (float)iy).Length()/dot; - if ( intensity <= 0.0f ) continue; - intensity *= m_groundMark.intensity; - - j = (ix+dot) + (iy+dot)*m_groundMark.dx; - if ( m_groundMark.table[j] == 1 ) // green ? - { - color.r = 1.0f-intensity; - color.g = 1.0f; - color.b = 1.0f-intensity; - AddDot(&ddsd, (int)ppx, (int)ppy, color); - } - if ( m_groundMark.table[j] == 2 ) // red ? - { - color.r = 1.0f; - color.g = 1.0f-intensity; - color.b = 1.0f-intensity; - AddDot(&ddsd, (int)ppx, (int)ppy, color); - } - } - } - } - - surface->Unlock(NULL); - } - } - - for ( i=0 ; i<D3DMAXGROUNDSPOT ; i++ ) - { - if ( m_groundSpot[i].bUsed == false || - m_groundSpot[i].radius == 0.0f ) - { - m_groundSpot[i].drawRadius = 0.0f; - } - else - { - m_groundSpot[i].drawPos = m_groundSpot[i].pos; - m_groundSpot[i].drawRadius = m_groundSpot[i].radius; - } - } - - m_groundMark.drawPos = m_groundMark.pos; - m_groundMark.drawRadius = m_groundMark.radius; - m_groundMark.drawIntensity = m_groundMark.intensity; - - m_bFirstGroundSpot = false; -} - -// Draw all the shadows. - -void CD3DEngine::DrawShadow() -{ - D3DVERTEX2 vertex[4]; // 2 triangles - Math::Vector corner[4], n, pos; - D3DMATERIAL7 material; - Math::Matrix matrix; - Math::Point ts, ti, rot; - float startDeepView, endDeepView; - float intensity, lastIntensity, hFactor, radius, max, height; - float dp, h, d, D; - int i; - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, false); - - matrix.LoadIdentity(); - { - D3DMATRIX mat = MAT_TO_D3DMAT(matrix); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - - ZeroMemory( &material, sizeof(D3DMATERIAL7) ); - material.diffuse.r = 1.0f; - material.diffuse.g = 1.0f; - material.diffuse.b = 1.0f; // white - material.ambient.r = 0.5f; - material.ambient.g = 0.5f; - material.ambient.b = 0.5f; - SetMaterial(material); - -#if _POLISH - SetTexture("textp.tga"); -#else - SetTexture("text.tga"); -#endif - - dp = 0.5f/256.0f; - ts.y = 192.0f/256.0f; - ti.y = 224.0f/256.0f; - ts.y += dp; - ti.y -= dp; - - n = Math::Vector(0.0f, 1.0f, 0.0f); - - startDeepView = m_deepView[m_rankView]*m_fogStart[m_rankView]; - endDeepView = m_deepView[m_rankView]; - - lastIntensity = -1.0f; - for ( i=0 ; i<m_shadowTotal ; i++ ) - { - if ( !m_shadow[i].bUsed ) continue; - if ( m_shadow[i].bHide ) continue; - - pos = m_shadow[i].pos; // pos = center of the shadow on the ground - - if ( m_eyePt.y == pos.y ) continue; // camera at the same level? - - // h is the height above the ground to which the shadow - // will be drawn. - if ( m_eyePt.y > pos.y ) // camera on? - { - height = m_eyePt.y-pos.y; - h = m_shadow[i].radius; - max = height*0.5f; - if ( h > max ) h = max; - if ( h > 4.0f ) h = 4.0f; - - D = Math::Distance(m_eyePt, pos); - if ( D >= endDeepView ) continue; - d = D*h/height; - - pos.x += (m_eyePt.x-pos.x)*d/D; - pos.z += (m_eyePt.z-pos.z)*d/D; - pos.y += h; - } - else // camera underneath? - { - height = pos.y-m_eyePt.y; - h = m_shadow[i].radius; - max = height*0.1f; - if ( h > max ) h = max; - if ( h > 4.0f ) h = 4.0f; - - D = Math::Distance(m_eyePt, pos); - if ( D >= endDeepView ) continue; - d = D*h/height; - - pos.x += (m_eyePt.x-pos.x)*d/D; - pos.z += (m_eyePt.z-pos.z)*d/D; - pos.y -= h; - } - - // The hFactor decreases the intensity and size increases more - // the object is high relative to the ground. - hFactor = m_shadow[i].height/20.0f; - if ( hFactor < 0.0f ) hFactor = 0.0f; - if ( hFactor > 1.0f ) hFactor = 1.0f; - hFactor = powf(1.0f-hFactor, 2.0f); - if ( hFactor < 0.2f ) hFactor = 0.2f; - - radius = m_shadow[i].radius*1.5f; - radius *= 2.0f-hFactor; // greater if high - radius *= 1.0f-d/D; // smaller if close - - if ( m_shadow[i].type == D3DSHADOWNORM ) - { - corner[0].x = +radius; - corner[0].z = +radius; - corner[0].y = 0.0f; - - corner[1].x = -radius; - corner[1].z = +radius; - corner[1].y = 0.0f; - - corner[2].x = +radius; - corner[2].z = -radius; - corner[2].y = 0.0f; - - corner[3].x = -radius; - corner[3].z = -radius; - corner[3].y = 0.0f; - - ts.x = 64.0f/256.0f; - ti.x = 96.0f/256.0f; - } - else - { - rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(radius, radius)); - corner[0].x = rot.x; - corner[0].z = rot.y; - corner[0].y = 0.0f; - - rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(-radius, radius)); - corner[1].x = rot.x; - corner[1].z = rot.y; - corner[1].y = 0.0f; - - rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(radius, -radius)); - corner[2].x = rot.x; - corner[2].z = rot.y; - corner[2].y = 0.0f; - - rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(-radius, -radius)); - corner[3].x = rot.x; - corner[3].z = rot.y; - corner[3].y = 0.0f; - - if ( m_shadow[i].type == D3DSHADOWWORM ) - { - ts.x = 96.0f/256.0f; - ti.x = 128.0f/256.0f; - } - else - { - ts.x = 64.0f/256.0f; - ti.x = 96.0f/256.0f; - } - } - - corner[0] = Math::CrossProduct(corner[0], m_shadow[i].normal); - corner[1] = Math::CrossProduct(corner[1], m_shadow[i].normal); - corner[2] = Math::CrossProduct(corner[2], m_shadow[i].normal); - corner[3] = Math::CrossProduct(corner[3], m_shadow[i].normal); - - corner[0] += pos; - corner[1] += pos; - corner[2] += pos; - corner[3] += pos; - - ts.x += dp; - ti.x -= dp; - - vertex[0] = D3DVERTEX2(corner[1], n, ts.x, ts.y); - vertex[1] = D3DVERTEX2(corner[0], n, ti.x, ts.y); - vertex[2] = D3DVERTEX2(corner[3], n, ts.x, ti.y); - vertex[3] = D3DVERTEX2(corner[2], n, ti.x, ti.y); - - intensity = (0.5f+m_shadow[i].intensity*0.5f)*hFactor; - - // Decreases the intensity of the shade if you're in the area - // between the beginning and the end of the fog. - if ( D > startDeepView ) - { - intensity *= 1.0f-(D-startDeepView)/(endDeepView-startDeepView); - } - - // Decreases if the intensity is almost horizontal - // with shade (shade very platte). -//? if ( height < 4.0f ) intensity *= height/4.0f; - - if ( intensity == 0.0f ) continue; - - if ( lastIntensity != intensity ) // intensity changed? - { - lastIntensity = intensity; - SetState(D3DSTATETTw, RetColor(intensity)); - } - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - AddStatisticTriangle(2); - } - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, true); -} - - -// Called ounces per frame, the call is the entry point for 3d rendering. -// This function sets up render states, clears the -// viewport, and renders the scene. - -HRESULT CD3DEngine::Render() -{ - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DObjLevel6* p6; - D3DVERTEX2* pv; - int l1, l2, l3, l4, l5, objRank, tState; - CInterface* pInterface; - bool bTransparent; - D3DCOLOR color, tColor; - - if ( !m_bRender ) return S_OK; - - m_statisticTriangle = 0; - m_lastState = -1; - m_lastColor = 999; - m_lastTexture[0][0] = 0; - m_lastTexture[1][0] = 0; - ZeroMemory(&m_lastMaterial, sizeof(D3DMATERIAL7)); - - if ( m_bGroundSpot ) - { - RenderGroundSpot(); - } - - // Clear the viewport - if ( m_bSkyMode && m_cloud->RetLevel() != 0.0f ) // clouds? - { - color = m_backgroundCloudDown; - } - else - { - color = m_backgroundColorDown; - } - m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, - color, 1.0f, 0L ); - - m_light->LightUpdate(); - - // Begin the scene - if( FAILED( m_pD3DDevice->BeginScene() ) ) return S_OK; - - if ( m_bDrawWorld ) - { - DrawBackground(); // draws the background - if ( m_bPlanetMode ) DrawPlanet(); // draws the planets - if ( m_bSkyMode ) m_cloud->Draw(); // draws the clouds - - // Display the objects - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, true); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, F2DW(16)); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL); - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matProj); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &mat); - } - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, true); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, m_fogColor[m_rankView]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(m_deepView[m_rankView]*m_fogStart[m_rankView])); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(m_deepView[m_rankView])); - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matView); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat); - } - - if ( m_bWaterMode ) m_water->DrawBack(); // draws water - - if ( m_bShadow ) - { - // Draw the field. - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - SetTexture(p2->texName1, 0); - SetTexture(p2->texName2, 1); - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - if ( m_objectParam[objRank].type != TYPETERRAIN ) continue; - if ( !m_objectParam[objRank].bDrawWorld ) continue; - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_objectParam[objRank].transform); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - - if ( !IsVisible(objRank) ) continue; - m_light->LightUpdate(m_objectParam[objRank].type); - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( m_objectParam[objRank].distance < p4->min || - m_objectParam[objRank].distance >= p4->max ) continue; - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - SetMaterial(p6->material); - SetState(p6->state); - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed/3; - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed-2; - } - } - } - } - } - } - - DrawShadow(); // draws the shadows - } - - // Draw objects. - bTransparent = false; - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - SetTexture(p2->texName1, 0); - SetTexture(p2->texName2, 1); - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - if ( m_bShadow && m_objectParam[objRank].type == TYPETERRAIN ) continue; - if ( !m_objectParam[objRank].bDrawWorld ) continue; - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_objectParam[objRank].transform); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - - if ( !IsVisible(objRank) ) continue; - m_light->LightUpdate(m_objectParam[objRank].type); - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( m_objectParam[objRank].distance < p4->min || - m_objectParam[objRank].distance >= p4->max ) continue; - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - SetMaterial(p6->material); - if ( m_objectParam[objRank].transparency != 0.0f ) // transparent ? - { - bTransparent = true; - continue; - } - SetState(p6->state); - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed/3; - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed-2; - } - } - } - } - } - } - - if ( bTransparent ) - { - if ( m_bStateColor ) - { - tState = D3DSTATETTb|D3DSTATE2FACE; - tColor = 0x44444444; - } - else - { - tState = D3DSTATETTb; - tColor = 0x88888888; - } - - // Draw transparent objects. - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - SetTexture(p2->texName1, 0); - SetTexture(p2->texName2, 1); - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - if ( m_bShadow && m_objectParam[objRank].type == TYPETERRAIN ) continue; - if ( !m_objectParam[objRank].bDrawWorld ) continue; - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_objectParam[objRank].transform); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - - if ( !IsVisible(objRank) ) continue; - m_light->LightUpdate(m_objectParam[objRank].type); - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( m_objectParam[objRank].distance < p4->min || - m_objectParam[objRank].distance >= p4->max ) continue; - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - SetMaterial(p6->material); - if ( m_objectParam[objRank].transparency == 0.0f ) continue; - SetState(tState, tColor); - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed/3; - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed-2; - } - } - } - } - } - } - } - - m_light->LightUpdate(TYPETERRAIN); - if ( m_bWaterMode ) m_water->DrawSurf(); // draws water -//? m_cloud->Draw(); // draws the clouds - - m_particule->DrawParticule(SH_WORLD); // draws the particles of the 3D world - m_blitz->Draw(); // draws lightning - if ( m_bLensMode ) DrawFrontsize(); // draws the foreground - if ( !m_bOverFront ) DrawOverColor(); // draws the foreground color - } - - // Draw the user interface over the scene. - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matWorldInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - - pInterface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - if ( pInterface != 0 ) - { - pInterface->Draw(); // draws the entire interface - } - m_particule->DrawParticule(SH_INTERFACE); // draws the particles of the interface - - if ( m_bDrawFront ) - { - // Display the objects - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, true); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, F2DW(16)); -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL); - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matProj); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &mat); - } - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, m_ambiantColor[m_rankView]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, true); - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, m_fogColor[m_rankView]); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_LINEAR); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(m_deepView[m_rankView]*m_fogStart[m_rankView])); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(m_deepView[m_rankView])); - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matView); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat); - } - - p1 = m_objectPointer; - for ( l1=0 ; l1<p1->totalUsed ; l1++ ) - { - p2 = p1->table[l1]; - if ( p2 == 0 ) continue; - SetTexture(p2->texName1, 0); - SetTexture(p2->texName2, 1); - for ( l2=0 ; l2<p2->totalUsed ; l2++ ) - { - p3 = p2->table[l2]; - if ( p3 == 0 ) continue; - objRank = p3->objRank; - if ( !m_objectParam[objRank].bDrawFront ) continue; - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_objectParam[objRank].transform); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - - if ( !IsVisible(objRank) ) continue; - m_light->LightUpdate(m_objectParam[objRank].type); - for ( l3=0 ; l3<p3->totalUsed ; l3++ ) - { - p4 = p3->table[l3]; - if ( p4 == 0 ) continue; - if ( m_objectParam[objRank].distance < p4->min || - m_objectParam[objRank].distance >= p4->max ) continue; - for ( l4=0 ; l4<p4->totalUsed ; l4++ ) - { - p5 = p4->table[l4]; - if ( p5 == 0 ) continue; - for ( l5=0 ; l5<p5->totalUsed ; l5++ ) - { - p6 = p5->table[l5]; - if ( p6 == 0 ) continue; - SetMaterial(p6->material); - SetState(p6->state); - if ( p6->type == D3DTYPE6T ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed/3; - } - if ( p6->type == D3DTYPE6S ) - { - pv = &p6->vertex[0]; - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, - D3DFVF_VERTEX2, - pv, p6->totalUsed, - NULL); - m_statisticTriangle += p6->totalUsed-2; - } - } - } - } - } - } - - m_particule->DrawParticule(SH_FRONT); // draws the particles of the 3D world - - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matWorldInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - } - - if ( m_bOverFront ) DrawOverColor(); // draws the foreground color - - if ( m_mouseType != D3DMOUSEHIDE ) - { - DrawMouse(); - } - - // End the scene. - m_pD3DDevice->EndScene(); - - DrawHilite(); - return S_OK; -} - - -// Draw the gradient background. - -void CD3DEngine::DrawBackground() -{ - if ( m_bSkyMode && m_cloud->RetLevel() != 0.0f ) // clouds ? - { - if ( m_backgroundCloudUp != m_backgroundCloudDown ) // degraded? - { - DrawBackgroundGradient(m_backgroundCloudUp, m_backgroundCloudDown); - } - } - else - { - if ( m_backgroundColorUp != m_backgroundColorDown ) // degraded? - { - DrawBackgroundGradient(m_backgroundColorUp, m_backgroundColorDown); - } - } - - if ( m_bBackForce || (m_bSkyMode && m_backgroundName[0] != 0) ) - { - DrawBackgroundImage(); // image - } -} - -// Draw the gradient background. - -void CD3DEngine::DrawBackgroundGradient(D3DCOLOR up, D3DCOLOR down) -{ - D3DLVERTEX vertex[4]; // 2 triangles - D3DCOLOR color[3]; - Math::Point p1, p2; - - p1.x = 0.0f; - p1.y = 0.5f; - p2.x = 1.0f; - p2.y = 1.0f; - - color[0] = up; - color[1] = down; - color[2] = 0x00000000; - -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, false ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - - SetTexture("xxx.tga"); // no texture - SetState(D3DSTATENORMAL); - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matWorldInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - - vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); - vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); - vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); - vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); - AddStatisticTriangle(2); -} - -// Draws a portion of the image background. - -void CD3DEngine::DrawBackgroundImageQuarter(Math::Point p1, Math::Point p2, char *name) -{ - D3DVERTEX2 vertex[4]; // 2 triangles - Math::Vector n; - float u1, u2, v1, v2, h, a; - - n = Math::Vector(0.0f, 0.0f, -1.0f); // normal - - if ( m_bBackgroundFull ) - { - u1 = 0.0f; - v1 = 0.0f; - u2 = 1.0f; - v2 = 1.0f; - - if ( m_bBackgroundQuarter ) - { - u1 += 0.5f/512.0f; - v1 += 0.5f/384.0f; - u2 -= 0.5f/512.0f; - v2 -= 0.5f/384.0f; - } - } - else - { - h = 0.5f; // visible area vertically (1=all) - a = m_eyeDirV-Math::PI*0.15f; - if ( a > Math::PI ) a -= Math::PI*2.0f; // a = -Math::PI..Math::PI - if ( a > Math::PI/4.0f ) a = Math::PI/4.0f; - if ( a < -Math::PI/4.0f ) a = -Math::PI/4.0f; - - u1 = -m_eyeDirH/Math::PI; - u2 = u1+1.0f/Math::PI; -//? u1 = -m_eyeDirH/(Math::PI*2.0f); -//? u2 = u1+1.0f/(Math::PI*2.0f); - - v1 = (1.0f-h)*(0.5f+a/(2.0f*Math::PI/4.0f))+0.1f; - v2 = v1+h; - } - -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, false ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - - SetTexture(name); - SetState(D3DSTATEWRAP); - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matWorldInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - - vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(Math::Vector(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(Math::Vector(p2.x, p2.y, 0.0f), n, u2,v1); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - AddStatisticTriangle(2); -} - -// Draws the image background. - -void CD3DEngine::DrawBackgroundImage() -{ - Math::Point p1, p2; - char name[50]; - - if ( m_bBackgroundQuarter ) - { - p1.x = 0.0f; - p1.y = 0.5f; - p2.x = 0.5f; - p2.y = 1.0f; - QuarterName(name, m_backgroundName, 0); - DrawBackgroundImageQuarter(p1, p2, name); - - p1.x = 0.5f; - p1.y = 0.5f; - p2.x = 1.0f; - p2.y = 1.0f; - QuarterName(name, m_backgroundName, 1); - DrawBackgroundImageQuarter(p1, p2, name); - - p1.x = 0.0f; - p1.y = 0.0f; - p2.x = 0.5f; - p2.y = 0.5f; - QuarterName(name, m_backgroundName, 2); - DrawBackgroundImageQuarter(p1, p2, name); - - p1.x = 0.5f; - p1.y = 0.0f; - p2.x = 1.0f; - p2.y = 0.5f; - QuarterName(name, m_backgroundName, 3); - DrawBackgroundImageQuarter(p1, p2, name); - } - else - { - p1.x = 0.0f; - p1.y = 0.0f; - p2.x = 1.0f; - p2.y = 1.0f; - DrawBackgroundImageQuarter(p1, p2, m_backgroundName); - } -} - -// Draws all the planets. - -void CD3DEngine::DrawPlanet() -{ - if ( !m_planet->PlanetExist() ) return; - -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, false ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matWorldInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - - m_planet->Draw(); // draws the planets -} - -// Draws the image foreground. - -void CD3DEngine::DrawFrontsize() -{ - D3DVERTEX2 vertex[4]; // 2 triangles - Math::Vector n; - Math::Point p1, p2; - float u1, u2, v1, v2; - - if ( m_frontsizeName[0] == 0 ) return; - - n = Math::Vector(0.0f, 0.0f, -1.0f); // normal - - p1.x = 0.0f; - p1.y = 0.0f; - p2.x = 1.0f; - p2.y = 1.0f; - - u1 = -m_eyeDirH/(Math::PI*0.6f)+Math::PI*0.5f; - u2 = u1+0.50f; - - v1 = 0.2f; - v2 = 1.0f; - -#if 0 - char s[100]; - sprintf(s, "h=%.2f v=%.2f u=%.2f;%.2f v=%.2f;%.2f", m_eyeDirH, m_eyeDirV, u1, u2, v1, v2); - SetInfoText(3, s); -#endif - - vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(Math::Vector(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(Math::Vector(p2.x, p2.y, 0.0f), n, u2,v1); - -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, false ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - - SetTexture(m_frontsizeName); - SetState(D3DSTATECLAMP|D3DSTATETTb); - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matWorldInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - AddStatisticTriangle(2); -} - -// Draws the foreground color. - -void CD3DEngine::DrawOverColor() -{ - D3DLVERTEX vertex[4]; // 2 triangles - D3DCOLOR color[3]; - Math::Point p1, p2; - - if ( !m_bStateColor ) return; - if ( (m_overColor == 0x00000000 && m_overMode == D3DSTATETCb) || - (m_overColor == 0xffffffff && m_overMode == D3DSTATETCw) ) return; - - p1.x = 0.0f; - p1.y = 0.0f; - p2.x = 1.0f; - p2.y = 1.0f; - - color[0] = m_overColor; - color[1] = m_overColor; - color[2] = 0x00000000; - -//? m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, false ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENT, 0xffffffff); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_LIGHTING, false ); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - - SetTexture("xxx.tga"); // no texture - SetState(m_overMode); - - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matViewInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matProjInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &mat); - } - { - D3DMATRIX mat = MAT_TO_D3DMAT(m_matWorldInterface); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); - } - - vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); - vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); - vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color[1],color[2], 0.0f,0.0f); - vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color[0],color[2], 0.0f,0.0f); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL); - AddStatisticTriangle(2); -} - - -// Lists the ranks of objects and subobjects selected. - -void CD3DEngine::SetHiliteRank(int *rankList) -{ - int i; - - i = 0; - while ( *rankList != -1 ) - { - m_hiliteRank[i++] = *rankList++; - } - m_hiliteRank[i] = -1; // terminator -} - -// Give the box in the 2D screen of any object. - -bool CD3DEngine::GetBBox2D(int objRank, Math::Point &min, Math::Point &max) -{ - Math::Vector p, pp; - int i; - - min.x = 1000000.0f; - min.y = 1000000.0f; - max.x = -1000000.0f; - max.y = -1000000.0f; - - for ( i=0 ; i<8 ; i++ ) - { - if ( i & (1<<0) ) p.x = m_objectParam[objRank].bboxMin.x; - else p.x = m_objectParam[objRank].bboxMax.x; - if ( i & (1<<1) ) p.y = m_objectParam[objRank].bboxMin.y; - else p.y = m_objectParam[objRank].bboxMax.y; - if ( i & (1<<2) ) p.z = m_objectParam[objRank].bboxMin.z; - else p.z = m_objectParam[objRank].bboxMax.z; - if ( TransformPoint(pp, objRank, p) ) - { - if ( pp.x < min.x ) min.x = pp.x; - if ( pp.x > max.x ) max.x = pp.x; - if ( pp.y < min.y ) min.y = pp.y; - if ( pp.y > max.y ) max.y = pp.y; - } - } - - if ( min.x == 1000000.0f || - min.y == 1000000.0f || - max.x == -1000000.0f || - max.y == -1000000.0f ) return false; - - return true; -} - -// Determines the rectangle of the object highlighted, which will be designed by CD3DApplication. - -void CD3DEngine::DrawHilite() -{ - Math::Point min, max, omin, omax; - int i; - - min.x = 1000000.0f; - min.y = 1000000.0f; - max.x = -1000000.0f; - max.y = -1000000.0f; - - i = 0; - while ( m_hiliteRank[i] != -1 ) - { - if ( GetBBox2D(m_hiliteRank[i++], omin, omax) ) - { - min.x = Math::Min(min.x, omin.x); - min.y = Math::Min(min.y, omin.y); - max.x = Math::Max(max.x, omax.x); - max.y = Math::Max(max.y, omax.y); - } - } - - if ( min.x == 1000000.0f || - min.y == 1000000.0f || - max.x == -1000000.0f || - max.y == -1000000.0f ) - { - m_bHilite = false; // not highlighted - } - else - { - m_hiliteP1 = min; - m_hiliteP2 = max; - m_bHilite = true; - } -} - -// Give the rectangle highlighted by drawing CD3DApplication. - -bool CD3DEngine::GetHilite(Math::Point &p1, Math::Point &p2) -{ - p1 = m_hiliteP1; - p2 = m_hiliteP2; - return m_bHilite; -} - - -// Triangles adds qq records for statistics. - -void CD3DEngine::AddStatisticTriangle(int nb) -{ - m_statisticTriangle += nb; -} - -// Returns the number of triangles rendered. - -int CD3DEngine::RetStatisticTriangle() -{ - return m_statisticTriangle; -} - -bool CD3DEngine::GetSpriteCoord(int &x, int &y) -{ - D3DVIEWPORT7 vp; - Math::Vector v, vv; - - return false; - //? - vv = Math::Vector(0.0f, 0.0f, 0.0f); - if ( !TransformPoint(v, 20*20+1, vv) ) return false; - - m_pD3DDevice->GetViewport(&vp); - v.x *= vp.dwWidth/2; - v.y *= vp.dwHeight/2; - v.x = v.x+vp.dwWidth/2; - v.y = vp.dwHeight-(v.y+vp.dwHeight/2); - - x = (int)v.x; - y = (int)v.y; - return true; -} - - -// Tests whether to exclude a point. - -bool IsExcludeColor(Math::Point *pExclu, int x, int y) -{ - int i; - - i = 0; - while ( pExclu[i+0].x != 0.0f || pExclu[i+0].y != 0.0f || - pExclu[i+1].y != 0.0f || pExclu[i+1].y != 0.0f ) - { - if ( x >= (int)(pExclu[i+0].x*256.0f) && - x < (int)(pExclu[i+1].x*256.0f) && - y >= (int)(pExclu[i+0].y*256.0f) && - y < (int)(pExclu[i+1].y*256.0f) ) return true; // exclude - - i += 2; - } - - return false; // point to include -} - -// Change the color of a texture. - -bool CD3DEngine::ChangeColor(char *name, - D3DCOLORVALUE colorRef1, D3DCOLORVALUE colorNew1, - D3DCOLORVALUE colorRef2, D3DCOLORVALUE colorNew2, - float tolerance1, float tolerance2, - Math::Point ts, Math::Point ti, - Math::Point *pExclu, float shift, bool bHSV) -{ - LPDIRECTDRAWSURFACE7 surface; - DDSURFACEDESC2 ddsd; - D3DCOLORVALUE color; - ColorHSV cr1, cn1, cr2, cn2, c; - int dx, dy, x, y, sx, sy, ex, ey; - - D3DTextr_Invalidate(name); - LoadTexture(name); // reloads the initial texture - - if ( colorRef1.r == colorNew1.r && - colorRef1.g == colorNew1.g && - colorRef1.b == colorNew1.b && - colorRef2.r == colorNew2.r && - colorRef2.g == colorNew2.g && - colorRef2.b == colorNew2.b ) return true; - - surface = D3DTextr_GetSurface(name); - if ( surface == 0 ) return false; - - ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2)); - ddsd.dwSize = sizeof(DDSURFACEDESC2); - if ( surface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != DD_OK ) return false; - - dx = ddsd.dwWidth; - dy = ddsd.dwHeight; - - sx = (int)(ts.x*dx); - sy = (int)(ts.y*dy); - ex = (int)(ti.x*dx); - ey = (int)(ti.y*dy); - - RGB2HSV(colorRef1, cr1); - RGB2HSV(colorNew1, cn1); - RGB2HSV(colorRef2, cr2); - RGB2HSV(colorNew2, cn2); - - for ( y=sy ; y<ey ; y++ ) - { - for ( x=sx ; x<ex ; x++ ) - { - if ( pExclu != 0 && IsExcludeColor(pExclu, x,y) ) continue; - - color = GetDot(&ddsd, x, y); - - if ( bHSV ) - { - RGB2HSV(color, c); - if ( c.s > 0.01f && fabs(c.h-cr1.h) < tolerance1 ) - { - c.h += cn1.h-cr1.h; - c.s += cn1.s-cr1.s; - c.v += cn1.v-cr1.v; - if ( c.h < 0.0f ) c.h -= 1.0f; - if ( c.h > 1.0f ) c.h += 1.0f; - HSV2RGB(c, color); - color.r += shift; - color.g += shift; - color.b += shift; - ::SetDot(&ddsd, x, y, color); - } - else - if ( tolerance2 != -1.0f && - c.s > 0.01f && fabs(c.h-cr2.h) < tolerance2 ) - { - c.h += cn2.h-cr2.h; - c.s += cn2.s-cr2.s; - c.v += cn2.v-cr2.v; - if ( c.h < 0.0f ) c.h -= 1.0f; - if ( c.h > 1.0f ) c.h += 1.0f; - HSV2RGB(c, color); - color.r += shift; - color.g += shift; - color.b += shift; - ::SetDot(&ddsd, x, y, color); - } - } - else - { - if ( fabs(color.r-colorRef1.r)+ - fabs(color.g-colorRef1.g)+ - fabs(color.b-colorRef1.b) < tolerance1*3.0f ) - { - color.r = colorNew1.r+color.r-colorRef1.r+shift; - color.g = colorNew1.g+color.g-colorRef1.g+shift; - color.b = colorNew1.b+color.b-colorRef1.b+shift; - ::SetDot(&ddsd, x, y, color); - } - else - if ( tolerance2 != -1 && - fabs(color.r-colorRef2.r)+ - fabs(color.g-colorRef2.g)+ - fabs(color.b-colorRef2.b) < tolerance2*3.0f ) - { - color.r = colorNew2.r+color.r-colorRef2.r+shift; - color.g = colorNew2.g+color.g-colorRef2.g+shift; - color.b = colorNew2.b+color.b-colorRef2.b+shift; - ::SetDot(&ddsd, x, y, color); - } - } - } - } - - surface->Unlock(NULL); - return true; -} - - -// Open an image to work directly in it. - -bool CD3DEngine::OpenImage(char *name) -{ -//? D3DTextr_Invalidate(name); -//? LoadTexture(name); - - m_imageSurface = D3DTextr_GetSurface(name); - if ( m_imageSurface == 0 ) return false; - - ZeroMemory(&m_imageDDSD, sizeof(DDSURFACEDESC2)); - m_imageDDSD.dwSize = sizeof(DDSURFACEDESC2); - if ( m_imageSurface->Lock(NULL, &m_imageDDSD, DDLOCK_WAIT, NULL) != DD_OK ) - { - return false; - } - - if ( m_imageDDSD.ddpfPixelFormat.dwRGBBitCount != 16 ) - { - m_imageSurface->Unlock(NULL); - return false; - } - - m_imageDX = m_imageDDSD.dwWidth; - m_imageDY = m_imageDDSD.dwHeight; - - return true; -} - -// Copy the working image. - -bool CD3DEngine::CopyImage() -{ - WORD* pbSurf; - int y; - - if ( m_imageCopy == 0 ) - { - m_imageCopy = (WORD*)malloc(m_imageDX*m_imageDY*sizeof(WORD)); - } - - for ( y=0 ; y<m_imageDY ; y++ ) - { - pbSurf = (WORD*)m_imageDDSD.lpSurface; - pbSurf += m_imageDDSD.lPitch*y/2; - memcpy(m_imageCopy+y*m_imageDX, pbSurf, m_imageDX*sizeof(WORD)); - } - return true; -} - -// Restores the image work. - -bool CD3DEngine::LoadImage() -{ - WORD* pbSurf; - int y; - - if ( m_imageCopy == 0 ) return false; - - for ( y=0 ; y<m_imageDY ; y++ ) - { - pbSurf = (WORD*)m_imageDDSD.lpSurface; - pbSurf += m_imageDDSD.lPitch*y/2; - memcpy(pbSurf, m_imageCopy+y*m_imageDX, m_imageDX*sizeof(WORD)); - } - return true; -} - -// Scroll the copy of the working image. - -bool CD3DEngine::ScrollImage(int dx, int dy) -{ - int x, y; - - if ( dx > 0 ) - { - for ( y=0 ; y<m_imageDY ; y++ ) - { - for ( x=0 ; x<m_imageDX-dx ; x++ ) - { - m_imageCopy[x+y*m_imageDX] = m_imageCopy[x+dx+y*m_imageDX]; - } - } - } - - if ( dx < 0 ) - { - for ( y=0 ; y<m_imageDY ; y++ ) - { - for ( x=m_imageDX-1 ; x>=-dx ; x-- ) - { - m_imageCopy[x+y*m_imageDX] = m_imageCopy[x+dx+y*m_imageDX]; - } - } - } - - if ( dy > 0 ) - { - for ( y=0 ; y<m_imageDY-dy ; y++ ) - { - memcpy(m_imageCopy+y*m_imageDX, m_imageCopy+(y+dy)*m_imageDX, m_imageDX*sizeof(WORD)); - } - } - - if ( dy < 0 ) - { - for ( y=m_imageDY-1 ; y>=-dy ; y-- ) - { - memcpy(m_imageCopy+y*m_imageDX, m_imageCopy+(y+dy)*m_imageDX, m_imageDX*sizeof(WORD)); - } - } - - return true; -} - -// Draws a point in the image work. - -bool CD3DEngine::SetDot(int x, int y, D3DCOLORVALUE color) -{ - WORD* pbSurf; - WORD r,g,b, w; - - if ( x < 0 || x >= m_imageDX || - y < 0 || y >= m_imageDY ) return false; - -#if 1 - if ( color.r < 0.0f ) color.r = 0.0f; - if ( color.r > 1.0f ) color.r = 1.0f; - if ( color.g < 0.0f ) color.g = 0.0f; - if ( color.g > 1.0f ) color.g = 1.0f; - if ( color.b < 0.0f ) color.b = 0.0f; - if ( color.b > 1.0f ) color.b = 1.0f; - - r = (int)(color.r*32.0f); - g = (int)(color.g*32.0f); - b = (int)(color.b*32.0f); - - if ( r >= 32 ) r = 31; // 5 bits - if ( g >= 32 ) g = 31; // 5 bits - if ( b >= 32 ) b = 31; // 5 bits -#else - r = (int)(color.r*31.0f); - g = (int)(color.g*31.0f); - b = (int)(color.b*31.0f); -#endif - - if ( m_imageDDSD.ddpfPixelFormat.dwRBitMask == 0xf800 ) // 565 ? - { - w = (r<<11)|(g<<6)|b; - } - else if ( m_imageDDSD.ddpfPixelFormat.dwRBitMask == 0x7c00 ) // 555 ? - { - w = (r<<10)|(g<<5)|b; - } - else - { - w = -1; // blank - } - - pbSurf = (WORD*)m_imageDDSD.lpSurface; - pbSurf += m_imageDDSD.lPitch*y/2; - pbSurf += x; - - *pbSurf = w; - return true; -} - -// Closes the working image. - -bool CD3DEngine::CloseImage() -{ - m_imageSurface->Unlock(NULL); - return true; -} - - -// Writes a .BMP screenshot. - -bool CD3DEngine::WriteScreenShot(char *filename, int width, int height) -{ - return m_app->WriteScreenShot(filename, width, height); -} - -// Initializes an hDC on the rendering surface. - -bool CD3DEngine::GetRenderDC(HDC &hDC) -{ - return m_app->GetRenderDC(hDC); -} - -// Frees the hDC of the rendering surface. - -bool CD3DEngine::ReleaseRenderDC(HDC &hDC) -{ - return m_app->ReleaseRenderDC(hDC); -} - -PBITMAPINFO CD3DEngine::CreateBitmapInfoStruct(HBITMAP hBmp) -{ - return m_app->CreateBitmapInfoStruct(hBmp); -} - -bool CD3DEngine::CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC) -{ - return m_app->CreateBMPFile(pszFile, pbi, hBMP, hDC); -} - -// Returns the pointer to the class cText. - -CText* CD3DEngine::RetText() -{ - return m_text; -} - - -// Managing of information text displayed in the window. - -void CD3DEngine::SetInfoText(int line, char* text) -{ - strcpy(m_infoText[line], text); -} - -char* CD3DEngine::RetInfoText(int line) -{ - return m_infoText[line]; -} - - - -// Specifies the length of the camera. -// 0.75 = normal -// 1.50 = wide-angle - -void CD3DEngine::SetFocus(float focus) -{ - D3DVIEWPORT7 vp; - float fAspect; - - m_focus = focus; - - if ( m_pD3DDevice != 0 ) - { - m_pD3DDevice->GetViewport(&vp); - m_dim.x = vp.dwWidth; - m_dim.y = vp.dwHeight; - } - - fAspect = ((float)m_dim.y) / m_dim.x; -//? Math::LoadProjectionMatrix(m_matProj, m_focus, fAspect, 0.5f, m_deepView[m_rankView]); - Math::LoadProjectionMatrix(m_matProj, m_focus, fAspect, 0.5f, m_deepView[0]); -} - -float CD3DEngine::RetFocus() -{ - return m_focus; -} - -// - -void CD3DEngine::UpdateMatProj() -{ - D3DMATRIX mat = MAT_TO_D3DMAT(m_matProj); - m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &mat); -} - - - -// Ignores key presses. - -void CD3DEngine::FlushPressKey() -{ - m_app->FlushPressKey(); -} - -// Resets the default keys. - -void CD3DEngine::ResetKey() -{ - m_app->ResetKey(); -} - -// Modifies a button. - -void CD3DEngine::SetKey(int keyRank, int option, int key) -{ - m_app->SetKey(keyRank, option, key); -} - -// Gives a key. - -int CD3DEngine::RetKey(int keyRank, int option) -{ - return m_app->RetKey(keyRank, option); -} - - -// Use the joystick or keyboard. - -void CD3DEngine::SetJoystick(bool bEnable) -{ - m_app->SetJoystick(bEnable); -} - -bool CD3DEngine::RetJoystick() -{ - return m_app->RetJoystick(); -} - - -void CD3DEngine::SetDebugMode(bool bMode) -{ - m_app->SetDebugMode(bMode); -} - -bool CD3DEngine::RetDebugMode() -{ - return m_app->RetDebugMode(); -} - -bool CD3DEngine::RetSetupMode() -{ - return m_app->RetSetupMode(); -} - - -// Indicates whether a point is visible. - -bool CD3DEngine::IsVisiblePoint(const Math::Vector &pos) -{ - return ( Math::Distance(m_eyePt, pos) <= m_deepView[0] ); -} - - -// Initialize scene objects. - -HRESULT CD3DEngine::InitDeviceObjects() -{ - // Set miscellaneous render states. - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, true); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD); - m_pD3DDevice->SetRenderState(D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID); - - // Set up the textures. - D3DTextr_RestoreAllTextures(m_pD3DDevice); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR); - m_pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTFN_LINEAR); - m_pD3DDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTFG_LINEAR); - - SetFocus(m_focus); - - // Definitions of the matrices for the interface. - m_matWorldInterface.LoadIdentity(); - - m_matViewInterface.LoadIdentity(); - m_matViewInterface.Set(1, 4, -0.5f); - m_matViewInterface.Set(2, 4, -0.5f); - m_matViewInterface.Set(3, 4, 1.0f); - - m_matProjInterface.LoadIdentity(); - m_matProjInterface.Set(1, 1, 2.0f); - m_matProjInterface.Set(2, 2, 2.0f); - m_matProjInterface.Set(4, 3, 1.0f); - m_matProjInterface.Set(3, 4, -1.0f); - m_matProjInterface.Set(4, 4, 0.0f); - - return S_OK; -} - - -// Restore all surfaces. - -HRESULT CD3DEngine::RestoreSurfaces() -{ - return S_OK; -} - - -// Called when the app is exitting, or the device is being changed, -// this function deletes any device dependant objects. - -HRESULT CD3DEngine::DeleteDeviceObjects() -{ - D3DTextr_InvalidateAllTextures(); - return S_OK; -} - - -// Called before the app exits, this function gives the app the chance -// to cleanup after itself. - -HRESULT CD3DEngine::FinalCleanup() -{ - return S_OK; -} - - -// Overrrides the main WndProc, so the sample can do custom message -// handling (e.g. processing mouse, keyboard, or menu commands). - -LRESULT CD3DEngine::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) -{ -#if 0 - if ( uMsg == WM_KEYDOWN ) // Alt+key ? - { - if ( wParam == 'Q' ) - { - debug_blend1 ++; - if ( debug_blend1 > 13 ) debug_blend1 = 0; - } - if ( wParam == 'W' ) - { - debug_blend2 ++; - if ( debug_blend2 > 13 ) debug_blend2 = 0; - } - if ( wParam == 'E' ) - { - debug_blend3 ++; - if ( debug_blend3 > 13 ) debug_blend3 = 0; - } - if ( wParam == 'R' ) - { - debug_blend4 ++; - if ( debug_blend4 > 13 ) debug_blend4 = 0; - } - char s[100]; - sprintf(s, "src=%d, dest=%d, src=%d, dest=%d", debug_blend1, debug_blend2, debug_blend3, debug_blend4); - SetInfoText(4, s); - } -#endif - -#if 1 - if ( uMsg == WM_SYSKEYDOWN ) // Alt+key ? - { - if ( wParam == VK_F7 ) // Alt+F7 ? - { - s_resol = 0; - } - if ( wParam == VK_F8 ) // Alt+F8 ? - { - s_resol = 1; - } - if ( wParam == VK_F9 ) // Alt+F9 ? - { - s_resol = 2; - } - if ( wParam == VK_F10 ) // Alt+F10 ? - { - s_resol = 3; - } - } -#endif - - return 0; -} - - -// Mouse control. - -void CD3DEngine::MoveMousePos(Math::Point pos) -{ - m_mousePos = pos; - m_app->SetMousePos(pos); -} - -void CD3DEngine::SetMousePos(Math::Point pos) -{ - m_mousePos = pos; -} - -Math::Point CD3DEngine::RetMousePos() -{ - return m_mousePos; -} - -void CD3DEngine::SetMouseType(D3DMouse type) -{ - m_mouseType = type; -} - -D3DMouse CD3DEngine::RetMouseType() -{ - return m_mouseType; -} - -void CD3DEngine::SetMouseHide(bool bHide) -{ - if ( m_bMouseHide == bHide ) return; - - if ( bHide ) // hide the mouse? - { - m_bNiceMouse = m_app->RetNiceMouse(); - if ( !m_bNiceMouse ) - { - m_app->SetNiceMouse(true); - } - m_bMouseHide = true; - } - else // shows the mouse? - { - if ( !m_bNiceMouse ) - { - m_app->SetNiceMouse(false); - } - m_bMouseHide = false; - } -} - -bool CD3DEngine::RetMouseHide() -{ - return m_bMouseHide; -} - -void CD3DEngine::SetNiceMouse(bool bNice) -{ - m_app->SetNiceMouse(bNice); -} - -bool CD3DEngine::RetNiceMouse() -{ - return m_app->RetNiceMouse(); -} - -bool CD3DEngine::RetNiceMouseCap() -{ - return m_app->RetNiceMouseCap(); -} - -// Draws the sprite of the mouse. - -void CD3DEngine::DrawMouse() -{ - D3DMATERIAL7 material; - Math::Point pos, ppos, dim; - int i; - - struct Mouse - { - D3DMouse type; - int icon1, icon2, iconShadow; - int mode1, mode2; - float hotx, hoty; - }; - - static Mouse table[] = - { - { D3DMOUSENORM, 0, 1,32, D3DSTATETTw, D3DSTATETTb, 1.0f, 1.0f}, - { D3DMOUSEWAIT, 2, 3,33, D3DSTATETTw, D3DSTATETTb, 8.0f, 12.0f}, - { D3DMOUSEHAND, 4, 5,34, D3DSTATETTw, D3DSTATETTb, 7.0f, 2.0f}, - { D3DMOUSENO, 6, 7,35, D3DSTATETTw, D3DSTATETTb, 10.0f, 10.0f}, - { D3DMOUSEEDIT, 8, 9,-1, D3DSTATETTb, D3DSTATETTw, 6.0f, 10.0f}, - { D3DMOUSECROSS, 10,11,-1, D3DSTATETTb, D3DSTATETTw, 10.0f, 10.0f}, - { D3DMOUSEMOVEV, 12,13,-1, D3DSTATETTb, D3DSTATETTw, 5.0f, 11.0f}, - { D3DMOUSEMOVEH, 14,15,-1, D3DSTATETTb, D3DSTATETTw, 11.0f, 5.0f}, - { D3DMOUSEMOVED, 16,17,-1, D3DSTATETTb, D3DSTATETTw, 9.0f, 9.0f}, - { D3DMOUSEMOVEI, 18,19,-1, D3DSTATETTb, D3DSTATETTw, 9.0f, 9.0f}, - { D3DMOUSEMOVE, 20,21,-1, D3DSTATETTb, D3DSTATETTw, 11.0f, 11.0f}, - { D3DMOUSETARGET, 22,23,-1, D3DSTATETTb, D3DSTATETTw, 15.0f, 15.0f}, - { D3DMOUSESCROLLL, 24,25,43, D3DSTATETTb, D3DSTATETTw, 2.0f, 9.0f}, - { D3DMOUSESCROLLR, 26,27,44, D3DSTATETTb, D3DSTATETTw, 17.0f, 9.0f}, - { D3DMOUSESCROLLU, 28,29,45, D3DSTATETTb, D3DSTATETTw, 9.0f, 2.0f}, - { D3DMOUSESCROLLD, 30,31,46, D3DSTATETTb, D3DSTATETTw, 9.0f, 17.0f}, - { D3DMOUSEHIDE }, - }; - - if ( m_bMouseHide ) return; - if ( !m_app->RetNiceMouse() ) return; // mouse windows? - - ZeroMemory( &material, sizeof(D3DMATERIAL7) ); - material.diffuse.r = 1.0f; - material.diffuse.g = 1.0f; - material.diffuse.b = 1.0f; - material.ambient.r = 0.5f; - material.ambient.g = 0.5f; - material.ambient.b = 0.5f; - SetMaterial(material); - - SetTexture("mouse.tga"); - - i = 0; - while ( table[i].type != D3DMOUSEHIDE ) - { - if ( m_mouseType == table[i].type ) - { - dim.x = 0.05f*0.75f; - dim.y = 0.05f; - - pos.x = m_mousePos.x - (table[i].hotx*dim.x)/32.0f; - pos.y = m_mousePos.y - ((32.0f-table[i].hoty)*dim.y)/32.0f; - - ppos.x = pos.x+(4.0f/640.0f); - ppos.y = pos.y-(3.0f/480.0f); - SetState(D3DSTATETTw); - DrawSprite(ppos, dim, table[i].iconShadow); - - SetState(table[i].mode1); - DrawSprite(pos, dim, table[i].icon1); - - SetState(table[i].mode2); - DrawSprite(pos, dim, table[i].icon2); - break; - } - i ++; - } -} - -// Draws the sprite of the mouse. - -void CD3DEngine::DrawSprite(Math::Point pos, Math::Point dim, int icon) -{ - D3DVERTEX2 vertex[4]; // 2 triangles - Math::Point p1, p2; - Math::Vector n; - float u1, u2, v1, v2, dp; - - if ( icon == -1 ) return; - - p1.x = pos.x; - p1.y = pos.y; - p2.x = pos.x + dim.x; - p2.y = pos.y + dim.y; - - u1 = (32.0f/256.0f)*(icon%8); - v1 = (32.0f/256.0f)*(icon/8); // u-v texture - u2 = (32.0f/256.0f)+u1; - v2 = (32.0f/256.0f)+v1; - - dp = 0.5f/256.0f; - u1 += dp; - v1 += dp; - u2 -= dp; - v2 -= dp; - - n = Math::Vector(0.0f, 0.0f, -1.0f); // normal - - vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p1.y, 0.0f), n, u1,v2); - vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p2.y, 0.0f), n, u1,v1); - vertex[2] = D3DVERTEX2(Math::Vector(p2.x, p1.y, 0.0f), n, u2,v2); - vertex[3] = D3DVERTEX2(Math::Vector(p2.x, p2.y, 0.0f), n, u2,v1); - - m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); - AddStatisticTriangle(2); -} - |