Use CText for virus particle rendering

As suggested by @RaptorParkowsky on Trello - https://trello.com/c/56MszsWA/66-texture-remastering-checklist
master
krzys-h 2015-08-07 13:24:45 +02:00
parent 36254080bf
commit 4d5b4c47a2
7 changed files with 101 additions and 50 deletions

2
data

@ -1 +1 @@
Subproject commit 96ebb502c539bab8e360777c87db95d9cfcb7fc5
Subproject commit 363d38235e18b0db0a909dca5f8ffa1fe4825205

View File

@ -2083,6 +2083,29 @@ void CEngine::SetState(int state, const Color& color)
m_device->SetTextureEnabled(0, true);
m_device->SetTextureStageParams(0, params);
}
else if (state & ENG_RSTATE_TTEXTURE_ALPHA) // texture with alpha channel?
{
m_device->SetRenderState(RENDER_STATE_FOG, false);
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, true);
m_device->SetAlphaTestFunc(COMP_FUNC_GREATER, 0.0f);
m_device->SetRenderState(RENDER_STATE_BLENDING, true);
m_device->SetBlendFunc(BLEND_DST_COLOR, BLEND_INV_SRC_ALPHA);
TextureStageParams params;
params.colorOperation = TEX_MIX_OPER_MODULATE;
params.colorArg1 = TEX_MIX_ARG_SRC_COLOR;
params.colorArg2 = TEX_MIX_ARG_TEXTURE;
params.alphaOperation = TEX_MIX_OPER_MODULATE;
params.alphaArg1 = TEX_MIX_ARG_TEXTURE;
params.alphaArg2 = TEX_MIX_ARG_FACTOR;
params.factor = color;
m_device->SetTextureEnabled(0, true);
m_device->SetTextureStageParams(0, params);
}
else // normal ?
{
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, false);

View File

@ -128,7 +128,9 @@ enum EngineRenderState
//! Only opaque texture, no blending, etc.
ENG_RSTATE_OPAQUE_TEXTURE = (1<<19),
//! Only opaque color, no texture, blending, etc.
ENG_RSTATE_OPAQUE_COLOR = (1<<20)
ENG_RSTATE_OPAQUE_COLOR = (1<<20),
//! Texture using alpha channel
ENG_RSTATE_TTEXTURE_ALPHA = (1<<21)
};

View File

