ddnet/src/game/client/render.cpp

653 lines
20 KiB
C++
Raw Normal View History

2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
2008-01-12 17:09:00 +00:00
#include <math.h>
2010-05-29 07:25:38 +00:00
#include <base/math.h>
2010-05-29 07:25:38 +00:00
#include <engine/shared/config.h>
#include <engine/graphics.h>
#include <engine/map.h>
#include <game/generated/client_data.h>
#include <game/generated/protocol.h>
#include <game/layers.h>
#include "animstate.h"
#include "render.h"
2008-01-12 17:09:00 +00:00
2010-05-29 07:25:38 +00:00
static float gs_SpriteWScale;
static float gs_SpriteHScale;
2009-10-27 14:38:53 +00:00
/*
static void layershot_begin()
{
if(!config.cl_layershot)
return;
2009-10-27 14:38:53 +00:00
Graphics()->Clear(0,0,0);
}
static void layershot_end()
{
if(!config.cl_layershot)
return;
char buf[256];
str_format(buf, sizeof(buf), "screenshots/layers_%04d.png", config.cl_layershot);
gfx_screenshot_direct(buf);
config.cl_layershot++;
}*/
void CRenderTools::Init(IGraphics *pGraphics, CUI *pUI)
{
m_pGraphics = pGraphics;
m_pUI = pUI;
m_TeeQuadContainerIndex = Graphics()->CreateQuadContainer();
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
SelectSprite(SPRITE_TEE_BODY, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f, false);
SelectSprite(SPRITE_TEE_BODY_OUTLINE, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f, false);
SelectSprite(SPRITE_TEE_EYE_PAIN, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f*0.4f, false);
SelectSprite(SPRITE_TEE_EYE_HAPPY, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f*0.4f, false);
SelectSprite(SPRITE_TEE_EYE_SURPRISE, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f*0.4f, false);
SelectSprite(SPRITE_TEE_EYE_ANGRY, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f*0.4f, false);
SelectSprite(SPRITE_TEE_EYE_NORMAL, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f*0.4f, false);
SelectSprite(SPRITE_TEE_FOOT_OUTLINE, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f);
SelectSprite(SPRITE_TEE_FOOT, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f);
}
2011-06-01 18:19:12 +00:00
void CRenderTools::SelectSprite(CDataSprite *pSpr, int Flags, int sx, int sy)
2008-01-12 17:09:00 +00:00
{
2010-05-29 07:25:38 +00:00
int x = pSpr->m_X+sx;
int y = pSpr->m_Y+sy;
int w = pSpr->m_W;
int h = pSpr->m_H;
int cx = pSpr->m_pSet->m_Gridx;
int cy = pSpr->m_pSet->m_Gridy;
2008-01-12 17:09:00 +00:00
float f = sqrtf(h*h + w*w);
2010-05-29 07:25:38 +00:00
gs_SpriteWScale = w/f;
gs_SpriteHScale = h/f;
float x1 = x/(float)cx + 0.5f/(float)(cx*32);
float x2 = (x+w)/(float)cx - 0.5f/(float)(cx*32);
float y1 = y/(float)cy + 0.5f/(float)(cy*32);
float y2 = (y+h)/(float)cy - 0.5f/(float)(cy*32);
2010-05-29 07:25:38 +00:00
float Temp = 0;
2008-01-12 17:09:00 +00:00
2010-05-29 07:25:38 +00:00
if(Flags&SPRITE_FLAG_FLIP_Y)
2008-01-12 17:09:00 +00:00
{
2010-05-29 07:25:38 +00:00
Temp = y1;
2008-01-12 17:09:00 +00:00
y1 = y2;
2010-05-29 07:25:38 +00:00
y2 = Temp;
2008-01-12 17:09:00 +00:00
}
2010-05-29 07:25:38 +00:00
if(Flags&SPRITE_FLAG_FLIP_X)
2008-01-12 17:09:00 +00:00
{
2010-05-29 07:25:38 +00:00
Temp = x1;
2008-01-12 17:09:00 +00:00
x1 = x2;
2010-05-29 07:25:38 +00:00
x2 = Temp;
2008-01-12 17:09:00 +00:00
}
2009-10-27 14:38:53 +00:00
Graphics()->QuadsSetSubset(x1, y1, x2, y2);
2008-01-12 17:09:00 +00:00
}
2010-05-29 07:25:38 +00:00
void CRenderTools::SelectSprite(int Id, int Flags, int sx, int sy)
2008-01-12 17:09:00 +00:00
{
2011-09-06 13:27:56 +00:00
if(Id < 0 || Id >= g_pData->m_NumSprites)
2008-01-12 17:09:00 +00:00
return;
2010-05-29 07:25:38 +00:00
SelectSprite(&g_pData->m_aSprites[Id], Flags, sx, sy);
2008-01-12 17:09:00 +00:00
}
2010-05-29 07:25:38 +00:00
void CRenderTools::DrawSprite(float x, float y, float Size)
2008-01-12 17:09:00 +00:00
{
2010-05-29 07:25:38 +00:00
IGraphics::CQuadItem QuadItem(x, y, Size*gs_SpriteWScale, Size*gs_SpriteHScale);
Graphics()->QuadsDraw(&QuadItem, 1);
2008-01-12 17:09:00 +00:00
}
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float Size, bool DoSpriteScale)
{
if(DoSpriteScale)
{
IGraphics::CQuadItem QuadItem(x, y, Size*gs_SpriteWScale, Size*gs_SpriteHScale);
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
else
{
IGraphics::CQuadItem QuadItem(x, y, Size, Size);
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
}
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float Size, bool DoSpriteScale)
{
if(DoSpriteScale)
{
IGraphics::CQuadItem QuadItem(-(Size*gs_SpriteWScale) / 2.f, -(Size*gs_SpriteHScale) / 2.f, (Size*gs_SpriteWScale), (Size*gs_SpriteHScale));
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
else
{
IGraphics::CQuadItem QuadItem(-(Size) / 2.f, -(Size) / 2.f, (Size), (Size));
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
}
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float X, float Y, float Width, float Height)
{
IGraphics::CQuadItem QuadItem(X, Y, Width, Height);
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
2010-05-29 07:25:38 +00:00
void CRenderTools::DrawRoundRectExt(float x, float y, float w, float h, float r, int Corners)
2008-01-12 17:09:00 +00:00
{
2010-05-29 07:25:38 +00:00
IGraphics::CFreeformItem ArrayF[32];
int NumItems = 0;
int Num = 8;
for(int i = 0; i < Num; i+=2)
2008-01-12 17:09:00 +00:00
{
2010-05-29 07:25:38 +00:00
float a1 = i/(float)Num * pi/2;
float a2 = (i+1)/(float)Num * pi/2;
float a3 = (i+2)/(float)Num * pi/2;
float Ca1 = cosf(a1);
float Ca2 = cosf(a2);
float Ca3 = cosf(a3);
float Sa1 = sinf(a1);
float Sa2 = sinf(a2);
float Sa3 = sinf(a3);
if(Corners&1) // TL
ArrayF[NumItems++] = IGraphics::CFreeformItem(
2008-01-12 17:09:00 +00:00
x+r, y+r,
2010-05-29 07:25:38 +00:00
x+(1-Ca1)*r, y+(1-Sa1)*r,
x+(1-Ca3)*r, y+(1-Sa3)*r,
x+(1-Ca2)*r, y+(1-Sa2)*r);
2008-01-12 17:09:00 +00:00
2010-05-29 07:25:38 +00:00
if(Corners&2) // TR
ArrayF[NumItems++] = IGraphics::CFreeformItem(
2008-01-12 17:09:00 +00:00
x+w-r, y+r,
2010-05-29 07:25:38 +00:00
x+w-r+Ca1*r, y+(1-Sa1)*r,
x+w-r+Ca3*r, y+(1-Sa3)*r,
x+w-r+Ca2*r, y+(1-Sa2)*r);
2008-01-12 17:09:00 +00:00
2010-05-29 07:25:38 +00:00
if(Corners&4) // BL
ArrayF[NumItems++] = IGraphics::CFreeformItem(
2008-01-12 17:09:00 +00:00
x+r, y+h-r,
2010-05-29 07:25:38 +00:00
x+(1-Ca1)*r, y+h-r+Sa1*r,
x+(1-Ca3)*r, y+h-r+Sa3*r,
x+(1-Ca2)*r, y+h-r+Sa2*r);
2008-01-12 17:09:00 +00:00
2010-05-29 07:25:38 +00:00
if(Corners&8) // BR
ArrayF[NumItems++] = IGraphics::CFreeformItem(
2008-01-12 17:09:00 +00:00
x+w-r, y+h-r,
2010-05-29 07:25:38 +00:00
x+w-r+Ca1*r, y+h-r+Sa1*r,
x+w-r+Ca3*r, y+h-r+Sa3*r,
x+w-r+Ca2*r, y+h-r+Sa2*r);
2008-01-12 17:09:00 +00:00
}
2010-05-29 07:25:38 +00:00
Graphics()->QuadsDrawFreeform(ArrayF, NumItems);
IGraphics::CQuadItem ArrayQ[9];
NumItems = 0;
ArrayQ[NumItems++] = IGraphics::CQuadItem(x+r, y+r, w-r*2, h-r*2); // center
ArrayQ[NumItems++] = IGraphics::CQuadItem(x+r, y, w-r*2, r); // top
ArrayQ[NumItems++] = IGraphics::CQuadItem(x+r, y+h-r, w-r*2, r); // bottom
ArrayQ[NumItems++] = IGraphics::CQuadItem(x, y+r, r, h-r*2); // left
ArrayQ[NumItems++] = IGraphics::CQuadItem(x+w-r, y+r, r, h-r*2); // right
2010-05-29 07:25:38 +00:00
if(!(Corners&1)) ArrayQ[NumItems++] = IGraphics::CQuadItem(x, y, r, r); // TL
if(!(Corners&2)) ArrayQ[NumItems++] = IGraphics::CQuadItem(x+w, y, -r, r); // TR
if(!(Corners&4)) ArrayQ[NumItems++] = IGraphics::CQuadItem(x, y+h, r, -r); // BL
if(!(Corners&8)) ArrayQ[NumItems++] = IGraphics::CQuadItem(x+w, y+h, -r, -r); // BR
Graphics()->QuadsDrawTL(ArrayQ, NumItems);
2008-01-12 17:09:00 +00:00
}
void CRenderTools::DrawRoundRectExt4(float x, float y, float w, float h, vec4 ColorTopLeft, vec4 ColorTopRight, vec4 ColorBottomLeft, vec4 ColorBottomRight, float r, int Corners)
{
int Num = 8;
for(int i = 0; i < Num; i+=2)
{
float a1 = i/(float)Num * pi/2;
float a2 = (i+1)/(float)Num * pi/2;
float a3 = (i+2)/(float)Num * pi/2;
float Ca1 = cosf(a1);
float Ca2 = cosf(a2);
float Ca3 = cosf(a3);
float Sa1 = sinf(a1);
float Sa2 = sinf(a2);
float Sa3 = sinf(a3);
if(Corners&1) // TL
{
Graphics()->SetColor(ColorTopLeft.r, ColorTopLeft.g, ColorTopLeft.b, ColorTopLeft.a);
IGraphics::CFreeformItem ItemF = IGraphics::CFreeformItem(
x+r, y+r,
x+(1-Ca1)*r, y+(1-Sa1)*r,
x+(1-Ca3)*r, y+(1-Sa3)*r,
x+(1-Ca2)*r, y+(1-Sa2)*r);
Graphics()->QuadsDrawFreeform(&ItemF, 1);
}
if(Corners&2) // TR
{
Graphics()->SetColor(ColorTopRight.r, ColorTopRight.g, ColorTopRight.b, ColorTopRight.a);
IGraphics::CFreeformItem ItemF = IGraphics::CFreeformItem(
x+w-r, y+r,
x+w-r+Ca1*r, y+(1-Sa1)*r,
x+w-r+Ca3*r, y+(1-Sa3)*r,
x+w-r+Ca2*r, y+(1-Sa2)*r);
Graphics()->QuadsDrawFreeform(&ItemF, 1);
}
if(Corners&4) // BL
{
Graphics()->SetColor(ColorBottomLeft.r, ColorBottomLeft.g, ColorBottomLeft.b, ColorBottomLeft.a);
IGraphics::CFreeformItem ItemF = IGraphics::CFreeformItem(
x+r, y+h-r,
x+(1-Ca1)*r, y+h-r+Sa1*r,
x+(1-Ca3)*r, y+h-r+Sa3*r,
x+(1-Ca2)*r, y+h-r+Sa2*r);
Graphics()->QuadsDrawFreeform(&ItemF, 1);
}
if(Corners&8) // BR
{
Graphics()->SetColor(ColorBottomRight.r, ColorBottomRight.g, ColorBottomRight.b, ColorBottomRight.a);
IGraphics::CFreeformItem ItemF = IGraphics::CFreeformItem(
x+w-r, y+h-r,
x+w-r+Ca1*r, y+h-r+Sa1*r,
x+w-r+Ca3*r, y+h-r+Sa3*r,
x+w-r+Ca2*r, y+h-r+Sa2*r);
Graphics()->QuadsDrawFreeform(&ItemF, 1);
}
if(Corners&16) // ITL
{
Graphics()->SetColor(ColorTopLeft.r, ColorTopLeft.g, ColorTopLeft.b, ColorTopLeft.a);
IGraphics::CFreeformItem ItemF = IGraphics::CFreeformItem(
x, y,
x+(1-Ca1)*r, y-r+Sa1*r,
x+(1-Ca3)*r, y-r+Sa3*r,
x+(1-Ca2)*r, y-r+Sa2*r);
Graphics()->QuadsDrawFreeform(&ItemF, 1);
}
if(Corners&32) // ITR
{
Graphics()->SetColor(ColorTopRight.r, ColorTopRight.g, ColorTopRight.b, ColorTopRight.a);
IGraphics::CFreeformItem ItemF = IGraphics::CFreeformItem(
x+w, y,
x+w-r+Ca1*r, y-r+Sa1*r,
x+w-r+Ca3*r, y-r+Sa3*r,
x+w-r+Ca2*r, y-r+Sa2*r);
Graphics()->QuadsDrawFreeform(&ItemF, 1);
}
if(Corners&64) // IBL
{
Graphics()->SetColor(ColorBottomLeft.r, ColorBottomLeft.g, ColorBottomLeft.b, ColorBottomLeft.a);
IGraphics::CFreeformItem ItemF = IGraphics::CFreeformItem(
x, y+h,
x+(1-Ca1)*r, y+h+(1-Sa1)*r,
x+(1-Ca3)*r, y+h+(1-Sa3)*r,
x+(1-Ca2)*r, y+h+(1-Sa2)*r);
Graphics()->QuadsDrawFreeform(&ItemF, 1);
}
if(Corners&128) // IBR
{
Graphics()->SetColor(ColorBottomRight.r, ColorBottomRight.g, ColorBottomRight.b, ColorBottomRight.a);
IGraphics::CFreeformItem ItemF = IGraphics::CFreeformItem(
x+w, y+h,
x+w-r+Ca1*r, y+h+(1-Sa1)*r,
x+w-r+Ca3*r, y+h+(1-Sa3)*r,
x+w-r+Ca2*r, y+h+(1-Sa2)*r);
Graphics()->QuadsDrawFreeform(&ItemF, 1);
}
}
Graphics()->SetColor4(ColorTopLeft, ColorTopRight, ColorBottomLeft, ColorBottomRight);
IGraphics::CQuadItem ItemQ = IGraphics::CQuadItem(x+r, y+r, w-r*2, h-r*2); // center
Graphics()->QuadsDrawTL(&ItemQ, 1);
Graphics()->SetColor4(ColorTopLeft, ColorTopRight, ColorTopLeft, ColorTopRight);
ItemQ = IGraphics::CQuadItem(x+r, y, w-r*2, r); // top
Graphics()->QuadsDrawTL(&ItemQ, 1);
Graphics()->SetColor4(ColorBottomLeft, ColorBottomRight, ColorBottomLeft, ColorBottomRight);
ItemQ = IGraphics::CQuadItem(x+r, y+h-r, w-r*2, r); // bottom
Graphics()->QuadsDrawTL(&ItemQ, 1);
Graphics()->SetColor4(ColorTopLeft, ColorTopLeft, ColorBottomLeft, ColorBottomLeft);
ItemQ = IGraphics::CQuadItem(x, y+r, r, h-r*2); // left
Graphics()->QuadsDrawTL(&ItemQ, 1);
Graphics()->SetColor4(ColorTopRight, ColorTopRight, ColorBottomRight, ColorBottomRight);
ItemQ = IGraphics::CQuadItem(x+w-r, y+r, r, h-r*2); // right
Graphics()->QuadsDrawTL(&ItemQ, 1);
if(!(Corners&1))
{
Graphics()->SetColor(ColorTopLeft.r, ColorTopLeft.g, ColorTopLeft.b, ColorTopLeft.a);
IGraphics::CQuadItem ItemQ = IGraphics::CQuadItem(x, y, r, r); // TL
Graphics()->QuadsDrawTL(&ItemQ, 1);
}
if(!(Corners&2))
{
Graphics()->SetColor(ColorTopRight.r, ColorTopRight.g, ColorTopRight.b, ColorTopRight.a);
IGraphics::CQuadItem ItemQ = IGraphics::CQuadItem(x+w, y, -r, r); // TR
Graphics()->QuadsDrawTL(&ItemQ, 1);
}
if(!(Corners&4))
{
Graphics()->SetColor(ColorBottomLeft.r, ColorBottomLeft.g, ColorBottomLeft.b, ColorBottomLeft.a);
IGraphics::CQuadItem ItemQ = IGraphics::CQuadItem(x, y+h, r, -r); // BL
Graphics()->QuadsDrawTL(&ItemQ, 1);
}
if(!(Corners&8))
{
Graphics()->SetColor(ColorBottomRight.r, ColorBottomRight.g, ColorBottomRight.b, ColorBottomRight.a);
IGraphics::CQuadItem ItemQ = IGraphics::CQuadItem(x+w, y+h, -r, -r); // BR
Graphics()->QuadsDrawTL(&ItemQ, 1);
}
}
int CRenderTools::CreateRoundRectQuadContainer(float x, float y, float w, float h, float r, int Corners)
{
int ContainerIndex = Graphics()->CreateQuadContainer();
IGraphics::CFreeformItem ArrayF[32];
int NumItems = 0;
int Num = 8;
for(int i = 0; i < Num; i += 2)
{
float a1 = i / (float)Num * pi / 2;
float a2 = (i + 1) / (float)Num * pi / 2;
float a3 = (i + 2) / (float)Num * pi / 2;
float Ca1 = cosf(a1);
float Ca2 = cosf(a2);
float Ca3 = cosf(a3);
float Sa1 = sinf(a1);
float Sa2 = sinf(a2);
float Sa3 = sinf(a3);
if(Corners & 1) // TL
ArrayF[NumItems++] = IGraphics::CFreeformItem(
x + r, y + r,
x + (1 - Ca1)*r, y + (1 - Sa1)*r,
x + (1 - Ca3)*r, y + (1 - Sa3)*r,
x + (1 - Ca2)*r, y + (1 - Sa2)*r);
if(Corners & 2) // TR
ArrayF[NumItems++] = IGraphics::CFreeformItem(
x + w - r, y + r,
x + w - r + Ca1 * r, y + (1 - Sa1)*r,
x + w - r + Ca3 * r, y + (1 - Sa3)*r,
x + w - r + Ca2 * r, y + (1 - Sa2)*r);
if(Corners & 4) // BL
ArrayF[NumItems++] = IGraphics::CFreeformItem(
x + r, y + h - r,
x + (1 - Ca1)*r, y + h - r + Sa1 * r,
x + (1 - Ca3)*r, y + h - r + Sa3 * r,
x + (1 - Ca2)*r, y + h - r + Sa2 * r);
if(Corners & 8) // BR
ArrayF[NumItems++] = IGraphics::CFreeformItem(
x + w - r, y + h - r,
x + w - r + Ca1 * r, y + h - r + Sa1 * r,
x + w - r + Ca3 * r, y + h - r + Sa3 * r,
x + w - r + Ca2 * r, y + h - r + Sa2 * r);
}
Graphics()->QuadContainerAddQuads(ContainerIndex, ArrayF, NumItems);
IGraphics::CQuadItem ArrayQ[9];
NumItems = 0;
ArrayQ[NumItems++] = IGraphics::CQuadItem(x + r, y + r, w - r * 2, h - r * 2); // center
ArrayQ[NumItems++] = IGraphics::CQuadItem(x + r, y, w - r * 2, r); // top
ArrayQ[NumItems++] = IGraphics::CQuadItem(x + r, y + h - r, w - r * 2, r); // bottom
ArrayQ[NumItems++] = IGraphics::CQuadItem(x, y + r, r, h - r * 2); // left
ArrayQ[NumItems++] = IGraphics::CQuadItem(x + w - r, y + r, r, h - r * 2); // right
if(!(Corners & 1)) ArrayQ[NumItems++] = IGraphics::CQuadItem(x, y, r, r); // TL
if(!(Corners & 2)) ArrayQ[NumItems++] = IGraphics::CQuadItem(x + w, y, -r, r); // TR
if(!(Corners & 4)) ArrayQ[NumItems++] = IGraphics::CQuadItem(x, y + h, r, -r); // BL
if(!(Corners & 8)) ArrayQ[NumItems++] = IGraphics::CQuadItem(x + w, y + h, -r, -r); // BR
Graphics()->QuadContainerAddQuads(ContainerIndex, ArrayQ, NumItems);
return ContainerIndex;
}
2010-05-29 07:25:38 +00:00
void CRenderTools::DrawRoundRect(float x, float y, float w, float h, float r)
2008-01-12 17:09:00 +00:00
{
2010-05-29 07:25:38 +00:00
DrawRoundRectExt(x,y,w,h,r,0xf);
2008-01-12 17:09:00 +00:00
}
2019-04-26 12:06:32 +00:00
void CRenderTools::DrawUIRect(const CUIRect *r, ColorRGBA Color, int Corners, float Rounding)
2008-01-17 23:09:49 +00:00
{
Graphics()->TextureClear();
2009-10-27 14:38:53 +00:00
// TODO: FIX US
Graphics()->QuadsBegin();
2019-04-26 22:11:15 +00:00
Graphics()->SetColor(Color);
2010-05-29 07:25:38 +00:00
DrawRoundRectExt(r->x,r->y,r->w,r->h,Rounding*UI()->Scale(), Corners);
2009-10-27 14:38:53 +00:00
Graphics()->QuadsEnd();
2008-01-17 23:09:49 +00:00
}
void CRenderTools::DrawUIRect4(const CUIRect *r, vec4 ColorTopLeft, vec4 ColorTopRight, vec4 ColorBottomLeft, vec4 ColorBottomRight, int Corners, float Rounding)
{
Graphics()->TextureClear();
Graphics()->QuadsBegin();
DrawRoundRectExt4(r->x,r->y,r->w,r->h,ColorTopLeft,ColorTopRight,ColorBottomLeft,ColorBottomRight,Rounding, Corners);
Graphics()->QuadsEnd();
}
void CRenderTools::DrawCircle(float x, float y, float r, int Segments)
{
IGraphics::CFreeformItem Array[32];
int NumItems = 0;
float FSegments = (float)Segments;
for(int i = 0; i < Segments; i+=2)
{
float a1 = i/FSegments * 2*pi;
float a2 = (i+1)/FSegments * 2*pi;
float a3 = (i+2)/FSegments * 2*pi;
float Ca1 = cosf(a1);
float Ca2 = cosf(a2);
float Ca3 = cosf(a3);
float Sa1 = sinf(a1);
float Sa2 = sinf(a2);
float Sa3 = sinf(a3);
Array[NumItems++] = IGraphics::CFreeformItem(
x, y,
x+Ca1*r, y+Sa1*r,
x+Ca3*r, y+Sa3*r,
x+Ca2*r, y+Sa2*r);
if(NumItems == 32)
{
Graphics()->QuadsDrawFreeform(Array, 32);
NumItems = 0;
}
}
if(NumItems)
Graphics()->QuadsDrawFreeform(Array, NumItems);
}
2019-04-21 16:20:53 +00:00
void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote, vec2 Dir, vec2 Pos, float Alpha)
2008-01-12 17:09:00 +00:00
{
2010-05-29 07:25:38 +00:00
vec2 Direction = Dir;
vec2 Position = Pos;
2008-01-12 17:09:00 +00:00
2009-10-27 14:38:53 +00:00
//Graphics()->TextureSet(data->images[IMAGE_CHAR_DEFAULT].id);
2010-05-29 07:25:38 +00:00
Graphics()->TextureSet(pInfo->m_Texture);
2008-01-12 17:09:00 +00:00
// first pass we draw the outline
// second pass we draw the filling
for(int p = 0; p < 2; p++)
{
2010-05-29 07:25:38 +00:00
int OutLine = p==0 ? 1 : 0;
2008-01-12 17:09:00 +00:00
for(int f = 0; f < 2; f++)
{
2010-05-29 07:25:38 +00:00
float AnimScale = pInfo->m_Size * 1.0f/64.0f;
float BaseSize = pInfo->m_Size;
2008-01-12 17:09:00 +00:00
if(f == 1)
{
2010-05-29 07:25:38 +00:00
Graphics()->QuadsSetRotation(pAnim->GetBody()->m_Angle*pi*2);
2008-01-12 17:09:00 +00:00
// draw body
2019-04-21 16:20:53 +00:00
Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, Alpha);
2010-05-29 07:25:38 +00:00
vec2 BodyPos = Position + vec2(pAnim->GetBody()->m_X, pAnim->GetBody()->m_Y)*AnimScale;
2019-07-08 21:08:42 +00:00
float BodySize = g_Config.m_ClFatSkins ? BaseSize * 1.3f : BaseSize;
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, OutLine, BodyPos.x, BodyPos.y, BodySize / 64.f, BodySize / 64.f);
2008-01-12 17:09:00 +00:00
// draw eyes
if(p == 1)
{
int QuadOffset = 2;
int EyeQuadOffset = 0;
2010-05-29 07:25:38 +00:00
switch (Emote)
2008-01-12 17:09:00 +00:00
{
case EMOTE_PAIN:
EyeQuadOffset = 0;
2008-01-12 17:09:00 +00:00
break;
case EMOTE_HAPPY:
EyeQuadOffset = 1;
2008-01-12 17:09:00 +00:00
break;
case EMOTE_SURPRISE:
EyeQuadOffset = 2;
2008-01-12 17:09:00 +00:00
break;
case EMOTE_ANGRY:
EyeQuadOffset = 3;
2008-01-12 17:09:00 +00:00
break;
default:
EyeQuadOffset = 4;
2008-01-12 17:09:00 +00:00
break;
}
2010-05-29 07:25:38 +00:00
float EyeScale = BaseSize*0.40f;
float h = Emote == EMOTE_BLINK ? BaseSize*0.15f : EyeScale;
float EyeSeparation = (0.075f - 0.010f*absolute(Direction.x))*BaseSize;
vec2 Offset = vec2(Direction.x*0.125f, -0.05f+Direction.y*0.10f)*BaseSize;
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset + EyeQuadOffset, BodyPos.x - EyeSeparation + Offset.x, BodyPos.y + Offset.y, EyeScale / (64.f*0.4f), h / (64.f*0.4f));
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset + EyeQuadOffset, BodyPos.x + EyeSeparation + Offset.x, BodyPos.y + Offset.y, -EyeScale / (64.f*0.4f), h / (64.f*0.4f));
2008-01-12 17:09:00 +00:00
}
}
// draw feet
2011-06-01 18:19:12 +00:00
CAnimKeyframe *pFoot = f ? pAnim->GetFrontFoot() : pAnim->GetBackFoot();
2008-01-12 17:09:00 +00:00
2010-05-29 07:25:38 +00:00
float w = BaseSize;
float h = BaseSize/2;
2008-01-12 17:09:00 +00:00
int QuadOffset = 7;
2010-05-29 07:25:38 +00:00
Graphics()->QuadsSetRotation(pFoot->m_Angle*pi*2);
2010-05-29 07:25:38 +00:00
bool Indicate = !pInfo->m_GotAirJump && g_Config.m_ClAirjumpindicator;
2008-03-23 11:57:25 +00:00
float cs = 1.0f; // color scale
if(!OutLine)
2008-03-23 11:57:25 +00:00
{
++QuadOffset;
2010-05-29 07:25:38 +00:00
if(Indicate)
2008-03-23 11:57:25 +00:00
cs = 0.5f;
}
2019-05-03 18:37:17 +00:00
Graphics()->SetColor(pInfo->m_ColorFeet.r*cs, pInfo->m_ColorFeet.g*cs, pInfo->m_ColorFeet.b*cs, Alpha);
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset, Position.x + pFoot->m_X*AnimScale, Position.y + pFoot->m_Y*AnimScale, w / 64.f, h / 32.f);
2008-01-12 17:09:00 +00:00
}
}
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
Graphics()->QuadsSetRotation(0);
2008-01-12 17:09:00 +00:00
}
void CRenderTools::CalcScreenParams(float Aspect, float Zoom, float *w, float *h)
2008-01-12 17:09:00 +00:00
{
const float Amount = 1150 * 1000;
const float WMax = 1500;
const float HMax = 1050;
2010-05-29 07:25:38 +00:00
float f = sqrtf(Amount) / sqrtf(Aspect);
*w = f*Aspect;
2008-01-12 17:09:00 +00:00
*h = f;
2008-01-12 17:09:00 +00:00
// limit the view
2010-05-29 07:25:38 +00:00
if(*w > WMax)
2008-01-12 17:09:00 +00:00
{
2010-05-29 07:25:38 +00:00
*w = WMax;
*h = *w/Aspect;
2008-01-12 17:09:00 +00:00
}
2010-05-29 07:25:38 +00:00
if(*h > HMax)
2008-01-12 17:09:00 +00:00
{
2010-05-29 07:25:38 +00:00
*h = HMax;
*w = *h*Aspect;
2008-01-12 17:09:00 +00:00
}
*w *= Zoom;
*h *= Zoom;
2008-01-12 17:09:00 +00:00
}
2010-05-29 07:25:38 +00:00
void CRenderTools::MapscreenToWorld(float CenterX, float CenterY, float ParallaxX, float ParallaxY,
float OffsetX, float OffsetY, float Aspect, float Zoom, float *pPoints)
2008-01-12 17:09:00 +00:00
{
2010-05-29 07:25:38 +00:00
float Width, Height;
CalcScreenParams(Aspect, Zoom, &Width, &Height);
CenterX *= ParallaxX/100.0f;
CenterY *= ParallaxY/100.0f;
2010-05-29 07:25:38 +00:00
pPoints[0] = OffsetX+CenterX-Width/2;
pPoints[1] = OffsetY+CenterY-Height/2;
2010-08-05 18:55:51 +00:00
pPoints[2] = pPoints[0]+Width;
pPoints[3] = pPoints[1]+Height;
2008-01-12 17:09:00 +00:00
}
2010-05-29 07:25:38 +00:00
void CRenderTools::RenderTilemapGenerateSkip(class CLayers *pLayers)
2008-03-12 23:53:39 +00:00
{
2010-05-29 07:25:38 +00:00
for(int g = 0; g < pLayers->NumGroups(); g++)
2008-03-12 23:53:39 +00:00
{
2010-05-29 07:25:38 +00:00
CMapItemGroup *pGroup = pLayers->GetGroup(g);
2010-05-29 07:25:38 +00:00
for(int l = 0; l < pGroup->m_NumLayers; l++)
2008-03-12 23:53:39 +00:00
{
2010-05-29 07:25:38 +00:00
CMapItemLayer *pLayer = pLayers->GetLayer(pGroup->m_StartLayer+l);
2008-03-12 23:53:39 +00:00
2010-05-29 07:25:38 +00:00
if(pLayer->m_Type == LAYERTYPE_TILES)
2008-03-12 23:53:39 +00:00
{
2010-05-29 07:25:38 +00:00
CMapItemLayerTilemap *pTmap = (CMapItemLayerTilemap *)pLayer;
CTile *pTiles = (CTile *)pLayers->Map()->GetData(pTmap->m_Data);
for(int y = 0; y < pTmap->m_Height; y++)
2008-03-12 23:53:39 +00:00
{
2012-02-15 00:40:40 +00:00
for(int x = 1; x < pTmap->m_Width;)
2008-03-12 23:53:39 +00:00
{
int sx;
2010-05-29 07:25:38 +00:00
for(sx = 1; x+sx < pTmap->m_Width && sx < 255; sx++)
2008-03-12 23:53:39 +00:00
{
2010-05-29 07:25:38 +00:00
if(pTiles[y*pTmap->m_Width+x+sx].m_Index)
2008-03-12 23:53:39 +00:00
break;
}
2010-05-29 07:25:38 +00:00
pTiles[y*pTmap->m_Width+x].m_Skip = sx-1;
2013-12-20 11:27:10 +00:00
x += sx;
2008-03-12 23:53:39 +00:00
}
}
}
}
}
}