mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-01-18 22:51:39 +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
|
else
|
||||||
RenderNode(nodes + numnodes - 1); // The head node is the last node output.
|
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!):
|
// Render back to front (we don't have a zbuffer at the moment, sniff!):
|
||||||
if (!r_debug_cull)
|
if (!r_debug_cull)
|
||||||
{
|
{
|
||||||
|
@ -130,8 +133,9 @@ void RenderPolyBsp::RenderSubsector(subsector_t *sub)
|
||||||
AddLine(line, frontsector);
|
AddLine(line, frontsector);
|
||||||
}
|
}
|
||||||
|
|
||||||
FTexture *floortex = TexMan(frontsector->GetTexture(sector_t::floor));
|
FTextureID floorpicnum = frontsector->GetTexture(sector_t::floor);
|
||||||
if (floortex->UseType != FTexture::TEX_Null)
|
FTexture *floortex = TexMan(floorpicnum);
|
||||||
|
if (floortex->UseType != FTexture::TEX_Null && floorpicnum != skyflatnum)
|
||||||
{
|
{
|
||||||
TriVertex *vertices = PolyVertexBuffer::GetVertices(sub->numlines);
|
TriVertex *vertices = PolyVertexBuffer::GetVertices(sub->numlines);
|
||||||
if (!vertices)
|
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);
|
PolyTriangleDrawer::draw(uniforms, vertices, sub->numlines, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, floortex);
|
||||||
}
|
}
|
||||||
|
|
||||||
FTexture *ceiltex = TexMan(frontsector->GetTexture(sector_t::ceiling));
|
FTextureID ceilpicnum = frontsector->GetTexture(sector_t::ceiling);
|
||||||
if (ceiltex->UseType != FTexture::TEX_Null)
|
FTexture *ceiltex = TexMan(ceilpicnum);
|
||||||
|
if (ceiltex->UseType != FTexture::TEX_Null && ceilpicnum != skyflatnum)
|
||||||
{
|
{
|
||||||
TriVertex *vertices = PolyVertexBuffer::GetVertices(sub->numlines);
|
TriVertex *vertices = PolyVertexBuffer::GetVertices(sub->numlines);
|
||||||
if (!vertices)
|
if (!vertices)
|
||||||
|
@ -261,8 +266,8 @@ void RenderPolyBsp::AddLine(seg_t *line, sector_t *frontsector)
|
||||||
double middlefloorz1 = MIN(bottomceilz1, middleceilz1);
|
double middlefloorz1 = MIN(bottomceilz1, middleceilz1);
|
||||||
double middlefloorz2 = MIN(bottomceilz2, middleceilz2);
|
double middlefloorz2 = MIN(bottomceilz2, middleceilz2);
|
||||||
|
|
||||||
bool bothSkyCeiling = false;// frontsector->GetTexture(sector_t::ceiling) == skyflatnum && backsector->GetTexture(sector_t::ceiling) == skyflatnum;
|
bool bothSkyCeiling = 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 bothSkyFloor = frontsector->GetTexture(sector_t::floor) == skyflatnum && backsector->GetTexture(sector_t::floor) == skyflatnum;
|
||||||
|
|
||||||
if ((topceilz1 > topfloorz1 || topceilz2 > topfloorz2) && !bothSkyCeiling && line->sidedef)
|
if ((topceilz1 > topfloorz1 || topceilz2 > topfloorz2) && !bothSkyCeiling && line->sidedef)
|
||||||
{
|
{
|
||||||
|
@ -1290,3 +1295,143 @@ void PolyVertexBuffer::Clear()
|
||||||
{
|
{
|
||||||
NextBufferVertex = 0;
|
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 TriVertex *GetVertices(int count);
|
||||||
static void Clear();
|
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