@ -28,6 +28,7 @@
#include "graphics/engine/engine.h"
#include "graphics/engine/terrain.h"
#include "graphics/engine/text.h"
#include "graphics/engine/water.h"
#include "math/geometry.h"
@ -295,8 +296,11 @@ int CParticle::CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point
type == PARTISMOKE2 ||
type == PARTISMOKE3 ||
type == PARTIBLOOD ||
type == PARTIBLOODM ||
type == PARTIVIRUS1 ||
type == PARTIBLOODM )
{
t = 4; // effect03 (ENG_RSTATE_TTEXTURE_WHITE)
}
if ( type == PARTIVIRUS1 ||
type == PARTIVIRUS2 ||
type == PARTIVIRUS3 ||
type == PARTIVIRUS4 ||
@ -307,7 +311,7 @@ int CParticle::CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point
type == PARTIVIRUS9 ||
type == PARTIVIRUS10 )
{
t = 4; // text (D3DSTATETTw)
t = 5; // text render
}
if (t >= MAXPARTITYPE) return -1;
if (t == -1) return -1;
@ -1799,53 +1803,43 @@ void CParticle::FrameParticle(float rTime)
if (m_particle[i].type == PARTIVIRUS1) // A ?
{
ts.x = 0.0f/256.0f; ts.y = 19.0f/256.0f;
ti.x = 10.0f/256.0f; ti.y = 30.0f/256.0f;
m_particle[i].text = 'A';
}
if (m_particle[i].type == PARTIVIRUS2) // C ?
{
ts.x = 19.0f/256.0f; ts.y = 19.0f/256.0f;
ti.x = 28.0f/256.0f; ti.y = 30.0f/256.0f;
m_particle[i].text = 'C';
}
if (m_particle[i].type == PARTIVIRUS3) // E ?
{
ts.x = 36.0f/256.0f; ts.y = 19.0f/256.0f;
ti.x = 45.0f/256.0f; ti.y = 30.0f/256.0f;
m_particle[i].text = 'E';
}
if (m_particle[i].type == PARTIVIRUS4) // N ?
{
ts.x = 110.0f/256.0f; ts.y = 19.0f/256.0f;
ti.x = 120.0f/256.0f; ti.y = 30.0f/256.0f;
m_particle[i].text = 'N';
}
if (m_particle[i].type == PARTIVIRUS5) // R ?
{
ts.x = 148.0f/256.0f; ts.y = 19.0f/256.0f;
ti.x = 158.0f/256.0f; ti.y = 30.0f/256.0f;
m_particle[i].text = 'R';
}
if (m_particle[i].type == PARTIVIRUS6) // T ?
{
ts.x = 166.0f/256.0f; ts.y = 19.0f/256.0f;
ti.x = 175.0f/256.0f; ti.y = 30.0f/256.0f;
m_particle[i].text = 'T';
}
if (m_particle[i].type == PARTIVIRUS7) // 0 ?
{
ts.x = 90.0f/256.0f; ts.y = 2.0f/256.0f;
ti.x = 98.0f/256.0f; ti.y = 13.0f/256.0f;
m_particle[i].text = '0';
}
if (m_particle[i].type == PARTIVIRUS8) // 2 ?
{
ts.x = 103.0f/256.0f; ts.y = 2.0f/256.0f;
ti.x = 111.0f/256.0f; ti.y = 13.0f/256.0f;
m_particle[i].text = '2';
}
if (m_particle[i].type == PARTIVIRUS9) // 5 ?
{
ts.x = 125.0f/256.0f; ts.y = 2.0f/256.0f;
ti.x = 132.0f/256.0f; ti.y = 13.0f/256.0f;
m_particle[i].text = '5';
}
if (m_particle[i].type == PARTIVIRUS10) // 9 ?
{
ts.x = 153.0f/256.0f; ts.y = 2.0f/256.0f;
ti.x = 161.0f/256.0f; ti.y = 13.0f/256.0f;
m_particle[i].text = '9';
}
}
@ -2861,7 +2855,7 @@ void CParticle::DrawParticleNorm(int i)
vertex[2] = Vertex(corner[3], n, Math::Point(m_particle[i].texSup.x, m_particle[i].texInf.y));
vertex[3] = Vertex(corner[2], n, Math::Point(m_particle[i].texInf.x, m_particle[i].texInf.y));
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4, m_particle[i].color);
m_engine->AddStatisticTriangle(2);
}
}
@ -3367,6 +3361,22 @@ void CParticle::DrawParticleCylinder(int i)
m_engine->SetState(ENG_RSTATE_TTEXTURE_BLACK, IntensityToColor(m_particle[i].intensity));
}
void CParticle::DrawParticleText(int i)
{
CharTexture tex = m_engine->GetText()->GetCharTexture(static_cast<UTF8Char>(m_particle[i].text), FONT_COLOBOT, FONT_SIZE_BIG*2.0f);
if (tex.id == 0) return;
m_device->SetTexture(0, tex.id);
m_engine->SetState(ENG_RSTATE_TTEXTURE_ALPHA, IntensityToColor(m_particle[i].intensity));
m_particle[i].texSup.x = 0.0f;
m_particle[i].texSup.y = 0.0f;
m_particle[i].texInf.x = static_cast<float>(tex.charSize.x) / static_cast<float>(tex.texSize.x);
m_particle[i].texInf.y = static_cast<float>(tex.charSize.y) / static_cast<float>(tex.texSize.y);
m_particle[i].color = Color(0.0f, 0.0f, 0.0f);
DrawParticleNorm(i);
}
void CParticle::DrawParticleWheel(int i)
{
float dist = Math::DistanceProjected(m_engine->GetEyePt(), m_wheelTrace[i].pos[0]);
@ -3554,7 +3564,7 @@ void CParticle::DrawParticle(int sheet)
bool loadTexture = false;
int state;
if (t == 4) state = ENG_RSTATE_TTEXTURE_WHITE; // text.png
if (t == 4) state = ENG_RSTATE_TTEXTURE_WHITE; // effect03.png
else state = ENG_RSTATE_TTEXTURE_BLACK; // effect[00..02].png
m_engine->SetState(state);
@ -3564,7 +3574,7 @@ void CParticle::DrawParticle(int sheet)
if (!m_particle[i].used) continue;
if (m_particle[i].sheet != sheet) continue;
if (!loadTexture)
if (!loadTexture && t != 5)
{
std::string name;
NameParticle(name, t);
@ -3607,6 +3617,11 @@ void CParticle::DrawParticle(int sheet)
{
DrawParticleCylinder(i);
}
else if ( m_particle[i].type >= PARTIVIRUS1 &&
m_particle[i].type <= PARTIVIRUS10 )
{
DrawParticleText(i);
}
else // normal?
{
DrawParticleNorm(i);

View File

@ -40,7 +40,7 @@ namespace Gfx
{
const short MAXPARTICULE = 500;
const short MAXPARTITYPE = 5;
const short MAXPARTITYPE = 6;
const short MAXTRACK = 100;
const short MAXTRACKLEN = 10;
const short MAXPARTIFOG = 100;
@ -214,6 +214,8 @@ struct Particle
CObject* objFather = nullptr; // father object (for example reactor)
short objRank = 0; // rank of the object, or -1
short trackRank = 0; // rank of the drag
char text = 0;
Color color = Color(1.0f, 1.0f, 1.0f, 1.0f);
};
struct Track
@ -337,6 +339,8 @@ protected:
void DrawParticleSphere(int i);
//! Draws a cylindrical particle
void DrawParticleCylinder(int i);
//! Draws a text particle
void DrawParticleText(int i);
//! Draws a tire mark
void DrawParticleWheel(int i);
//! Seeks if an object collided with a bullet

View File

@ -895,11 +895,6 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::P
}
else
{
CachedFont* cf = GetOrOpenFont(font, size);
if (cf == nullptr)
return;
int width = 1;
if (ch.c1 > 0 && ch.c1 < 32)
{
@ -909,21 +904,7 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::P
ch = TranslateSpecialChar(ch.c1);
}
auto it = cf->cache.find(ch);
CharTexture tex;
if (it != cf->cache.end())
{
tex = (*it).second;
}
else
{
tex = CreateCharTexture(ch, cf);
if (tex.id == 0) // invalid
return;
cf->cache[ch] = tex;
}
CharTexture tex = GetCharTexture(ch, font, size);
Math::Point p1(pos.x, pos.y + tex.charSize.y - tex.texSize.y);
Math::Point p2(pos.x + tex.texSize.x, pos.y + tex.charSize.y);
@ -1051,5 +1032,30 @@ CharTexture CText::CreateCharTexture(UTF8Char ch, CachedFont* font)
return texture;
}
CharTexture CText::GetCharTexture(UTF8Char ch, FontType font, float size)
{
CachedFont* cf = GetOrOpenFont(font, size);
if (cf == nullptr)
return CharTexture();
auto it = cf->cache.find(ch);
CharTexture tex;
if (it != cf->cache.end())
{
tex = (*it).second;
}
else
{
tex = CreateCharTexture(ch, cf);
if (tex.id == 0) // invalid
return CharTexture();
cf->cache[ch] = tex;
}
return tex;
}
} // namespace Gfx

View File

@ -315,6 +315,8 @@ public:
UTF8Char TranslateSpecialChar(int specialChar);
CharTexture GetCharTexture(UTF8Char ch, FontType font, float size);
protected:
CachedFont* GetOrOpenFont(FontType type, float size);
CharTexture CreateCharTexture(UTF8Char ch, CachedFont* font);
@ -346,4 +348,3 @@ protected:
} // namespace Gfx