Rendering functions, documentation
- rewrote the render functions for CEngine, CCloud and CWater - added documentationdev-ui
parent
146ad47e4a
commit
712154bc4f
|
@ -20,6 +20,7 @@
|
|||
#include "graphics/engine/cloud.h"
|
||||
|
||||
#include "common/iman.h"
|
||||
#include "graphics/core/device.h"
|
||||
#include "graphics/engine/engine.h"
|
||||
#include "graphics/engine/terrain.h"
|
||||
#include "math/geometry.h"
|
||||
|
@ -94,112 +95,96 @@ void Gfx::CCloud::AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep,
|
|||
|
||||
void Gfx::CCloud::Draw()
|
||||
{
|
||||
/* TODO!
|
||||
LPDIRECT3DDEVICE7 device;
|
||||
D3DVERTEX2* vertex;
|
||||
Math::Matrix* matView;
|
||||
D3DMATERIAL7 material;
|
||||
Math::Matrix matrix;
|
||||
Math::Vector n, pos, p, eye;
|
||||
Math::Point uv1, uv2;
|
||||
float iDeep, deep, size, fogStart, fogEnd;
|
||||
int i, j, u;
|
||||
if (! m_enable) return;
|
||||
if (m_level == 0.0f) return;
|
||||
if (m_lines.empty()) return;
|
||||
|
||||
if ( !m_enable ) return;
|
||||
if ( m_level == 0.0f ) return;
|
||||
if ( m_linesUsed == 0 ) return;
|
||||
std::vector<Gfx::VertexTex2> vertices((m_brick+2)*2, Gfx::VertexTex2());
|
||||
|
||||
vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2);
|
||||
|
||||
iDeep = m_engine->GetDeepView();
|
||||
deep = (m_brick*m_size)/2.0f;
|
||||
float iDeep = m_engine->GetDeepView();
|
||||
float deep = (m_brick*m_size)/2.0f;
|
||||
m_engine->SetDeepView(deep);
|
||||
m_engine->SetFocus(m_engine->GetFocus());
|
||||
m_engine->UpdateMatProj(); // increases the depth of view
|
||||
|
||||
fogStart = deep*0.15f;
|
||||
fogEnd = deep*0.24f;
|
||||
float fogStart = deep*0.15f;
|
||||
float fogEnd = deep*0.24f;
|
||||
|
||||
device = m_engine->GetD3DDevice();
|
||||
device->SetRenderState(D3DRENDERSTATE_AMBIENT, 0x00000000);
|
||||
device->SetRenderState(D3DRENDERSTATE_LIGHTING, false);
|
||||
device->SetRenderState(D3DRENDERSTATE_ZENABLE, false);
|
||||
device->SetRenderState(D3DRENDERSTATE_FOGENABLE, true);
|
||||
device->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(fogStart));
|
||||
device->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(fogEnd));
|
||||
Gfx::CDevice* device = m_engine->GetDevice();
|
||||
|
||||
matView = m_engine->GetMatView();
|
||||
{
|
||||
D3DMATRIX mat = MAT_TO_D3DMAT(*matView);
|
||||
device->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat);
|
||||
}
|
||||
// TODO: do this better?
|
||||
device->SetFogParams(Gfx::FOG_LINEAR, m_engine->GetFogColor( m_engine->GetRankView() ),
|
||||
fogStart, fogEnd, 1.0f);
|
||||
|
||||
ZeroMemory( &material, sizeof(D3DMATERIAL7) );
|
||||
device->SetTransform(Gfx::TRANSFORM_VIEW, m_engine->GetMatView());
|
||||
|
||||
Gfx::Material material;
|
||||
material.diffuse = m_diffuse;
|
||||
material.ambient = m_ambient;
|
||||
m_engine->SetMaterial(material);
|
||||
|
||||
m_engine->SetTexture(m_filename, 0);
|
||||
m_engine->SetTexture(m_filename, 1);
|
||||
m_engine->SetTexture(m_fileName, 0);
|
||||
m_engine->SetTexture(m_fileName, 1);
|
||||
|
||||
m_engine->SetState(D3DSTATETTb|D3DSTATEFOG|D3DSTATEWRAP);
|
||||
m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK | Gfx::ENG_RSTATE_FOG | Gfx::ENG_RSTATE_WRAP);
|
||||
|
||||
Math::Matrix matrix;
|
||||
matrix.LoadIdentity();
|
||||
{
|
||||
D3DMATRIX mat = MAT_TO_D3DMAT(matrix);
|
||||
device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
|
||||
}
|
||||
device->SetTransform(Gfx::TRANSFORM_WORLD, matrix);
|
||||
|
||||
size = m_size/2.0f;
|
||||
eye = m_engine->GetEyePt();
|
||||
n = Math::Vector(0.0f, -1.0f, 0.0f);
|
||||
float size = m_size/2.0f;
|
||||
Math::Vector eye = m_engine->GetEyePt();
|
||||
Math::Vector n = Math::Vector(0.0f, -1.0f, 0.0f);
|
||||
|
||||
// Draws all the lines.
|
||||
for ( i=0 ; i<m_linesUsed ; i++ )
|
||||
// Draws all the lines
|
||||
for (int i = 0; i < static_cast<int>( m_lines.size() ); i++)
|
||||
{
|
||||
Math::Vector pos;
|
||||
pos.y = m_level;
|
||||
pos.z = m_lines[i].pz;
|
||||
pos.x = m_lines[i].px1;
|
||||
|
||||
u = 0;
|
||||
int vertexIndex = 0;
|
||||
|
||||
Math::Vector p;
|
||||
Math::Point uv1, uv2;
|
||||
|
||||
p.x = pos.x-size;
|
||||
p.z = pos.z+size;
|
||||
p.y = pos.y;
|
||||
AdjustLevel(p, eye, deep, uv1, uv2);
|
||||
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
|
||||
vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
|
||||
|
||||
p.x = pos.x-size;
|
||||
p.z = pos.z-size;
|
||||
p.y = pos.y;
|
||||
AdjustLevel(p, eye, deep, uv1, uv2);
|
||||
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
|
||||
vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
|
||||
|
||||
for ( j=0 ; j<m_lines[i].len ; j++ )
|
||||
for (int j = 0; j < m_lines[i].len; j++)
|
||||
{
|
||||
p.x = pos.x+size;
|
||||
p.z = pos.z+size;
|
||||
p.y = pos.y;
|
||||
AdjustLevel(p, eye, deep, uv1, uv2);
|
||||
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
|
||||
vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
|
||||
|
||||
p.x = pos.x+size;
|
||||
p.z = pos.z-size;
|
||||
p.y = pos.y;
|
||||
AdjustLevel(p, eye, deep, uv1, uv2);
|
||||
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
|
||||
vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
|
||||
|
||||
pos.x += size*2.0f;
|
||||
}
|
||||
|
||||
device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL);
|
||||
m_engine->AddStatisticTriangle(u-2);
|
||||
device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, &vertices[0], vertexIndex);
|
||||
m_engine->AddStatisticTriangle(vertexIndex - 2);
|
||||
}
|
||||
|
||||
m_engine->SetDeepView(iDeep);
|
||||
m_engine->SetFocus(m_engine->GetFocus());
|
||||
m_engine->UpdateMatProj(); // gives depth to initial
|
||||
|
||||
free(vertex); */
|
||||
}
|
||||
|
||||
void Gfx::CCloud::CreateLine(int x, int y, int len)
|
||||
|
|
|
@ -40,12 +40,19 @@ namespace Gfx {
|
|||
class CEngine;
|
||||
class CTerrain;
|
||||
|
||||
/**
|
||||
* \struct CloudLine
|
||||
* \brief Cloud strip
|
||||
*/
|
||||
struct CloudLine
|
||||
{
|
||||
//! Beginning
|
||||
//@{
|
||||
//! Beginning (terrain coordinates)
|
||||
short x, y;
|
||||
//! In length x
|
||||
//@}
|
||||
//! Length in X direction (terrain coordinates)
|
||||
short len;
|
||||
//! X (1, 2) and Z coordinates (world coordinates)
|
||||
float px1, px2, pz;
|
||||
|
||||
CloudLine()
|
||||
|
@ -57,6 +64,15 @@ struct CloudLine
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* \class CCloud
|
||||
* \brief Cloud layer renderer
|
||||
*
|
||||
* Renders the cloud layer as fog. Cloud layer is similar to water layer
|
||||
* - it occurs only at specified level of terrain. Cloud map is created
|
||||
* the same way water is created. CloudLine structs are used to specify
|
||||
* lines in X direction in XY terrain coordinates.
|
||||
*/
|
||||
class CCloud
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -946,7 +946,7 @@ bool Gfx::CEngine::AddQuick(int objRank, const Gfx::EngineObjLevel4& buffer,
|
|||
|
||||
if (buffer.type == Gfx::ENG_TRIANGLE_TYPE_TRIANGLES)
|
||||
m_objects[objRank].totalTriangles += buffer.vertices.size() / 3;
|
||||
else // surfaces
|
||||
else if (buffer.type == Gfx::ENG_TRIANGLE_TYPE_SURFACE)
|
||||
m_objects[objRank].totalTriangles += buffer.vertices.size() - 2;
|
||||
|
||||
return true;
|
||||
|
@ -2203,13 +2203,15 @@ bool Gfx::CEngine::LoadAllTextures()
|
|||
|
||||
if (! p1.tex1Name.empty())
|
||||
{
|
||||
if (! LoadTexture(p1.tex1Name).Valid())
|
||||
p1.tex1 = LoadTexture(p1.tex1Name);
|
||||
if (! p1.tex1.Valid())
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if (! p1.tex2Name.empty())
|
||||
{
|
||||
if (! LoadTexture(p1.tex2Name).Valid())
|
||||
p1.tex2 = LoadTexture(p1.tex2Name);
|
||||
if (! p1.tex2.Valid())
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
@ -2865,15 +2867,6 @@ void Gfx::CEngine::Render()
|
|||
|
||||
void Gfx::CEngine::Draw3DScene()
|
||||
{
|
||||
/* TODO!
|
||||
D3DObjLevel1* p1;
|
||||
D3DObjLevel2* p2;
|
||||
D3DObjLevel3* p3;
|
||||
D3DObjLevel4* p4;
|
||||
D3DObjLevel5* p5;
|
||||
D3DVERTEX2* pv;
|
||||
int l1, l2, l3, l4, l5, objRank;*/
|
||||
|
||||
if (m_groundSpotVisible)
|
||||
UpdateGroundSpotTextures();
|
||||
|
||||
|
@ -2899,144 +2892,144 @@ void Gfx::CEngine::Draw3DScene()
|
|||
|
||||
if (m_shadowVisible)
|
||||
{
|
||||
// Draw the field
|
||||
// TODO!
|
||||
/*
|
||||
p1 = m_objectPointer;
|
||||
for ( l1=0 ; l1<p1->totalUsed ; l1++ )
|
||||
// Draw the terrain
|
||||
|
||||
for (int l1 = 0; l1 < static_cast<int>( m_objectTree.size() ); l1++)
|
||||
{
|
||||
p2 = p1->table[l1];
|
||||
if ( p2 == 0 ) continue;
|
||||
SetTexture(p2->tex1Name, 0);
|
||||
SetTexture(p2->tex2Name, 1);
|
||||
for ( l2=0 ; l2<p2->totalUsed ; l2++ )
|
||||
Gfx::EngineObjLevel1& p1 = m_objectTree[l1];
|
||||
if (! p1.used) continue;
|
||||
|
||||
// Should be loaded by now
|
||||
SetTexture(p1.tex1, 0);
|
||||
SetTexture(p1.tex2, 1);
|
||||
|
||||
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
||||
{
|
||||
p3 = p2->table[l2];
|
||||
if ( p3 == 0 ) continue;
|
||||
objRank = p3->objRank;
|
||||
if ( m_objects[objRank].type != TYPETERRAIN ) continue;
|
||||
if ( !m_objects[objRank].bDrawWorld ) continue;
|
||||
Gfx::EngineObjLevel2& p2 = p1.next[l2];
|
||||
if (! p2.used) continue;
|
||||
|
||||
{
|
||||
D3DMATRIX mat = MAT_TO_D3DMAT(m_objects[objRank].transform);
|
||||
m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
|
||||
}
|
||||
int objRank = p2.objRank;
|
||||
if (m_objects[objRank].type != Gfx::ENG_OBJTYPE_TERRAIN)
|
||||
continue;
|
||||
if (! m_objects[objRank].drawWorld)
|
||||
continue;
|
||||
|
||||
if ( !IsVisible(objRank) ) continue;
|
||||
m_light->LightUpdate(m_objects[objRank].type);
|
||||
for ( l3=0 ; l3<p3->totalUsed ; l3++ )
|
||||
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
||||
{
|
||||
p4 = p3->table[l3];
|
||||
if ( p4 == 0 ) continue;
|
||||
if ( m_objects[objRank].distance < p4->min ||
|
||||
m_objects[objRank].distance >= p4->max ) continue;
|
||||
for ( l4=0 ; l4<p4->totalUsed ; l4++ )
|
||||
Gfx::EngineObjLevel3& p3 = p2.next[l1];
|
||||
if (! p3.used) continue;
|
||||
|
||||
if ( m_objects[objRank].distance < p3.min ||
|
||||
m_objects[objRank].distance >= p3.max ) continue;
|
||||
|
||||
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
||||
{
|
||||
p5 = p4->table[l4];
|
||||
if ( p5 == 0 ) continue;
|
||||
for ( l5=0 ; l5<p5->totalUsed ; l5++ )
|
||||
Gfx::EngineObjLevel4& p4 = p3.next[l4];
|
||||
if (! p4.used) continue;
|
||||
|
||||
SetMaterial(p4.material);
|
||||
SetState(p4.state);
|
||||
|
||||
if (p4.type == Gfx::ENG_TRIANGLE_TYPE_TRIANGLES)
|
||||
{
|
||||
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_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLES,
|
||||
&p4.vertices[0],
|
||||
p4.vertices.size() );
|
||||
m_statisticTriangle += p4.vertices.size() / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// Draws the shadows
|
||||
DrawShadow();
|
||||
}
|
||||
|
||||
// Draw objects
|
||||
bool transparent = false;
|
||||
/* TODO!
|
||||
p1 = m_objectPointer;
|
||||
for ( l1=0 ; l1<p1->totalUsed ; l1++ )
|
||||
{
|
||||
p2 = p1->table[l1];
|
||||
if ( p2 == 0 ) continue;
|
||||
SetTexture(p2->tex1Name, 0);
|
||||
SetTexture(p2->tex2Name, 1);
|
||||
for ( l2=0 ; l2<p2->totalUsed ; l2++ )
|
||||
{
|
||||
p3 = p2->table[l2];
|
||||
if ( p3 == 0 ) continue;
|
||||
objRank = p3->objRank;
|
||||
if ( m_bShadow && m_objects[objRank].type == TYPETERRAIN ) continue;
|
||||
if ( !m_objects[objRank].bDrawWorld ) continue;
|
||||
|
||||
{
|
||||
D3DMATRIX mat = MAT_TO_D3DMAT(m_objects[objRank].transform);
|
||||
m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
|
||||
}
|
||||
|
||||
if ( !IsVisible(objRank) ) continue;
|
||||
m_light->LightUpdate(m_objects[objRank].type);
|
||||
for ( l3=0 ; l3<p3->totalUsed ; l3++ )
|
||||
{
|
||||
p4 = p3->table[l3];
|
||||
if ( p4 == 0 ) continue;
|
||||
if ( m_objects[objRank].distance < p4->min ||
|
||||
m_objects[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_objects[objRank].transparency != 0.0f ) // transparent ?
|
||||
if (p4.type == Gfx::ENG_TRIANGLE_TYPE_SURFACE)
|
||||
{
|
||||
transparent = 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;
|
||||
m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLE_STRIP,
|
||||
&p4.vertices[0],
|
||||
p4.vertices.size() );
|
||||
m_statisticTriangle += p4.vertices.size() - 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// Draws the shadows
|
||||
DrawShadow();
|
||||
}
|
||||
|
||||
// Draw objects (non-terrain)
|
||||
|
||||
bool transparent = false;
|
||||
|
||||
for (int l1 = 0; l1 < static_cast<int>( m_objectTree.size() ); l1++)
|
||||
{
|
||||
Gfx::EngineObjLevel1& p1 = m_objectTree[l1];
|
||||
if (! p1.used) continue;
|
||||
|
||||
// Should be loaded by now
|
||||
SetTexture(p1.tex1, 0);
|
||||
SetTexture(p1.tex2, 1);
|
||||
|
||||
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
||||
{
|
||||
Gfx::EngineObjLevel2& p2 = p1.next[l2];
|
||||
if (! p2.used) continue;
|
||||
|
||||
int objRank = p2.objRank;
|
||||
|
||||
if (m_shadowVisible && m_objects[objRank].type == Gfx::ENG_OBJTYPE_TERRAIN)
|
||||
continue;
|
||||
|
||||
if (! m_objects[objRank].drawWorld)
|
||||
continue;
|
||||
|
||||
m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_objects[objRank].transform);
|
||||
|
||||
if (! IsVisible(objRank))
|
||||
continue;
|
||||
|
||||
m_lightMan->UpdateLightsEnableState(m_objects[objRank].type);
|
||||
|
||||
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
||||
{
|
||||
Gfx::EngineObjLevel3& p3 = p2.next[l1];
|
||||
if (! p3.used) continue;
|
||||
|
||||
if ( m_objects[objRank].distance < p3.min ||
|
||||
m_objects[objRank].distance >= p3.max ) continue;
|
||||
|
||||
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
||||
{
|
||||
Gfx::EngineObjLevel4& p4 = p3.next[l4];
|
||||
if (! p4.used) continue;
|
||||
|
||||
if (m_objects[objRank].transparency != 0.0f) // transparent ?
|
||||
{
|
||||
transparent = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
SetMaterial(p4.material);
|
||||
SetState(p4.state);
|
||||
|
||||
if (p4.type == Gfx::ENG_TRIANGLE_TYPE_TRIANGLES)
|
||||
{
|
||||
m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLES,
|
||||
&p4.vertices[0],
|
||||
p4.vertices.size() );
|
||||
|
||||
m_statisticTriangle += p4.vertices.size() / 3;
|
||||
}
|
||||
else if (p4.type == Gfx::ENG_TRIANGLE_TYPE_SURFACE)
|
||||
{
|
||||
m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLE_STRIP,
|
||||
&p4.vertices[0],
|
||||
p4.vertices.size() );
|
||||
|
||||
m_statisticTriangle += p4.vertices.size() - 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw transparent objects
|
||||
|
||||
if (transparent)
|
||||
{
|
||||
|
@ -3053,70 +3046,73 @@ void Gfx::CEngine::Draw3DScene()
|
|||
tColor = Gfx::Color(136.0f / 255.0f, 136.0f / 255.0f, 136.0f / 255.0f, 136.0f / 255.0f);
|
||||
}
|
||||
|
||||
// Draw transparent objects.
|
||||
/* TODO!
|
||||
p1 = m_objectPointer;
|
||||
for ( l1=0 ; l1<p1->totalUsed ; l1++ )
|
||||
for (int l1 = 0; l1 < static_cast<int>( m_objectTree.size() ); l1++)
|
||||
{
|
||||
p2 = p1->table[l1];
|
||||
if ( p2 == 0 ) continue;
|
||||
SetTexture(p2->tex1Name, 0);
|
||||
SetTexture(p2->tex2Name, 1);
|
||||
for ( l2=0 ; l2<p2->totalUsed ; l2++ )
|
||||
Gfx::EngineObjLevel1& p1 = m_objectTree[l1];
|
||||
if (! p1.used) continue;
|
||||
|
||||
// Should be loaded by now
|
||||
SetTexture(p1.tex1, 0);
|
||||
SetTexture(p1.tex2, 1);
|
||||
|
||||
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
||||
{
|
||||
p3 = p2->table[l2];
|
||||
if ( p3 == 0 ) continue;
|
||||
objRank = p3->objRank;
|
||||
if ( m_bShadow && m_objects[objRank].type == TYPETERRAIN ) continue;
|
||||
if ( !m_objects[objRank].bDrawWorld ) continue;
|
||||
Gfx::EngineObjLevel2& p2 = p1.next[l2];
|
||||
if (! p2.used) continue;
|
||||
|
||||
{
|
||||
D3DMATRIX mat = MAT_TO_D3DMAT(m_objects[objRank].transform);
|
||||
m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
|
||||
}
|
||||
int objRank = p2.objRank;
|
||||
|
||||
if ( !IsVisible(objRank) ) continue;
|
||||
m_light->LightUpdate(m_objects[objRank].type);
|
||||
for ( l3=0 ; l3<p3->totalUsed ; l3++ )
|
||||
if (m_shadowVisible && m_objects[objRank].type == Gfx::ENG_OBJTYPE_TERRAIN)
|
||||
continue;
|
||||
|
||||
if (! m_objects[objRank].drawWorld)
|
||||
continue;
|
||||
|
||||
m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_objects[objRank].transform);
|
||||
|
||||
if (! IsVisible(objRank))
|
||||
continue;
|
||||
|
||||
m_lightMan->UpdateLightsEnableState(m_objects[objRank].type);
|
||||
|
||||
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
||||
{
|
||||
p4 = p3->table[l3];
|
||||
if ( p4 == 0 ) continue;
|
||||
if ( m_objects[objRank].distance < p4->min ||
|
||||
m_objects[objRank].distance >= p4->max ) continue;
|
||||
for ( l4=0 ; l4<p4->totalUsed ; l4++ )
|
||||
Gfx::EngineObjLevel3& p3 = p2.next[l1];
|
||||
if (! p3.used) continue;
|
||||
|
||||
if ( m_objects[objRank].distance < p3.min ||
|
||||
m_objects[objRank].distance >= p3.max ) continue;
|
||||
|
||||
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
||||
{
|
||||
p5 = p4->table[l4];
|
||||
if ( p5 == 0 ) continue;
|
||||
for ( l5=0 ; l5<p5->totalUsed ; l5++ )
|
||||
Gfx::EngineObjLevel4& p4 = p3.next[l4];
|
||||
if (! p4.used) continue;
|
||||
|
||||
if (m_objects[objRank].transparency == 0.0f)
|
||||
continue;
|
||||
|
||||
SetMaterial(p4.material);
|
||||
SetState(tState, tColor);
|
||||
|
||||
if (p4.type == Gfx::ENG_TRIANGLE_TYPE_TRIANGLES)
|
||||
{
|
||||
p6 = p5->table[l5];
|
||||
if ( p6 == 0 ) continue;
|
||||
SetMaterial(p6->material);
|
||||
if ( m_objects[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_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLES,
|
||||
&p4.vertices[0],
|
||||
p4.vertices.size() );
|
||||
|
||||
m_statisticTriangle += p4.vertices.size() / 3;
|
||||
}
|
||||
else if (p4.type == Gfx::ENG_TRIANGLE_TYPE_SURFACE)
|
||||
{
|
||||
m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLE_STRIP,
|
||||
&p4.vertices[0],
|
||||
p4.vertices.size() );
|
||||
m_statisticTriangle += p4.vertices.size() - 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
m_lightMan->UpdateLightsEnableState(Gfx::ENG_OBJTYPE_TERRAIN);
|
||||
|
@ -3165,68 +3161,70 @@ void Gfx::CEngine::DrawInterface()
|
|||
|
||||
m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matView);
|
||||
|
||||
// TODO!
|
||||
/*
|
||||
for (int l1 = 0; l1 < m_objectTree.size(); l1++)
|
||||
for (int l1 = 0; l1 < static_cast<int>( m_objectTree.size() ); l1++)
|
||||
{
|
||||
Gfx::EngineObjLevel1* p1 = &m_objectTree[l1];
|
||||
p2 = p1->table[l1];
|
||||
if ( p2 == 0 ) continue;
|
||||
SetTexture(p2->tex1Name, 0);
|
||||
SetTexture(p2->tex2Name, 1);
|
||||
for ( l2=0 ; l2<p2->totalUsed ; l2++ )
|
||||
Gfx::EngineObjLevel1& p1 = m_objectTree[l1];
|
||||
if (! p1.used) continue;
|
||||
|
||||
// Should be loaded by now
|
||||
SetTexture(p1.tex1, 0);
|
||||
SetTexture(p1.tex2, 1);
|
||||
|
||||
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
||||
{
|
||||
p3 = p2->table[l2];
|
||||
if ( p3 == 0 ) continue;
|
||||
objRank = p3->objRank;
|
||||
if ( !m_objects[objRank].bDrawFront ) continue;
|
||||
Gfx::EngineObjLevel2& p2 = p1.next[l2];
|
||||
if (! p2.used) continue;
|
||||
|
||||
{
|
||||
D3DMATRIX mat = MAT_TO_D3DMAT(m_objects[objRank].transform);
|
||||
m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
|
||||
}
|
||||
int objRank = p2.objRank;
|
||||
|
||||
if ( !IsVisible(objRank) ) continue;
|
||||
m_light->LightUpdate(m_objects[objRank].type);
|
||||
for ( l3=0 ; l3<p3->totalUsed ; l3++ )
|
||||
if (m_shadowVisible && m_objects[objRank].type == Gfx::ENG_OBJTYPE_TERRAIN)
|
||||
continue;
|
||||
|
||||
if (! m_objects[objRank].drawFront)
|
||||
continue;
|
||||
|
||||
m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_objects[objRank].transform);
|
||||
|
||||
if (! IsVisible(objRank))
|
||||
continue;
|
||||
|
||||
m_lightMan->UpdateLightsEnableState(m_objects[objRank].type);
|
||||
|
||||
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
||||
{
|
||||
p4 = p3->table[l3];
|
||||
if ( p4 == 0 ) continue;
|
||||
if ( m_objects[objRank].distance < p4->min ||
|
||||
m_objects[objRank].distance >= p4->max ) continue;
|
||||
for ( l4=0 ; l4<p4->totalUsed ; l4++ )
|
||||
Gfx::EngineObjLevel3& p3 = p2.next[l1];
|
||||
if (! p3.used) continue;
|
||||
|
||||
if ( m_objects[objRank].distance < p3.min ||
|
||||
m_objects[objRank].distance >= p3.max ) continue;
|
||||
|
||||
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
||||
{
|
||||
p5 = p4->table[l4];
|
||||
if ( p5 == 0 ) continue;
|
||||
for ( l5=0 ; l5<p5->totalUsed ; l5++ )
|
||||
Gfx::EngineObjLevel4& p4 = p3.next[l4];
|
||||
if (! p4.used) continue;
|
||||
|
||||
SetMaterial(p4.material);
|
||||
SetState(p4.state);
|
||||
|
||||
if (p4.type == Gfx::ENG_TRIANGLE_TYPE_TRIANGLES)
|
||||
{
|
||||
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_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLES,
|
||||
&p4.vertices[0],
|
||||
p4.vertices.size() );
|
||||
|
||||
m_statisticTriangle += p4.vertices.size() / 3;
|
||||
}
|
||||
else if (p4.type == Gfx::ENG_TRIANGLE_TYPE_SURFACE)
|
||||
{
|
||||
m_device->DrawPrimitive( Gfx::PRIMITIVE_TRIANGLE_STRIP,
|
||||
&p4.vertices[0],
|
||||
p4.vertices.size() );
|
||||
m_statisticTriangle += p4.vertices.size() - 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
m_particle->DrawParticle(Gfx::SH_FRONT); // draws the particles of the 3D world
|
||||
|
||||
|
|
|
@ -539,24 +539,95 @@ struct EngineMouse
|
|||
|
||||
|
||||
/**
|
||||
\class CEngine
|
||||
\brief The graphics engine
|
||||
|
||||
This is the main class for graphics engine. It is responsible for drawing the 3D scene,
|
||||
setting various render states, and facilitating the drawing of 2D interface.
|
||||
|
||||
It uses a lower-level CDevice object which is implementation-independent core engine.
|
||||
|
||||
\section Objecs Engine objects
|
||||
|
||||
The 3D scene is composed of objects which are basically collections of triangles forming
|
||||
a surface or simply independent triangles in space. Objects are stored in the engine
|
||||
as a tree structure which is composed of 4 tiers (EngineObjLevel1, EngineObjLevel2 and so on).
|
||||
Each tier stores some data about object triangle, like textures or materials used.
|
||||
Additional information on objects stored are in EngineObject structure.
|
||||
Each object is uniquely identified by its rank.
|
||||
|
||||
...
|
||||
* \class CEngine
|
||||
* \brief The graphics engine
|
||||
*
|
||||
* This is the main class for graphics engine. It is responsible for drawing the 3D scene,
|
||||
* setting various render states, and facilitating the drawing of 2D interface.
|
||||
*
|
||||
* It uses a lower-level CDevice object which is implementation-independent core engine.
|
||||
*
|
||||
* \section 3DScene 3D Scene
|
||||
*
|
||||
* The 3D scene is drawn with view coordinates set from camera position in 3D space and
|
||||
* a perspective projection matrix. The world matrix depends on the object drawn.
|
||||
* The coordinate system is left-handed: X axis is to the right, Y axis to the top and Z axis
|
||||
* is into the screen (Z = 0 is the sceen surface).
|
||||
*
|
||||
* In general, the 3D scene is composed of the following things:
|
||||
* - sky background (gradient or texture image)
|
||||
* - planets orbiting in the sky (drawn by CPlanet)
|
||||
* - terrain - ground of the game level (part of engine objects)
|
||||
* - main scene objects - robots, buildings, etc. (engine objects)
|
||||
* - water/lava (drawn by CWater)
|
||||
* - cloud layer (drawn by CCloud)
|
||||
* - fire, lightning and particle effects (CPyro, CLightning and CParticle)
|
||||
* - foreground image overlaid onto the scene at the end - for example, aiming crosshairs
|
||||
* - 2D interface controls available in-game
|
||||
* - mouse cursor
|
||||
* - animated highlight box of the selected object(s)
|
||||
*
|
||||
* \section 2DInterface 2D Interface
|
||||
*
|
||||
* The 2D interface is drawn in fixed XY coordinates, independent from window size.
|
||||
* Lower-left corner of the screen is (0,0) and upper-right corner is (1,1).
|
||||
* Matrices for world, view and projection are therefore fixed and never change.
|
||||
*
|
||||
* The class tracks the change of window coordinates and conversion functions
|
||||
* between the window and interface coordinates are provided.
|
||||
*
|
||||
* Interface drawing is delegated to CInterface class and particular controls
|
||||
* are instances of CControl class. The source code for these classes is in
|
||||
* src/ui directory.
|
||||
*
|
||||
* \section Objecs Engine Objects
|
||||
*
|
||||
* The 3D scene is composed of objects which are basically collections of triangles forming
|
||||
* a surface or simply independent triangles in space.
|
||||
*
|
||||
* Objects are uniquely identified by object rank obtained at object creation. Creating an
|
||||
* object equals to allocating space for EngineObject structure which holds object parameters.
|
||||
* Object's geometric data is stored in a separate structure - a 4-tier tree which splits
|
||||
* the information of each geometric triangle.
|
||||
*
|
||||
* The 4 tiers contain the following information:
|
||||
* - level 1 (EngineObjLevel1) - two textures (names and structs) applied to triangles,
|
||||
* - level 2 (EngineObjLevel2) - object rank
|
||||
* - level 3 (EngineObjLevel3) - minumum and maximum LOD (=level of detail)
|
||||
* - level 4 (EngineObjLevel4) - type of object*, material, render state and the actual triangle data
|
||||
*
|
||||
* NOTE: type of object in this context means only the internal type in 3D engine. It is not related
|
||||
* to CObject types.
|
||||
*
|
||||
* Such tiered structure complicates loops over all object data, but saves a lot of memory and
|
||||
* optimizes the rendering process (for instance, switching of textures is an expensive operation).
|
||||
*
|
||||
* \section Shadows Shadows
|
||||
*
|
||||
* Each engine object can be associated with a shadow (EngineShadow). Like objects, shadows are
|
||||
* identified by their rank obtained upon creation.
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* \section RenderStates Render States
|
||||
*
|
||||
* Almost every primitive drawn on screen is drawn in state set through EngineRenderState enum.
|
||||
* In some functions, custom modes are still set, using CDevice's SetRenderState. However, it
|
||||
* will be subject to removal in the future. Generally, setting render states should be minimized
|
||||
* to avoid unnecessary overhead.
|
||||
*
|
||||
* Some states are clearly the result of legacy drawing and texturing methods. For example, TTEXTURE
|
||||
* states should really be removed and the textures changed to ones with alpha channel. In the future,
|
||||
* the whole modesetting code will probably be refactored to something more maintainable.
|
||||
*
|
||||
* \section Textures Textures
|
||||
*
|
||||
* Textures are loaded from a texture subdir in data directory. In the old code, textures were identified
|
||||
* by file name and loaded using some D3D util code. With new code and OpenGL backend, this approach is not
|
||||
* efficient - name comparison, etc. takes a lot of time. In the future, textures should be loaded once
|
||||
* at object creation time, and then referenced to as Gfx::Texture structs, or even as unsigned int ID's
|
||||
* which is what OpenGL actually wants. The old method is kept for now, with mapping between texture names
|
||||
* and texture structs but it will also be subject to refactoring in the future.
|
||||
*/
|
||||
class CEngine
|
||||
{
|
||||
|
|
|
@ -47,7 +47,12 @@ enum BlitzPhase
|
|||
BPH_BLITZ,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \class CLightning
|
||||
* \brief Lightning effect renderer
|
||||
*
|
||||
* Functions are only stubs for now.
|
||||
*/
|
||||
class CLightning
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -723,25 +723,18 @@ bool Gfx::CModelFile::ReadDXF(std::istream &stream, float min, float max)
|
|||
|
||||
bool Gfx::CModelFile::CreateEngineObject(int objRank, int addState)
|
||||
{
|
||||
/*char texName1[20];
|
||||
char texName2[20];
|
||||
int texNum, i, state;
|
||||
|
||||
for (int i = 0; i < m_trianglesUsed; i++)
|
||||
for (int i = 0; i < static_cast<int>( m_triangles.size() ); i++)
|
||||
{
|
||||
if (! m_triangles[i].used) continue;
|
||||
int state = m_triangles[i].state;
|
||||
|
||||
state = m_triangles[i].state;
|
||||
strcpy(texName1, m_triangles[i].texName);
|
||||
texName2[0] = 0;
|
||||
/* TODO ???
|
||||
if (texName1 == "plant.png")
|
||||
state |= Gfx::ENG_RSTATE_ALPHA;
|
||||
|
||||
if ( strcmp(texName1, "plant.tga") == 0 ) // ???
|
||||
if (m_triangles[i].tex2Name.empty())
|
||||
{
|
||||
state |= D3DSTATEALPHA;
|
||||
}
|
||||
int texNum = 0;
|
||||
|
||||
if ( m_triangles[i].texNum2 != 0 )
|
||||
{
|
||||
if ( m_triangles[i].texNum2 == 1 )
|
||||
{
|
||||
texNum = m_engine->RetSecondTexture();
|
||||
|
@ -760,15 +753,22 @@ bool Gfx::CModelFile::CreateEngineObject(int objRank, int addState)
|
|||
state |= D3DSTATEDUALw;
|
||||
}
|
||||
sprintf(texName2, "dirty%.2d.tga", texNum); // ???
|
||||
}
|
||||
}*/
|
||||
|
||||
std::vector<Gfx::VertexTex2> vs;
|
||||
vs.push_back(m_triangles[i].p1);
|
||||
vs.push_back(m_triangles[i].p2);
|
||||
vs.push_back(m_triangles[i].p3);
|
||||
|
||||
m_engine->AddTriangles(objRank, vs,
|
||||
m_triangles[i].material,
|
||||
state + addState,
|
||||
m_triangles[i].tex1Name,
|
||||
m_triangles[i].tex2Name,
|
||||
m_triangles[i].min,
|
||||
m_triangles[i].max, false);
|
||||
}
|
||||
|
||||
m_engine->AddTriangle(objRank, &m_triangles[i].p1, 3,
|
||||
m_triangles[i].material,
|
||||
state + addState,
|
||||
texName1, texName2,
|
||||
m_triangles[i].min,
|
||||
m_triangles[i].max, false);
|
||||
}*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -256,7 +256,12 @@ struct WheelTrace
|
|||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \class CParticle
|
||||
* \brief Particle engine
|
||||
*
|
||||
* Functions are only stubs for now.
|
||||
*/
|
||||
class CParticle
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -35,6 +35,10 @@ namespace Gfx {
|
|||
|
||||
class CEngine;
|
||||
|
||||
/**
|
||||
* \struct Planet
|
||||
* \brief Planet texture definition
|
||||
*/
|
||||
struct Planet
|
||||
{
|
||||
//! Initial position in degrees
|
||||
|
@ -63,6 +67,15 @@ struct Planet
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \class CPlanet
|
||||
* \brief Planet manager
|
||||
*
|
||||
* Draws the planets orbiting in the sky.
|
||||
*
|
||||
* Planets are drawn in 2D mode, at coordinates calculated from camera position.
|
||||
*/
|
||||
class CPlanet
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -90,7 +90,12 @@ struct PyroLightOper
|
|||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \class CPyro
|
||||
* \brief Fire effect renderer
|
||||
*
|
||||
* Functions are only stubs for now.
|
||||
*/
|
||||
class CPyro
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -34,19 +34,31 @@ class CEngine;
|
|||
class CWater;
|
||||
|
||||
|
||||
//! Limit of slope considered a flat piece of land
|
||||
const short FLATLIMIT = (5.0f*Math::PI/180.0f);
|
||||
|
||||
|
||||
/**
|
||||
* \enum TerrainRes
|
||||
* \brief Underground resource type
|
||||
*/
|
||||
enum TerrainRes
|
||||
{
|
||||
TR_NULL = 0,
|
||||
TR_STONE = 1,
|
||||
TR_URANIUM = 2,
|
||||
TR_POWER = 3,
|
||||
//! No resource
|
||||
TR_NULL = 0,
|
||||
//! Titanium
|
||||
TR_STONE = 1,
|
||||
//! Uranium
|
||||
TR_URANIUM = 2,
|
||||
//! Energy
|
||||
TR_POWER = 3,
|
||||
//! Vault keys
|
||||
//@{
|
||||
TR_KEY_A = 4,
|
||||
TR_KEY_B = 5,
|
||||
TR_KEY_C = 6,
|
||||
TR_KEY_D = 7,
|
||||
TR_KEY_D = 7
|
||||
//@}
|
||||
};
|
||||
|
||||
struct BuildingLevel
|
||||
|
@ -98,6 +110,10 @@ struct DotLevel
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct FlyingLimit
|
||||
* \brief Spherical limit of flight
|
||||
*/
|
||||
struct FlyingLimit
|
||||
{
|
||||
Math::Vector center;
|
||||
|
@ -112,7 +128,22 @@ struct FlyingLimit
|
|||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \class CTerrain
|
||||
* \brief Terrain loader/generator and manager
|
||||
*
|
||||
* Terrain is created from relief textures specifying a XY plane with height
|
||||
* values which are then scaled and translated into XZ surface forming the
|
||||
* terrain of game level.
|
||||
*
|
||||
* The class also facilitates creating and searching for flat space expanses
|
||||
* for construction of buildings.
|
||||
*
|
||||
* The terrain also specifies underground resources loaded from texture
|
||||
* and flying limits for the player.
|
||||
*
|
||||
* ...
|
||||
*/
|
||||
class CTerrain
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -21,8 +21,10 @@
|
|||
|
||||
#include "common/iman.h"
|
||||
#include "common/logger.h"
|
||||
#include "graphics/core/device.h"
|
||||
#include "graphics/engine/engine.h"
|
||||
#include "graphics/engine/terrain.h"
|
||||
#include "math/geometry.h"
|
||||
#include "object/object.h"
|
||||
#include "sound/sound.h"
|
||||
|
||||
|
@ -258,53 +260,41 @@ void Gfx::CWater::AdjustLevel(Math::Vector &pos, Math::Vector &norm,
|
|||
/** This surface prevents to see the sky (background) underwater! */
|
||||
void Gfx::CWater::DrawBack()
|
||||
{
|
||||
GetLogger()->Trace("CWater::DrawBack(): stub!\n");
|
||||
/* TODO!
|
||||
LPDIRECT3DDEVICE7 device;
|
||||
D3DVERTEX2 vertex[4]; // 2 triangles
|
||||
D3DMATERIAL7 material;
|
||||
Math::Matrix matrix;
|
||||
Math::Vector eye, lookat, n, p, p1, p2;
|
||||
Math::Point uv1, uv2;
|
||||
float deep, dist;
|
||||
if (! m_draw) return;
|
||||
if (m_type[0] == WATER_NULL) return;
|
||||
if (m_lines.empty()) return;
|
||||
|
||||
if ( !m_bDraw ) return;
|
||||
if ( m_type[0] == WATER_NULL ) return;
|
||||
if ( m_lineUsed == 0 ) return;
|
||||
Math::Vector eye = m_engine->GetEyePt();
|
||||
Math::Vector lookat = m_engine->GetLookatPt();
|
||||
|
||||
eye = m_engine->GetEyePt();
|
||||
lookat = m_engine->GetLookatPt();
|
||||
|
||||
ZeroMemory( &material, sizeof(D3DMATERIAL7) );
|
||||
Gfx::Material material;
|
||||
material.diffuse = m_diffuse;
|
||||
material.ambient = m_ambient;
|
||||
m_engine->SetMaterial(material);
|
||||
|
||||
m_engine->SetTexture("", 0);
|
||||
m_engine->SetTexture("", 0); // TODO: disable texturing
|
||||
|
||||
device = m_engine->GetD3DDevice();
|
||||
device->SetRenderState(D3DRENDERSTATE_LIGHTING, false);
|
||||
device->SetRenderState(D3DRENDERSTATE_ZENABLE, false);
|
||||
device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);
|
||||
m_engine->SetState(D3DSTATENORMAL);
|
||||
Gfx::CDevice* device = m_engine->GetDevice();
|
||||
|
||||
deep = m_engine->GetDeepView(0);
|
||||
m_engine->SetState(Gfx::ENG_RSTATE_NORMAL);
|
||||
|
||||
float deep = m_engine->GetDeepView(0);
|
||||
m_engine->SetDeepView(deep*2.0f, 0);
|
||||
m_engine->SetFocus(m_engine->GetFocus());
|
||||
m_engine->UpdateMatProj(); // twice the depth of view
|
||||
|
||||
Math::Matrix matrix;
|
||||
matrix.LoadIdentity();
|
||||
{
|
||||
D3DMATRIX mat = MAT_TO_D3DMAT(matrix);
|
||||
device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
|
||||
}
|
||||
device->SetTransform(Gfx::TRANSFORM_WORLD, matrix);
|
||||
|
||||
Math::Vector p;
|
||||
p.x = eye.x;
|
||||
p.z = eye.z;
|
||||
dist = Math::DistanceProjected(eye, lookat);
|
||||
float dist = Math::DistanceProjected(eye, lookat);
|
||||
p.x = (lookat.x-eye.x)*deep*1.0f/dist + eye.x;
|
||||
p.z = (lookat.z-eye.z)*deep*1.0f/dist + eye.z;
|
||||
|
||||
Math::Vector p1, p2;
|
||||
p1.x = (lookat.z-eye.z)*deep*2.0f/dist + p.x;
|
||||
p1.z = -(lookat.x-eye.x)*deep*2.0f/dist + p.z;
|
||||
p2.x = -(lookat.z-eye.z)*deep*2.0f/dist + p.x;
|
||||
|
@ -313,155 +303,132 @@ void Gfx::CWater::DrawBack()
|
|||
p1.y = -50.0f;
|
||||
p2.y = m_level;
|
||||
|
||||
Math::Vector n;
|
||||
n.x = (lookat.x-eye.x)/dist;
|
||||
n.z = (lookat.z-eye.z)/dist;
|
||||
n.y = 0.0f;
|
||||
|
||||
uv1.x = uv1.y = 0.0f;
|
||||
uv2.x = uv2.y = 0.0f;
|
||||
Gfx::Vertex vertices[4] =
|
||||
{
|
||||
Gfx::Vertex(Math::Vector(p1.x, p2.y, p1.z), n),
|
||||
Gfx::Vertex(Math::Vector(p1.x, p1.y, p1.z), n),
|
||||
Gfx::Vertex(Math::Vector(p2.x, p2.y, p2.z), n),
|
||||
Gfx::Vertex(Math::Vector(p2.x, p1.y, p2.z), n)
|
||||
};
|
||||
|
||||
vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p2.y, p1.z), n, uv1.x,uv2.y);
|
||||
vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p1.y, p1.z), n, uv1.x,uv1.y);
|
||||
vertex[2] = D3DVERTEX2(Math::Vector(p2.x, p2.y, p2.z), n, uv2.x,uv2.y);
|
||||
vertex[3] = D3DVERTEX2(Math::Vector(p2.x, p1.y, p2.z), n, uv2.x,uv1.y);
|
||||
|
||||
device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL);
|
||||
device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, vertices, 4);
|
||||
m_engine->AddStatisticTriangle(2);
|
||||
|
||||
m_engine->SetDeepView(deep, 0);
|
||||
m_engine->SetFocus(m_engine->GetFocus());
|
||||
m_engine->UpdateMatProj(); // gives the initial depth of view
|
||||
|
||||
device->SetRenderState(D3DRENDERSTATE_LIGHTING, true);
|
||||
device->SetRenderState(D3DRENDERSTATE_ZENABLE, true);
|
||||
device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);*/
|
||||
}
|
||||
|
||||
void Gfx::CWater::DrawSurf()
|
||||
{
|
||||
GetLogger()->Trace("CWater::DrawSurf(): stub!\n");
|
||||
/* TODO!
|
||||
LPDIRECT3DDEVICE7 device;
|
||||
D3DVERTEX2* vertex; // triangles
|
||||
D3DMATERIAL7 material;
|
||||
Math::Matrix matrix;
|
||||
Math::Vector eye, lookat, n, pos, p;
|
||||
Math::Point uv1, uv2;
|
||||
bool bUnder;
|
||||
DWORD flags;
|
||||
float deep, size, sizez, radius;
|
||||
int rankview, i, j, u;
|
||||
|
||||
if (! m_draw) return;
|
||||
if (m_type[0] == Gfx::WATER_NULL) return;
|
||||
if (m_line.empty()) return;
|
||||
if (m_lines.empty()) return;
|
||||
|
||||
vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2);
|
||||
std::vector<Gfx::VertexTex2> vertices((m_brick+2)*2, Gfx::VertexTex2());
|
||||
|
||||
eye = m_engine->GetEyePt();
|
||||
lookat = m_engine->GetLookatPt();
|
||||
Math::Vector eye = m_engine->GetEyePt();
|
||||
|
||||
rankview = m_engine->GetRankView();
|
||||
bUnder = ( rankview == 1);
|
||||
int rankview = m_engine->GetRankView();
|
||||
bool under = ( rankview == 1);
|
||||
|
||||
device = m_engine->GetD3DDevice();
|
||||
device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);
|
||||
Gfx::CDevice* device = m_engine->GetDevice();
|
||||
|
||||
Math::Matrix matrix;
|
||||
matrix.LoadIdentity();
|
||||
{
|
||||
D3DMATRIX mat = MAT_TO_D3DMAT(matrix);
|
||||
device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);
|
||||
}
|
||||
device->SetTransform(Gfx::TRANSFORM_WORLD, matrix);
|
||||
|
||||
ZeroMemory( &material, sizeof(D3DMATERIAL7) );
|
||||
Gfx::Material material;
|
||||
material.diffuse = m_diffuse;
|
||||
material.ambient = m_ambient;
|
||||
m_engine->SetMaterial(material);
|
||||
|
||||
m_engine->SetTexture(m_filename, 0);
|
||||
m_engine->SetTexture(m_filename, 1);
|
||||
m_engine->SetTexture(m_fileName, 0);
|
||||
m_engine->SetTexture(m_fileName, 1);
|
||||
|
||||
if ( m_type[rankview] == WATER_TT )
|
||||
{
|
||||
m_engine->SetState(D3DSTATETTb|D3DSTATEDUALw|D3DSTATEWRAP, m_color);
|
||||
}
|
||||
if ( m_type[rankview] == WATER_TO )
|
||||
{
|
||||
m_engine->SetState(D3DSTATENORMAL|D3DSTATEDUALw|D3DSTATEWRAP);
|
||||
}
|
||||
if ( m_type[rankview] == WATER_CT )
|
||||
{
|
||||
m_engine->SetState(D3DSTATETTb);
|
||||
}
|
||||
if ( m_type[rankview] == WATER_CO )
|
||||
{
|
||||
m_engine->SetState(D3DSTATENORMAL);
|
||||
}
|
||||
device->SetRenderState(D3DRENDERSTATE_FOGENABLE, true);
|
||||
if (m_type[rankview] == WATER_TT)
|
||||
m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK | Gfx::ENG_RSTATE_DUAL_WHITE | Gfx::ENG_RSTATE_WRAP, m_color);
|
||||
|
||||
size = m_size/2.0f;
|
||||
if ( bUnder ) sizez = -size;
|
||||
else sizez = size;
|
||||
else if (m_type[rankview] == WATER_TO)
|
||||
m_engine->SetState(Gfx::ENG_RSTATE_NORMAL | Gfx::ENG_RSTATE_DUAL_WHITE | Gfx::ENG_RSTATE_WRAP);
|
||||
|
||||
// Draws all the lines.
|
||||
deep = m_engine->GetDeepView(0)*1.5f;
|
||||
else if (m_type[rankview] == WATER_CT)
|
||||
m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_BLACK);
|
||||
|
||||
for ( i=0 ; i<m_lineUsed ; i++ )
|
||||
else if (m_type[rankview] == WATER_CO)
|
||||
m_engine->SetState(Gfx::ENG_RSTATE_NORMAL);
|
||||
|
||||
device->SetRenderState(Gfx::RENDER_STATE_FOG, true);
|
||||
|
||||
float size = m_size/2.0f;
|
||||
float sizez = 0.0f;
|
||||
if (under) sizez = -size;
|
||||
else sizez = size;
|
||||
|
||||
// Draws all the lines
|
||||
float deep = m_engine->GetDeepView(0)*1.5f;
|
||||
|
||||
for (int i = 0; i < static_cast<int>( m_lines.size() ); i++)
|
||||
{
|
||||
Math::Vector pos;
|
||||
pos.y = m_level;
|
||||
pos.z = m_line[i].pz;
|
||||
pos.x = m_line[i].px1;
|
||||
pos.z = m_lines[i].pz;
|
||||
pos.x = m_lines[i].px1;
|
||||
|
||||
// Visible line?
|
||||
p = pos;
|
||||
p.x += size*(m_line[i].len-1);
|
||||
radius = sqrtf(powf(size, 2.0f)+powf(size*m_line[i].len, 2.0f));
|
||||
Math::Vector p = pos;
|
||||
p.x += size*(m_lines[i].len-1);
|
||||
float radius = sqrtf(powf(size, 2.0f)+powf(size*m_lines[i].len, 2.0f));
|
||||
if ( Math::Distance(p, eye) > deep+radius ) continue;
|
||||
|
||||
D3DVECTOR pD3D = VEC_TO_D3DVEC(p);
|
||||
device->ComputeSphereVisibility(&pD3D, &radius, 1, 0, &flags);
|
||||
// TODO: ComputeSphereVisibility
|
||||
|
||||
if ( flags & D3DSTATUS_CLIPINTERSECTIONALL ) continue;
|
||||
int vertexIndex = 0;
|
||||
|
||||
Math::Point uv1, uv2;
|
||||
Math::Vector n;
|
||||
|
||||
u = 0;
|
||||
p.x = pos.x-size;
|
||||
p.z = pos.z-sizez;
|
||||
p.y = pos.y;
|
||||
AdjustLevel(p, n, uv1, uv2);
|
||||
if ( bUnder ) n.y = -n.y;
|
||||
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
|
||||
if (under) n.y = -n.y;
|
||||
vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
|
||||
|
||||
p.x = pos.x-size;
|
||||
p.z = pos.z+sizez;
|
||||
p.y = pos.y;
|
||||
AdjustLevel(p, n, uv1, uv2);
|
||||
if ( bUnder ) n.y = -n.y;
|
||||
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
|
||||
if (under) n.y = -n.y;
|
||||
vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
|
||||
|
||||
for ( j=0 ; j<m_line[i].len ; j++ )
|
||||
for (int j = 0; j < m_lines[i].len; j++)
|
||||
{
|
||||
p.x = pos.x+size;
|
||||
p.z = pos.z-sizez;
|
||||
p.y = pos.y;
|
||||
AdjustLevel(p, n, uv1, uv2);
|
||||
if ( bUnder ) n.y = -n.y;
|
||||
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
|
||||
if (under) n.y = -n.y;
|
||||
vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
|
||||
|
||||
p.x = pos.x+size;
|
||||
p.z = pos.z+sizez;
|
||||
p.y = pos.y;
|
||||
AdjustLevel(p, n, uv1, uv2);
|
||||
if ( bUnder ) n.y = -n.y;
|
||||
vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y);
|
||||
if (under) n.y = -n.y;
|
||||
vertices[vertexIndex++] = Gfx::VertexTex2(p, n, uv1, uv2);
|
||||
|
||||
pos.x += size*2.0f;
|
||||
}
|
||||
|
||||
device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL);
|
||||
m_engine->AddStatisticTriangle(u-2);
|
||||
device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, &vertices[0], vertexIndex);
|
||||
m_engine->AddStatisticTriangle(vertexIndex - 2);
|
||||
}
|
||||
|
||||
free(vertex);*/
|
||||
}
|
||||
|
||||
bool Gfx::CWater::GetWater(int x, int y)
|
||||
|
|
|
@ -35,12 +35,19 @@ namespace Gfx {
|
|||
class CEngine;
|
||||
class CTerrain;
|
||||
|
||||
/**
|
||||
* \struct WaterLine
|
||||
* \brief Water strip
|
||||
*/
|
||||
struct WaterLine
|
||||
{
|
||||
//! Beginning
|
||||
//@{
|
||||
//! Beginning of line (terrain coordinates)
|
||||
short x, y;
|
||||
//! Length by x
|
||||
//@}
|
||||
//! Length in X direction (terrain coordinates)
|
||||
short len;
|
||||
//! X (1, 2) and Z coordinates (world coordinates)
|
||||
float px1, px2, pz;
|
||||
|
||||
WaterLine()
|
||||
|
@ -51,6 +58,10 @@ struct WaterLine
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct WaterVapor
|
||||
* \brief Water particle effect
|
||||
*/
|
||||
struct WaterVapor
|
||||
{
|
||||
bool used;
|
||||
|
@ -68,6 +79,10 @@ struct WaterVapor
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \enum WaterType
|
||||
* \brief Mode of water display
|
||||
*/
|
||||
enum WaterType
|
||||
{
|
||||
//! No water
|
||||
|
@ -82,7 +97,19 @@ enum WaterType
|
|||
WATER_CO = 4,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \class CWater
|
||||
* \brief Water manager/renderer
|
||||
*
|
||||
* Water is drawn where the terrain is below specified level. The mapping
|
||||
* is based on terrain coordinates - for each "brick" coordinate, the level
|
||||
* of terrain is tested. For every Y coordinate, many lines in X direction
|
||||
* are created (WaterLines).
|
||||
*
|
||||
* There are two parts of drawing process: drawing the background image
|
||||
* blocking the normal sky layer and drawing the surface of water.
|
||||
* The surface is drawn with texture, so with proper texture it can be lava.
|
||||
*/
|
||||
class CWater
|
||||
{
|
||||
public:
|
||||
|
|
Loading…
Reference in New Issue