Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f68b0f8c1 | ||
|
|
938c95c80d | ||
|
|
dfc7b5482e | ||
|
|
d258c920de | ||
|
|
b3eac23977 | ||
|
|
a114dd840b | ||
|
|
87fa339c8d | ||
|
|
afb5b717fe | ||
|
|
1a7dc425d2 | ||
|
|
038e8f0864 | ||
|
|
8ac506bf35 | ||
|
|
6cf2561dd3 | ||
|
|
3e459d4a21 |
No files matched your search
@@ -191,6 +191,7 @@ enum
|
||||
SHADER_SPRITE,
|
||||
SHADER_MODEL,
|
||||
SHADER_WATER,
|
||||
SHADER_WATERREFRACT,
|
||||
SHADER_FOG,
|
||||
SHADER_SKY,
|
||||
SHADER_PALETTE_POSTPROCESS,
|
||||
|
||||
@@ -39,6 +39,7 @@ void GL_EnableStencilTest(void);
|
||||
void GL_DisableStencilTest(void);
|
||||
|
||||
void GL_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
|
||||
void GL_DrawWaterPolygon(FOutVector *pOutVerts, FUINT iNumPts);
|
||||
void GL_DrawIndexedTriangles(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray);
|
||||
void GL_Draw2DLine(F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
|
||||
|
||||
|
||||
+261
-4
@@ -103,6 +103,8 @@ static constexpr INT32 bsp_culling_distances[] = {
|
||||
// Performance stats
|
||||
ps_metric_t ps_hw_nodesorttime = {};
|
||||
ps_metric_t ps_hw_nodedrawtime = {};
|
||||
ps_metric_t ps_hw_waterdrawtime = {};
|
||||
|
||||
ps_metric_t ps_hw_spritesorttime = {};
|
||||
ps_metric_t ps_hw_spritedrawtime = {};
|
||||
|
||||
@@ -712,7 +714,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
||||
if (PolyFlags & PF_Fog)
|
||||
shader = SHADER_FOG;
|
||||
else if (cv_ripplewater.value && (PolyFlags & PF_Ripple))
|
||||
{
|
||||
shader = SHADER_WATER;
|
||||
}
|
||||
else
|
||||
shader = SHADER_FLOOR;
|
||||
|
||||
@@ -807,6 +811,164 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
||||
#undef SETUP3DVERT
|
||||
}
|
||||
|
||||
// cut down version of HWR_RenderPlane
|
||||
// which renders only the refracted scene in place of planes
|
||||
// FIXME: we probably could just use stencil stuff for this
|
||||
// but i hate messing with that
|
||||
static void HWR_RenderRefractionPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, sector_t *FOFsector)
|
||||
{
|
||||
FOutVector *v3d;
|
||||
polyvertex_t *pv;
|
||||
pslope_t *slope = NULL;
|
||||
|
||||
size_t nrPlaneVerts;
|
||||
INT32 i;
|
||||
|
||||
float height; // constant y for all points on the convex flat polygon
|
||||
|
||||
static FOutVector *planeVerts = NULL;
|
||||
static UINT16 numAllocedPlaneVerts = 0;
|
||||
|
||||
poly_t *planepoly = xsub->planepoly;
|
||||
|
||||
// no convex poly were generated for this subsector
|
||||
if (!planepoly)
|
||||
return;
|
||||
|
||||
nrPlaneVerts = planepoly->numpts;
|
||||
|
||||
if (nrPlaneVerts < 3) // not even a triangle ?
|
||||
return;
|
||||
|
||||
const sector_t *sec = FOFsector;
|
||||
|
||||
// Get the slope pointer to simplify future code
|
||||
if (!isceiling && sec->f_slope)
|
||||
slope = sec->f_slope;
|
||||
else if (isceiling && sec->c_slope)
|
||||
slope = sec->c_slope;
|
||||
|
||||
height = FixedToFloat(fixedheight);
|
||||
|
||||
// Allocate plane-vertex buffer if we need to
|
||||
if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts)
|
||||
{
|
||||
numAllocedPlaneVerts = (UINT16)nrPlaneVerts;
|
||||
Z_Free(planeVerts);
|
||||
Z_Malloc(numAllocedPlaneVerts * sizeof (FOutVector), PU_LEVEL, &planeVerts);
|
||||
}
|
||||
|
||||
pv = planepoly->pts;
|
||||
|
||||
#define SETUP3DVERT(vert, vx, vy) {\
|
||||
vert->s = 0.0f;\
|
||||
vert->t = 0.0f;\
|
||||
\
|
||||
if (slope)\
|
||||
{\
|
||||
fixedheight = P_GetSlopeZAt(slope, FloatToFixed((vx)), FloatToFixed((vy)));\
|
||||
height = FixedToFloat(fixedheight);\
|
||||
}\
|
||||
\
|
||||
vert->x = (vx);\
|
||||
vert->y = height;\
|
||||
vert->z = (vy);\
|
||||
\
|
||||
}
|
||||
for (i = 0, v3d = planeVerts; i < (INT32)nrPlaneVerts; i++, v3d++, pv++)
|
||||
SETUP3DVERT(v3d, pv->x, pv->y);
|
||||
|
||||
GL_DrawWaterPolygon(planeVerts, nrPlaneVerts);
|
||||
|
||||
//FIXME: horizonlines with fofs dont work in gl for some reason!
|
||||
(void)subsector;
|
||||
/*if (gl_maphashorizonlines && subsector && cv_glhorizonlines.value)
|
||||
{
|
||||
// Horizon lines
|
||||
FOutVector horizonpts[6];
|
||||
float dist, vx, vy;
|
||||
float x1, y1, xd, yd;
|
||||
UINT8 numplanes, j;
|
||||
vertex_t v; // For determining the closest distance from the line to the camera, to split render planes for minimum distortion;
|
||||
|
||||
static constexpr float renderdist = 27000.0f; // How far out to properly render the plane
|
||||
static constexpr float farrenderdist = 32768.0f; // From here, raise plane to horizon level to fill in the line with some texture distortion
|
||||
|
||||
const seg_t *line = &segs[subsector->firstline];
|
||||
|
||||
for (i = 0; i < subsector->numlines; i++, line++)
|
||||
{
|
||||
if (line->polyseg)
|
||||
continue;
|
||||
|
||||
line_t* ld = line->linedef;
|
||||
|
||||
// this check sucks and is a hotspot lel
|
||||
if (LIKELY(ld->special != HORIZONSPECIAL))
|
||||
continue;
|
||||
|
||||
if (R_PointOnSegSide(viewx, viewy, line) != 0)
|
||||
continue;
|
||||
|
||||
P_ClosestPointOnLine(viewx, viewy, ld, &v);
|
||||
dist = FixedToFloat(R_PointToDist(v.x, v.y));
|
||||
|
||||
x1 = (line->fv1.x);
|
||||
y1 = (line->fv1.y);
|
||||
|
||||
xd = (line->fv2.x) - x1;
|
||||
yd = (line->fv2.y) - y1;
|
||||
|
||||
// Based on the seg length and the distance from the line, split horizon into multiple poly sets to reduce distortion
|
||||
dist = sqrtf((xd*xd) + (yd*yd)) / dist / 16.0f;
|
||||
|
||||
if (dist > 100.0f)
|
||||
numplanes = 100;
|
||||
else
|
||||
numplanes = (UINT8)dist + 1;
|
||||
|
||||
for (j = 0; j < numplanes; j++)
|
||||
{
|
||||
// Left side
|
||||
vx = x1 + xd * j / numplanes;
|
||||
vy = y1 + yd * j / numplanes;
|
||||
SETUP3DVERT((&horizonpts[1]), vx, vy);
|
||||
|
||||
dist = sqrtf(powf(vx - gl_viewx, 2) + powf(vy - gl_viewy, 2));
|
||||
vx = (vx - gl_viewx) * renderdist / dist + gl_viewx;
|
||||
vy = (vy - gl_viewy) * renderdist / dist + gl_viewy;
|
||||
SETUP3DVERT((&horizonpts[0]), vx, vy);
|
||||
|
||||
// Right side
|
||||
vx = x1 + xd * (j+1) / numplanes;
|
||||
vy = y1 + yd * (j+1) / numplanes;
|
||||
SETUP3DVERT((&horizonpts[2]), vx, vy);
|
||||
|
||||
dist = sqrtf(powf(vx - gl_viewx, 2) + powf(vy - gl_viewy, 2));
|
||||
vx = (vx - gl_viewx) * renderdist / dist + gl_viewx;
|
||||
vy = (vy - gl_viewy) * renderdist / dist + gl_viewy;
|
||||
SETUP3DVERT((&horizonpts[3]), vx, vy);
|
||||
|
||||
// Horizon fills
|
||||
vx = (horizonpts[0].x - gl_viewx) * farrenderdist / renderdist + gl_viewx;
|
||||
vy = (horizonpts[0].z - gl_viewy) * farrenderdist / renderdist + gl_viewy;
|
||||
SETUP3DVERT((&horizonpts[5]), vx, vy);
|
||||
horizonpts[5].y = gl_viewz;
|
||||
|
||||
vx = (horizonpts[3].x - gl_viewx) * farrenderdist / renderdist + gl_viewx;
|
||||
vy = (horizonpts[3].z - gl_viewy) * farrenderdist / renderdist + gl_viewy;
|
||||
SETUP3DVERT((&horizonpts[4]), vx, vy);
|
||||
horizonpts[4].y = gl_viewz;
|
||||
|
||||
// Draw
|
||||
GL_DrawWaterPolygon(&Surf, horizonpts, 6, PF_NoTexture|PF_Ripple);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
#undef SETUP3DVERT
|
||||
}
|
||||
|
||||
#ifdef WALLSPLATS
|
||||
static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf)
|
||||
{
|
||||
@@ -4225,7 +4387,9 @@ static void HWR_RenderDrawNodes(void)
|
||||
|
||||
// Reversed order
|
||||
for (i = 0; i < numdrawnodes; i++)
|
||||
{
|
||||
sortindex[i] = numdrawnodes - i - 1;
|
||||
}
|
||||
|
||||
// The order is correct apart from planes in the same subsector.
|
||||
// So scan the list and sort out these cases.
|
||||
@@ -4301,7 +4465,6 @@ static void HWR_RenderDrawNodes(void)
|
||||
|
||||
HWR_RenderPolyObjectPlane(polyplane->polysector, polyplane->isceiling, polyplane->fixedheight, polyplane->blend, polyplane->lightlevel,
|
||||
polyplane->lumpnum, polyplane->FOFSector, polyplane->alpha, polyplane->planecolormap);
|
||||
|
||||
}
|
||||
break;
|
||||
case DRAWNODE_WALL:
|
||||
@@ -4325,6 +4488,89 @@ static void HWR_RenderDrawNodes(void)
|
||||
drawnodes.clear(); // clear so our size is 0 again!
|
||||
}
|
||||
|
||||
static void HWR_RenderRefractionWater(void)
|
||||
{
|
||||
// this basically just draws a refracted screen copy in the place of water planes
|
||||
// best approach i can think of to handle translucent things being drawn behind water planes
|
||||
// this means other translucent shit will appear "correctly" and does not cause any sorting issues
|
||||
// caveat: anything translucent behind water planes will be unaffected by the refraction effect
|
||||
// there just is no better way to do this unless we wanna trash performance to hell by doing a screen copy per water plane
|
||||
// it "might" be possible to only partially copy the screen like the software renderer
|
||||
// but that will be rather tricky to implement since we dont really have "screen bounds" we can use for this
|
||||
// plus i also immensely suck at maths
|
||||
|
||||
static std::vector<gl_drawnode_t> waterdrawnodes;
|
||||
|
||||
const size_t numdrawnodes = drawnodes.size();
|
||||
|
||||
// no drawnodes...
|
||||
if (!numdrawnodes)
|
||||
return;
|
||||
|
||||
waterdrawnodes.reserve(DRAWNODES_INIT_SIZE/2); // surely there will be less water than other stuff, right?
|
||||
|
||||
// go through our drawnodes to pull out the water
|
||||
// HWR_RenderDrawNodes will skip those
|
||||
// we do this before since trying to capture
|
||||
// anything translucent in the refraction is utter arse pain
|
||||
for (size_t w = 0; w < numdrawnodes; w++)
|
||||
{
|
||||
gl_drawnode_t *drawnode = &drawnodes[w];
|
||||
|
||||
// gotta be a plane duh
|
||||
if (drawnode->type != DRAWNODE_PLANE)
|
||||
continue;
|
||||
|
||||
planeinfo_t *plane = &drawnode->u.plane;
|
||||
|
||||
// uh dont think we actually need this lol
|
||||
// but better be safe for now
|
||||
if (plane->alpha >= 255)
|
||||
continue;
|
||||
|
||||
// this only applies to translucent water with ripple effect!
|
||||
if (!(plane->blend & PF_Ripple))
|
||||
continue;
|
||||
|
||||
waterdrawnodes.push_back(drawnodes[w]);
|
||||
}
|
||||
|
||||
const size_t numwaterdrawnodes = waterdrawnodes.size();
|
||||
|
||||
// no water....
|
||||
if (!numwaterdrawnodes)
|
||||
return;
|
||||
|
||||
// this is probably a bit wasteful
|
||||
// since we only copy the screen once
|
||||
// but you might be able to see both planes not overlap if you look from a wonky angle
|
||||
auto wotercompare = [](const void *p1, const void *p2)
|
||||
{
|
||||
const gl_drawnode_t *n1 = (const gl_drawnode_t *)p1;
|
||||
const gl_drawnode_t *n2 = (const gl_drawnode_t *)p2;
|
||||
|
||||
return abs(n2->u.plane.fixedheight - viewz) -
|
||||
abs(n1->u.plane.fixedheight - viewz);
|
||||
};
|
||||
|
||||
qs22j(waterdrawnodes.data(), waterdrawnodes.size(), sizeof(gl_drawnode_t), wotercompare);
|
||||
|
||||
GL_SetTransform(&atransform);
|
||||
|
||||
GL_CopyMainFramebufferTexture();
|
||||
GL_CopyMainFramebufferDepth();
|
||||
|
||||
// now finally render the refraction planes
|
||||
for (auto &drawnode : waterdrawnodes)
|
||||
{
|
||||
planeinfo_t *plane = &drawnode.u.plane;
|
||||
gl_frontsector = NULL;
|
||||
HWR_RenderRefractionPlane(NULL, plane->xsub, plane->isceiling, plane->fixedheight, plane->FOFSector);
|
||||
}
|
||||
|
||||
waterdrawnodes.clear();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Draw all vissprites
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -5601,9 +5847,20 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, int stencil_level, bool
|
||||
HWR_DrawSprites<DrawSpritesType::kSprites>();
|
||||
PS_STOP_TIMING(ps_hw_spritedrawtime);
|
||||
|
||||
ps_numdrawnodes.value.i = 0;
|
||||
ps_hw_nodesorttime.value.p = 0;
|
||||
ps_hw_nodedrawtime.value.p = 0;
|
||||
ps_numdrawnodes.value.i = 0;
|
||||
ps_hw_nodesorttime.value.p = 0;
|
||||
ps_hw_nodedrawtime.value.p = 0;
|
||||
ps_hw_waterdrawtime.value.p = 0;
|
||||
|
||||
// thisll be a good mess making this toggable
|
||||
if (cv_ripplewater.value && HWR_UseShader() && !wireframe) // dont need this without shaders do we
|
||||
{
|
||||
// should we not do this during portal render?
|
||||
// wonder how bad the perf will be....
|
||||
PS_START_TIMING(ps_hw_waterdrawtime);
|
||||
HWR_RenderRefractionWater();
|
||||
PS_STOP_TIMING(ps_hw_waterdrawtime);
|
||||
}
|
||||
|
||||
HWR_RenderDrawNodes();
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ enum
|
||||
// Performance stats
|
||||
extern ps_metric_t ps_hw_nodesorttime;
|
||||
extern ps_metric_t ps_hw_nodedrawtime;
|
||||
extern ps_metric_t ps_hw_waterdrawtime;
|
||||
extern ps_metric_t ps_hw_spritesorttime;
|
||||
extern ps_metric_t ps_hw_spritedrawtime;
|
||||
|
||||
|
||||
@@ -41,6 +41,9 @@ static struct {
|
||||
// Water shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WATER_FRAGMENT_SHADER},
|
||||
|
||||
// Water refraction shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WATERREFRACT_FRAGMENT_SHADER},
|
||||
|
||||
// Fog shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_FOG_FRAGMENT_SHADER},
|
||||
|
||||
|
||||
@@ -243,23 +243,30 @@
|
||||
// Water surface shader
|
||||
//
|
||||
// Mostly guesstimated, rather than the rest being built off Software science.
|
||||
// Still needs to distort things underneath/around the water...
|
||||
// Still needs to distort things underneath/around the water... // huehueuehuehue
|
||||
//
|
||||
|
||||
// readjusted to match software much more closely
|
||||
|
||||
#define GLSL_WATER_CONST \
|
||||
"const float freq = 0.07;\n" \
|
||||
"const float amp = 0.07;\n" \
|
||||
"const float amp_t = 0.025;\n" \
|
||||
"const float speed = 4.0;\n" \
|
||||
"const float pi = 3.14159;\n" \
|
||||
"const float falltresh = 0.007;\n" \
|
||||
|
||||
#define GLSL_WATER_TEXEL \
|
||||
"float water_z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \
|
||||
"float a = -pi * (water_z * freq) + (leveltime * speed);\n" \
|
||||
"float sdistort = sin(a) * amp;\n" \
|
||||
"float cdistort = cos(a) * amp;\n" \
|
||||
"vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n"
|
||||
"float falloff = 1.0 / (1.0 + water_z * falltresh);\n" \
|
||||
"float distort = sin(a) * amp * falloff;\n" \
|
||||
"vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - distort, gl_TexCoord[0].t));\n" \
|
||||
|
||||
#define GLSL_WATER_FRAGMENT_SHADER \
|
||||
"#version 120\n" \
|
||||
GLSL_FLOOR_FUDGES \
|
||||
"const float freq = 0.025;\n" \
|
||||
"const float amp = 0.025;\n" \
|
||||
"const float speed = 2.0;\n" \
|
||||
"const float pi = 3.14159;\n" \
|
||||
GLSL_WATER_CONST \
|
||||
"#ifdef SRB2_PALETTE_RENDERING\n" \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform sampler3D palette_lookup_tex;\n" \
|
||||
@@ -294,6 +301,29 @@
|
||||
"}\n" \
|
||||
"#endif\0"
|
||||
|
||||
// water refraction stuff
|
||||
// this is probably complete shit but i dont care
|
||||
// got the idea for depth testing from https://lettier.github.io/3d-game-shaders-for-beginners/screen-space-refraction.html
|
||||
#define GLSL_WATERREFRACT_FRAGMENT_SHADER \
|
||||
"#version 120\n" \
|
||||
GLSL_WATER_CONST \
|
||||
"uniform sampler2D scene_tex;\n" \
|
||||
"uniform sampler2D scene_depth_tex;\n" \
|
||||
"uniform vec2 scr_resolution;\n" \
|
||||
"uniform float leveltime;\n" \
|
||||
"void main(void) {\n" \
|
||||
"float water_z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \
|
||||
"float a = -pi * (water_z * freq) + (leveltime * speed);\n" \
|
||||
"float falloff = 1.0 / (1.0 + water_z * falltresh);\n" \
|
||||
"float distort = sin(a) * amp * falloff;\n" \
|
||||
"vec2 uv = (gl_FragCoord.xy / scr_resolution) + vec2(distort, distort * 2.0) * 0.04;\n" \
|
||||
"float scenedepth = texture2D(scene_depth_tex, uv).r;\n" \
|
||||
"if (scenedepth < gl_FragCoord.z) {\n" \
|
||||
"discard;\n" \
|
||||
"}\n" \
|
||||
"gl_FragColor = texture2D(scene_tex, uv);\n" \
|
||||
"}\0"
|
||||
|
||||
//
|
||||
// Fog block shader
|
||||
//
|
||||
|
||||
@@ -173,6 +173,15 @@ boolean supportstencil = false;
|
||||
// can know when the textures aren't there, as textures are always considered resident in their virtual memory
|
||||
static GLuint screenTextures[NUMSCREENTEXTURES] = {};
|
||||
|
||||
// for water refraction
|
||||
enum
|
||||
{
|
||||
SCENE_TEX,
|
||||
SCENE_DEPTHTEX,
|
||||
NUMSCENETEXTURES
|
||||
};
|
||||
static GLuint sceneTextures[NUMSCENETEXTURES] = {};
|
||||
|
||||
#define byte2float(byte) (GLfloat)(byte / 255.0f)
|
||||
|
||||
// -----------------+
|
||||
@@ -723,6 +732,9 @@ typedef enum
|
||||
gluniform_palette_lookup_tex, // 3d texture containing the rgb->index lookup table
|
||||
gluniform_lighttable_tex, // 2d texture containing a light table
|
||||
|
||||
gluniform_scene_tex,
|
||||
gluniform_scene_depth_tex,
|
||||
|
||||
// misc.
|
||||
gluniform_leveltime,
|
||||
|
||||
@@ -2386,6 +2398,9 @@ static boolean GL_Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
|
||||
// misc.
|
||||
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
|
||||
|
||||
shader->uniforms[gluniform_scene_tex] = GETUNI("scene_tex");
|
||||
shader->uniforms[gluniform_scene_depth_tex] = GETUNI("scene_depth_tex");
|
||||
#undef GETUNI
|
||||
|
||||
// set permanent uniform values
|
||||
@@ -2400,6 +2415,9 @@ static boolean GL_Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
UNIFORM_1(shader->uniforms[gluniform_palette_lookup_tex], 1, pglUniform1i);
|
||||
UNIFORM_1(shader->uniforms[gluniform_lighttable_tex], 2, pglUniform1i);
|
||||
|
||||
UNIFORM_1(shader->uniforms[gluniform_scene_tex], 4, pglUniform1i);
|
||||
UNIFORM_1(shader->uniforms[gluniform_scene_depth_tex], 5, pglUniform1i);
|
||||
|
||||
// restore gl shader state
|
||||
pglUseProgram(gl_shaderstate.program);
|
||||
#undef UNIFORM_1
|
||||
@@ -2480,6 +2498,24 @@ void GL_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, F
|
||||
Clamp2D(GL_TEXTURE_WRAP_T);
|
||||
}
|
||||
|
||||
void GL_DrawWaterPolygon(FOutVector *pOutVerts, FUINT iNumPts)
|
||||
{
|
||||
GL_SetShader(HWR_GetShaderFromTarget(SHADER_WATERREFRACT));
|
||||
|
||||
pglActiveTexture(GL_TEXTURE4);
|
||||
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_TEX]);
|
||||
pglActiveTexture(GL_TEXTURE0);
|
||||
|
||||
pglActiveTexture(GL_TEXTURE5);
|
||||
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_DEPTHTEX]);
|
||||
pglActiveTexture(GL_TEXTURE0);
|
||||
|
||||
GL_PreparePolygon(NULL, PF_NoTexture|PF_Ripple);
|
||||
|
||||
pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x);
|
||||
pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts);
|
||||
}
|
||||
|
||||
void GL_DrawIndexedTriangles(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, unsigned int *IndexArray)
|
||||
{
|
||||
GL_PreparePolygon(pSurf, PolyFlags);
|
||||
@@ -3384,6 +3420,57 @@ void GL_Framebuffer_Disable(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
// faster than fbo blitting ig...
|
||||
// just copies the whole framebuffer as a texture
|
||||
void GL_CopyMainFramebufferTexture(void)
|
||||
{
|
||||
if (!sceneTextures[SCENE_TEX])
|
||||
{
|
||||
pglGenTextures(1, &sceneTextures[SCENE_TEX]);
|
||||
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_TEX]);
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
Clamp2D(GL_TEXTURE_WRAP_S);
|
||||
Clamp2D(GL_TEXTURE_WRAP_T);
|
||||
pglBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
// now copy the whole scene
|
||||
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_TEX]);
|
||||
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screen_width, screen_height);
|
||||
|
||||
// not sure why, but this is needed
|
||||
// otherwise bad things happen
|
||||
tex_downloaded = sceneTextures[SCENE_TEX];
|
||||
|
||||
pglBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void GL_CopyMainFramebufferDepth(void)
|
||||
{
|
||||
if (!sceneTextures[SCENE_DEPTHTEX])
|
||||
{
|
||||
pglGenTextures(1, &sceneTextures[SCENE_DEPTHTEX]);
|
||||
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_DEPTHTEX]);
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, screen_width, screen_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
Clamp2D(GL_TEXTURE_WRAP_S);
|
||||
Clamp2D(GL_TEXTURE_WRAP_T);
|
||||
pglBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
// and copy the depth from the scene
|
||||
// we need this for depth testing within the shader
|
||||
// so we can discard stuff in front of the water
|
||||
// this aint reflections after all!
|
||||
pglBindTexture(GL_TEXTURE_2D, sceneTextures[SCENE_DEPTHTEX]);
|
||||
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screen_width, screen_height);
|
||||
|
||||
pglBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
static const float defaultscreenVerts[12] =
|
||||
{
|
||||
-1.0f, -1.0f, 1.0f,
|
||||
@@ -3505,6 +3592,10 @@ void GL_FlushScreenTextures(void)
|
||||
{
|
||||
pglDeleteTextures(NUMSCREENTEXTURES, screenTextures);
|
||||
memset(screenTextures, 0, sizeof(screenTextures));
|
||||
|
||||
// gotta wipe the scene textures for the water refraction stuff aswell
|
||||
pglDeleteTextures(NUMSCENETEXTURES, sceneTextures);
|
||||
memset(sceneTextures, 0, sizeof(sceneTextures));
|
||||
}
|
||||
|
||||
void GL_DrawScreenTexture(int tex, FSurfaceInfo *surf, FBITFIELD polyflags)
|
||||
|
||||
@@ -104,6 +104,9 @@ void GL_Framebuffer_Disable(void);
|
||||
extern int supportFBO;
|
||||
#endif
|
||||
|
||||
void GL_CopyMainFramebufferTexture(void);
|
||||
void GL_CopyMainFramebufferDepth(void);
|
||||
|
||||
// ==========================================================================
|
||||
// GLOBAL
|
||||
// ==========================================================================
|
||||
|
||||
@@ -98,6 +98,7 @@ perfstatrow_t rendertime_rows[] = {
|
||||
{" sprdraw", " Sprite render: ", &ps_hw_spritedrawtime, PS_TIME|PS_LEVEL|PS_HW},
|
||||
{" nodesrt", " Drwnode sort: ", &ps_hw_nodesorttime, PS_TIME|PS_LEVEL|PS_HW},
|
||||
{" nodedrw", " Drwnode render:", &ps_hw_nodedrawtime, PS_TIME|PS_LEVEL|PS_HW},
|
||||
{" wtrdrw", " Water render: ", &ps_hw_waterdrawtime, PS_TIME|PS_LEVEL|PS_HW},
|
||||
{" other ", " Other: ", &ps_otherrendertime, PS_TIME|PS_LEVEL|PS_HW},
|
||||
#endif
|
||||
|
||||
@@ -536,6 +537,7 @@ static void PS_UpdateFrameStats(void)
|
||||
ps_skyboxtime.value.p +
|
||||
ps_hw_nodesorttime.value.p +
|
||||
ps_hw_nodedrawtime.value.p +
|
||||
ps_hw_waterdrawtime.value.p +
|
||||
ps_hw_spritesorttime.value.p +
|
||||
ps_hw_spritedrawtime.value.p;
|
||||
|
||||
|
||||
Reference in new issue
Block a user