mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 15:22:15 +00:00
Draw sky in a very expensive way
This commit is contained in:
parent
9820a6cb88
commit
6c52e1e52b
2 changed files with 172 additions and 6 deletions
157
src/r_poly.cpp
157
src/r_poly.cpp
|
@ -72,6 +72,9 @@ void RenderPolyBsp::Render()
|
|||
else
|
||||
RenderNode(nodes + numnodes - 1); // The head node is the last node output.
|
||||
|
||||
static PolySkyDome skydome;
|
||||
skydome.Render(worldToClip);
|
||||
|
||||
// Render back to front (we don't have a zbuffer at the moment, sniff!):
|
||||
if (!r_debug_cull)
|
||||
{
|
||||
|
@ -130,8 +133,9 @@ void RenderPolyBsp::RenderSubsector(subsector_t *sub)
|
|||
AddLine(line, frontsector);
|
||||
}
|
||||
|
||||
FTexture *floortex = TexMan(frontsector->GetTexture(sector_t::floor));
|
||||
if (floortex->UseType != FTexture::TEX_Null)
|
||||
FTextureID floorpicnum = frontsector->GetTexture(sector_t::floor);
|
||||
FTexture *floortex = TexMan(floorpicnum);
|
||||
if (floortex->UseType != FTexture::TEX_Null && floorpicnum != skyflatnum)
|
||||
{
|
||||
TriVertex *vertices = PolyVertexBuffer::GetVertices(sub->numlines);
|
||||
if (!vertices)
|
||||
|
@ -154,8 +158,9 @@ void RenderPolyBsp::RenderSubsector(subsector_t *sub)
|
|||
PolyTriangleDrawer::draw(uniforms, vertices, sub->numlines, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, floortex);
|
||||
}
|
||||
|
||||
FTexture *ceiltex = TexMan(frontsector->GetTexture(sector_t::ceiling));
|
||||
if (ceiltex->UseType != FTexture::TEX_Null)
|
||||
FTextureID ceilpicnum = frontsector->GetTexture(sector_t::ceiling);
|
||||
FTexture *ceiltex = TexMan(ceilpicnum);
|
||||
if (ceiltex->UseType != FTexture::TEX_Null && ceilpicnum != skyflatnum)
|
||||
{
|
||||
TriVertex *vertices = PolyVertexBuffer::GetVertices(sub->numlines);
|
||||
if (!vertices)
|
||||
|
@ -261,8 +266,8 @@ void RenderPolyBsp::AddLine(seg_t *line, sector_t *frontsector)
|
|||
double middlefloorz1 = MIN(bottomceilz1, middleceilz1);
|
||||
double middlefloorz2 = MIN(bottomceilz2, middleceilz2);
|
||||
|
||||
bool bothSkyCeiling = false;// frontsector->GetTexture(sector_t::ceiling) == skyflatnum && backsector->GetTexture(sector_t::ceiling) == skyflatnum;
|
||||
bool bothSkyFloor = false;// frontsector->GetTexture(sector_t::floor) == skyflatnum && backsector->GetTexture(sector_t::floor) == skyflatnum;
|
||||
bool bothSkyCeiling = frontsector->GetTexture(sector_t::ceiling) == skyflatnum && backsector->GetTexture(sector_t::ceiling) == skyflatnum;
|
||||
bool bothSkyFloor = frontsector->GetTexture(sector_t::floor) == skyflatnum && backsector->GetTexture(sector_t::floor) == skyflatnum;
|
||||
|
||||
if ((topceilz1 > topfloorz1 || topceilz2 > topfloorz2) && !bothSkyCeiling && line->sidedef)
|
||||
{
|
||||
|
@ -1290,3 +1295,143 @@ void PolyVertexBuffer::Clear()
|
|||
{
|
||||
NextBufferVertex = 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TriVertex PolySkyDome::SetVertex(float xx, float yy, float zz, float uu, float vv)
|
||||
{
|
||||
TriVertex v;
|
||||
v.x = xx;
|
||||
v.y = yy;
|
||||
v.z = zz;
|
||||
v.w = 1.0f;
|
||||
v.varying[0] = uu;
|
||||
v.varying[1] = vv;
|
||||
return v;
|
||||
}
|
||||
|
||||
TriVertex PolySkyDome::SetVertexXYZ(float xx, float yy, float zz, float uu, float vv)
|
||||
{
|
||||
TriVertex v;
|
||||
v.x = xx;
|
||||
v.y = zz;
|
||||
v.z = yy;
|
||||
v.w = 1.0f;
|
||||
v.varying[0] = uu;
|
||||
v.varying[1] = vv;
|
||||
return v;
|
||||
}
|
||||
|
||||
void PolySkyDome::SkyVertex(int r, int c, bool zflip)
|
||||
{
|
||||
static const FAngle maxSideAngle = 60.f;
|
||||
static const float scale = 10000.;
|
||||
|
||||
FAngle topAngle = (c / (float)mColumns * 360.f);
|
||||
FAngle sideAngle = maxSideAngle * (float)(mRows - r) / (float)mRows;
|
||||
float height = sideAngle.Sin();
|
||||
float realRadius = scale * sideAngle.Cos();
|
||||
FVector2 pos = topAngle.ToVector(realRadius);
|
||||
float z = (!zflip) ? scale * height : -scale * height;
|
||||
|
||||
float u, v;
|
||||
//uint32_t color = r == 0 ? 0xffffff : 0xffffffff;
|
||||
|
||||
// And the texture coordinates.
|
||||
if (!zflip) // Flipped Y is for the lower hemisphere.
|
||||
{
|
||||
u = (-c / (float)mColumns);
|
||||
v = (r / (float)mRows);
|
||||
}
|
||||
else
|
||||
{
|
||||
u = (-c / (float)mColumns);
|
||||
v = 1.0f + ((mRows - r) / (float)mRows);
|
||||
}
|
||||
|
||||
if (r != 4) z += 300;
|
||||
|
||||
// And finally the vertex.
|
||||
TriVertex vert;
|
||||
vert = SetVertexXYZ(-pos.X, z - 1.f, pos.Y, u * 4.0f, v + 0.5f/*, color*/);
|
||||
mVertices.Push(vert);
|
||||
}
|
||||
|
||||
void PolySkyDome::CreateSkyHemisphere(bool zflip)
|
||||
{
|
||||
int r, c;
|
||||
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
|
||||
for (c = 0; c < mColumns; c++)
|
||||
{
|
||||
SkyVertex(1, c, zflip);
|
||||
}
|
||||
|
||||
// The total number of triangles per hemisphere can be calculated
|
||||
// as follows: rows * columns * 2 + 2 (for the top cap).
|
||||
for (r = 0; r < mRows; r++)
|
||||
{
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
for (c = 0; c <= mColumns; c++)
|
||||
{
|
||||
SkyVertex(r + zflip, c, zflip);
|
||||
SkyVertex(r + 1 - zflip, c, zflip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PolySkyDome::CreateDome()
|
||||
{
|
||||
mColumns = 128;
|
||||
mRows = 4;
|
||||
CreateSkyHemisphere(false);
|
||||
CreateSkyHemisphere(true);
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
}
|
||||
|
||||
void PolySkyDome::RenderRow(const TriUniforms &uniforms, FTexture *skytex, int row)
|
||||
{
|
||||
PolyTriangleDrawer::draw(uniforms, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], TriangleDrawMode::Strip, false, 0, viewwidth, 0, viewheight, skytex);
|
||||
}
|
||||
|
||||
void PolySkyDome::RenderCapColorRow(const TriUniforms &uniforms, FTexture *skytex, int row, bool bottomCap)
|
||||
{
|
||||
uint32_t solid = skytex->GetSkyCapColor(bottomCap);
|
||||
if (!r_swtruecolor)
|
||||
solid = RGB32k.RGB[(RPART(solid) >> 3)][(GPART(solid) >> 3)][(BPART(solid) >> 3)];
|
||||
PolyTriangleDrawer::fill(uniforms, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], TriangleDrawMode::Fan, bottomCap, 0, viewwidth, 0, viewheight, solid);
|
||||
}
|
||||
|
||||
void PolySkyDome::Render(const TriMatrix &worldToClip)
|
||||
{
|
||||
FTextureID sky1tex, sky2tex;
|
||||
if ((level.flags & LEVEL_SWAPSKIES) && !(level.flags & LEVEL_DOUBLESKY))
|
||||
sky1tex = sky2texture;
|
||||
else
|
||||
sky1tex = sky1texture;
|
||||
sky2tex = sky2texture;
|
||||
|
||||
FTexture *frontskytex = TexMan(sky1tex, true);
|
||||
FTexture *backskytex = nullptr;
|
||||
if (level.flags & LEVEL_DOUBLESKY)
|
||||
backskytex = TexMan(sky2tex, true);
|
||||
|
||||
TriMatrix objectToWorld = TriMatrix::translate((float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z);
|
||||
|
||||
TriUniforms uniforms;
|
||||
uniforms.objectToClip = worldToClip * objectToWorld;
|
||||
uniforms.light = 256;
|
||||
uniforms.flags = 0;
|
||||
|
||||
int rc = mRows + 1;
|
||||
|
||||
RenderCapColorRow(uniforms, frontskytex, 0, false);
|
||||
RenderCapColorRow(uniforms, frontskytex, rc, true);
|
||||
|
||||
for (int i = 1; i <= mRows; i++)
|
||||
{
|
||||
RenderRow(uniforms, frontskytex, i);
|
||||
RenderRow(uniforms, frontskytex, rc + i);
|
||||
}
|
||||
}
|
||||
|
|
21
src/r_poly.h
21
src/r_poly.h
|
@ -181,3 +181,24 @@ public:
|
|||
static TriVertex *GetVertices(int count);
|
||||
static void Clear();
|
||||
};
|
||||
|
||||
class PolySkyDome
|
||||
{
|
||||
public:
|
||||
PolySkyDome() { CreateDome(); }
|
||||
void Render(const TriMatrix &worldToClip);
|
||||
|
||||
private:
|
||||
TArray<TriVertex> mVertices;
|
||||
TArray<unsigned int> mPrimStart;
|
||||
int mRows, mColumns;
|
||||
|
||||
void SkyVertex(int r, int c, bool yflip);
|
||||
void CreateSkyHemisphere(bool zflip);
|
||||
void CreateDome();
|
||||
void RenderRow(const TriUniforms &uniforms, FTexture *skytex, int row);
|
||||
void RenderCapColorRow(const TriUniforms &uniforms, FTexture *skytex, int row, bool bottomCap);
|
||||
|
||||
TriVertex SetVertex(float xx, float yy, float zz, float uu = 0, float vv = 0);
|
||||
TriVertex SetVertexXYZ(float xx, float yy, float zz, float uu = 0, float vv = 0);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue