ffov implemented in GL.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3320 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
efb1d412a5
commit
12cccf0e39
1 changed files with 494 additions and 198 deletions
|
@ -70,6 +70,7 @@ qboolean mirror;
|
|||
mplane_t *mirror_plane;
|
||||
msurface_t *r_mirror_chain;
|
||||
qboolean r_inmirror; //or out-of-body
|
||||
extern msurface_t *r_alpha_surfaces;
|
||||
|
||||
//
|
||||
// view origin
|
||||
|
@ -121,6 +122,8 @@ cvar_t gl_maxdist = SCVAR("gl_maxdist", "8192");
|
|||
extern cvar_t gl_contrast;
|
||||
extern cvar_t gl_mindist;
|
||||
|
||||
extern cvar_t ffov;
|
||||
|
||||
extern cvar_t gl_motionblur;
|
||||
extern cvar_t gl_motionblurscale;
|
||||
|
||||
|
@ -154,6 +157,12 @@ int scenepp_mt_parm_texture0i;
|
|||
int scenepp_mt_parm_colorf;
|
||||
int scenepp_mt_parm_inverti;
|
||||
|
||||
int scenepp_fisheye_texture;
|
||||
int scenepp_fisheye_program;
|
||||
int scenepp_fisheye_parm_fov;
|
||||
int scenepp_panorama_program;
|
||||
int scenepp_panorama_parm_fov;
|
||||
|
||||
// KrimZon - init post processing - called in GL_CheckExtensions, when they're called
|
||||
// I put it here so that only this file need be changed when messing with the post
|
||||
// processing shaders
|
||||
|
@ -223,6 +232,67 @@ void GL_InitSceneProcessingShaders_WaterWarp (void)
|
|||
Con_Printf(CON_ERROR "GL Error initing shader object\n");
|
||||
}
|
||||
|
||||
void GL_InitFisheyeFov(void)
|
||||
{
|
||||
char *vshader = "\
|
||||
varying vec2 texcoord;\
|
||||
void main(void)\
|
||||
{\
|
||||
texcoord = gl_MultiTexCoord0.xy;\
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\
|
||||
}";
|
||||
char *fisheyefshader = "\
|
||||
uniform samplerCube source;\
|
||||
varying vec2 texcoord;\
|
||||
uniform float fov;\
|
||||
void main(void)\
|
||||
{\
|
||||
vec3 tc; \
|
||||
vec2 d; \
|
||||
vec2 ang; \
|
||||
d = texcoord; \
|
||||
ang.x = sqrt(d.x*d.x+d.y*d.y)*fov; \
|
||||
ang.y = -atan(d.y, d.x); \
|
||||
tc.x = sin(ang.x) * cos(ang.y); \
|
||||
tc.y = sin(ang.x) * sin(ang.y); \
|
||||
tc.z = cos(ang.x); \
|
||||
gl_FragColor = textureCube(source, tc);\
|
||||
}";
|
||||
|
||||
char *panoramafshader = "\
|
||||
uniform samplerCube source;\
|
||||
varying vec2 texcoord;\
|
||||
uniform float fov;\
|
||||
void main(void)\
|
||||
{\
|
||||
vec3 tc; \
|
||||
float ang; \
|
||||
ang = texcoord.x*fov; \
|
||||
tc.x = sin(ang); \
|
||||
tc.y = -texcoord.y; \
|
||||
tc.z = cos(ang); \
|
||||
gl_FragColor = textureCube(source, tc);\
|
||||
}";
|
||||
|
||||
scenepp_fisheye_program = GLSlang_CreateProgram(NULL, vshader, fisheyefshader);
|
||||
if (scenepp_fisheye_program)
|
||||
{
|
||||
GLSlang_UseProgram(scenepp_fisheye_program);
|
||||
GLSlang_SetUniform1i(GLSlang_GetUniformLocation(scenepp_fisheye_program, "source"), 0);
|
||||
scenepp_fisheye_parm_fov = GLSlang_GetUniformLocation(scenepp_fisheye_program, "fov");
|
||||
GLSlang_UseProgram(0);
|
||||
}
|
||||
|
||||
scenepp_panorama_program = GLSlang_CreateProgram(NULL, vshader, panoramafshader);
|
||||
if (scenepp_panorama_program)
|
||||
{
|
||||
GLSlang_UseProgram(scenepp_panorama_program);
|
||||
GLSlang_SetUniform1i(GLSlang_GetUniformLocation(scenepp_panorama_program, "source"), 0);
|
||||
scenepp_panorama_parm_fov = GLSlang_GetUniformLocation(scenepp_panorama_program, "fov");
|
||||
GLSlang_UseProgram(0);
|
||||
}
|
||||
}
|
||||
|
||||
void GL_InitSceneProcessingShaders_MenuTint(void)
|
||||
{
|
||||
char *vshader = "\
|
||||
|
@ -273,6 +343,7 @@ void GL_InitSceneProcessingShaders_MenuTint(void)
|
|||
void GL_InitSceneProcessingShaders (void)
|
||||
{
|
||||
GL_InitSceneProcessingShaders_WaterWarp();
|
||||
GL_InitFisheyeFov();
|
||||
GL_InitSceneProcessingShaders_MenuTint();
|
||||
}
|
||||
|
||||
|
@ -285,6 +356,8 @@ void GL_SetupSceneProcessingTextures (void)
|
|||
unsigned char pp_warp_tex[PP_WARP_TEX_SIZE*PP_WARP_TEX_SIZE*3];
|
||||
unsigned char pp_edge_tex[PP_AMP_TEX_SIZE*PP_AMP_TEX_SIZE*3];
|
||||
|
||||
scenepp_fisheye_texture = 0;
|
||||
|
||||
sceneblur_texture = GL_AllocNewTexture();
|
||||
|
||||
if (!gl_config.arb_shader_objects)
|
||||
|
@ -1567,6 +1640,407 @@ void GLR_SetupFog (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void R_RenderMotionBlur(void)
|
||||
{
|
||||
int vwidth = 1, vheight = 1;
|
||||
float vs, vt, cs, ct;
|
||||
|
||||
if (gl_config.arb_texture_non_power_of_two)
|
||||
{ //we can use any size, supposedly
|
||||
vwidth = glwidth;
|
||||
vheight = glheight;
|
||||
}
|
||||
else
|
||||
{ //limit the texture size to square and use padding.
|
||||
while (vwidth < glwidth)
|
||||
vwidth *= 2;
|
||||
while (vheight < glheight)
|
||||
vheight *= 2;
|
||||
}
|
||||
|
||||
qglViewport (glx, gly, glwidth, glheight);
|
||||
|
||||
GL_Bind(sceneblur_texture);
|
||||
|
||||
// go 2d
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
qglOrtho (0, glwidth, 0, glheight, -99999, 99999);
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
|
||||
//blend the last frame onto the scene
|
||||
//the maths is because our texture is over-sized (must be power of two)
|
||||
cs = vs = (float)glwidth / vwidth * 0.5;
|
||||
ct = vt = (float)glheight / vheight * 0.5;
|
||||
vs *= gl_motionblurscale.value;
|
||||
vt *= gl_motionblurscale.value;
|
||||
|
||||
qglDisable (GL_DEPTH_TEST);
|
||||
qglDisable (GL_CULL_FACE);
|
||||
qglDisable (GL_ALPHA_TEST);
|
||||
qglEnable(GL_BLEND);
|
||||
qglColor4f(1, 1, 1, gl_motionblur.value);
|
||||
qglBegin(GL_QUADS);
|
||||
qglTexCoord2f(cs-vs, ct-vt);
|
||||
qglVertex2f(0, 0);
|
||||
qglTexCoord2f(cs+vs, ct-vt);
|
||||
qglVertex2f(glwidth, 0);
|
||||
qglTexCoord2f(cs+vs, ct+vt);
|
||||
qglVertex2f(glwidth, glheight);
|
||||
qglTexCoord2f(cs-vs, ct+vt);
|
||||
qglVertex2f(0, glheight);
|
||||
qglEnd();
|
||||
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPopMatrix();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPopMatrix();
|
||||
|
||||
|
||||
//copy the image into the texture so that we can play with it next frame too!
|
||||
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
static void R_RenderWaterWarp(void)
|
||||
{
|
||||
float vwidth = 1, vheight = 1;
|
||||
float vs, vt;
|
||||
|
||||
// get the powers of 2 for the size of the texture that will hold the scene
|
||||
|
||||
if (gl_config.arb_texture_non_power_of_two)
|
||||
{
|
||||
vwidth = glwidth;
|
||||
vheight = glheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (vwidth < glwidth)
|
||||
{
|
||||
vwidth *= 2;
|
||||
}
|
||||
while (vheight < glheight)
|
||||
{
|
||||
vheight *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
// get the maxtexcoords while we're at it
|
||||
vs = glwidth / vwidth;
|
||||
vt = glheight / vheight;
|
||||
|
||||
// 2d mode, but upside down to quake's normal 2d drawing
|
||||
// this makes grabbing the sreen a lot easier
|
||||
qglViewport (glx, gly, glwidth, glheight);
|
||||
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
// Push the matrices to go into 2d mode, that matches opengl's mode
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
// TODO: use actual window width and height
|
||||
qglOrtho (0, glwidth, 0, glheight, -99999, 99999);
|
||||
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
|
||||
qglDisable (GL_DEPTH_TEST);
|
||||
qglDisable (GL_CULL_FACE);
|
||||
qglDisable (GL_BLEND);
|
||||
qglEnable (GL_ALPHA_TEST);
|
||||
|
||||
// copy the scene to texture
|
||||
GL_Bind(scenepp_texture);
|
||||
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
if (qglGetError())
|
||||
Con_Printf(CON_ERROR "GL Error after qglCopyTexImage2D\n");
|
||||
|
||||
// Here we apply the shaders - currently just waterwarp
|
||||
GLSlang_UseProgram(scenepp_ww_program);
|
||||
//keep the amp proportional to the size of the scene in texture coords
|
||||
// WARNING - waterwarp can change the amplitude, but if it's too big it'll exceed
|
||||
// the size determined by the edge texture, after which black bits will be shown.
|
||||
// Suggest clamping to a suitable range.
|
||||
if (r_waterwarp.value<0)
|
||||
{
|
||||
GLSlang_SetUniform1f(scenepp_ww_parm_ampscalef, (0.005 / 0.625) * vs*(-r_waterwarp.value));
|
||||
}
|
||||
else
|
||||
{
|
||||
GLSlang_SetUniform1f(scenepp_ww_parm_ampscalef, (0.005 / 0.625) * vs*r_waterwarp.value);
|
||||
}
|
||||
|
||||
if (qglGetError())
|
||||
Con_Printf("GL Error after GLSlang_UseProgram\n");
|
||||
|
||||
{
|
||||
float xmin, xmax, ymin, ymax;
|
||||
|
||||
xmin = cl.time * 0.25;
|
||||
ymin = cl.time * 0.25;
|
||||
xmax = xmin + 1;
|
||||
ymax = ymin + 1/vt*vs;
|
||||
|
||||
GL_EnableMultitexture();
|
||||
GL_Bind (scenepp_texture_warp);
|
||||
|
||||
GL_SelectTexture(mtexid1+1);
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
GL_Bind(scenepp_texture_edge);
|
||||
|
||||
qglBegin(GL_QUADS);
|
||||
|
||||
qglMTexCoord2fSGIS (mtexid0, 0, 0);
|
||||
qglMTexCoord2fSGIS (mtexid1, xmin, ymin);
|
||||
qglMTexCoord2fSGIS (mtexid1+1, 0, 0);
|
||||
qglVertex2f(0, 0);
|
||||
|
||||
qglMTexCoord2fSGIS (mtexid0, vs, 0);
|
||||
qglMTexCoord2fSGIS (mtexid1, xmax, ymin);
|
||||
qglMTexCoord2fSGIS (mtexid1+1, 1, 0);
|
||||
qglVertex2f(glwidth, 0);
|
||||
|
||||
qglMTexCoord2fSGIS (mtexid0, vs, vt);
|
||||
qglMTexCoord2fSGIS (mtexid1, xmax, ymax);
|
||||
qglMTexCoord2fSGIS (mtexid1+1, 1, 1);
|
||||
qglVertex2f(glwidth, glheight);
|
||||
|
||||
qglMTexCoord2fSGIS (mtexid0, 0, vt);
|
||||
qglMTexCoord2fSGIS (mtexid1, xmin, ymax);
|
||||
qglMTexCoord2fSGIS (mtexid1+1, 0, 1);
|
||||
qglVertex2f(0, glheight);
|
||||
|
||||
qglEnd();
|
||||
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
GL_SelectTexture(mtexid1);
|
||||
|
||||
GL_DisableMultitexture();
|
||||
}
|
||||
|
||||
// Disable shaders
|
||||
GLSlang_UseProgram(0);
|
||||
|
||||
// After all the post processing, pop the matrices
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPopMatrix();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPopMatrix();
|
||||
|
||||
if (qglGetError())
|
||||
Con_Printf("GL Error after drawing with shaderobjects\n");
|
||||
}
|
||||
|
||||
qboolean R_RenderScene_Fish(void)
|
||||
{
|
||||
int cmapsize = 512;
|
||||
int i;
|
||||
static vec3_t ang[6] =
|
||||
{ {0, -90, 0}, {0, 90, 0},
|
||||
{90, 0, 0}, {-90, 0, 0},
|
||||
{0, 0, 0}, {0, -180, 0} };
|
||||
int order[6] = {4, 0, 1, 5, 3, 2};
|
||||
int numsides = 4;
|
||||
vec3_t saveang;
|
||||
int rot45 = 0;
|
||||
|
||||
if (!scenepp_panorama_program)
|
||||
return false;
|
||||
|
||||
if (gl_config.arb_texture_non_power_of_two)
|
||||
{
|
||||
if (glwidth < glheight)
|
||||
cmapsize = glwidth;
|
||||
else
|
||||
cmapsize = glheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (cmapsize > glwidth || cmapsize > glheight)
|
||||
{
|
||||
cmapsize /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy(r_refdef.viewangles, saveang);
|
||||
saveang[2] = 0;
|
||||
|
||||
if (ffov.value < 0)
|
||||
{
|
||||
//panoramic view needs at most the four sides
|
||||
if (ffov.value >= -90)
|
||||
numsides = 1;
|
||||
// else if (ffov.value >= -180)
|
||||
// {
|
||||
// numsides = 2;
|
||||
// rot45 = 1;
|
||||
// }
|
||||
else if (ffov.value >= -270)
|
||||
numsides = 3;
|
||||
else
|
||||
numsides = 4;
|
||||
|
||||
order[0] = 4;
|
||||
order[1] = 0;
|
||||
order[2] = 1;
|
||||
order[3] = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
//fisheye view sees a full sphere
|
||||
//
|
||||
if (ffov.value <= 77)
|
||||
numsides = 1;
|
||||
// else if (ffov.value <= 180)
|
||||
// {
|
||||
// numsides = 3;
|
||||
// rot45 = 3;
|
||||
// }
|
||||
else if (ffov.value <= 270)
|
||||
numsides = 5;
|
||||
else
|
||||
numsides = 6;
|
||||
|
||||
order[0] = 4;
|
||||
order[1] = 0;
|
||||
order[2] = 3;
|
||||
order[3] = 1;
|
||||
order[4] = 2;
|
||||
order[5] = 5;
|
||||
}
|
||||
|
||||
qglViewport (glx, gly+glheight - cmapsize, cmapsize, cmapsize);
|
||||
|
||||
if (!scenepp_fisheye_texture)
|
||||
{
|
||||
scenepp_fisheye_texture = GL_AllocNewTexture();
|
||||
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
qglEnable(GL_TEXTURE_CUBE_MAP_ARB);
|
||||
|
||||
bindTexFunc(GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture);
|
||||
for (i = 0; i < 6; i++)
|
||||
qglCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, 0, GL_RGB, 0, 0, cmapsize, cmapsize, 0);
|
||||
qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
qglDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
||||
}
|
||||
|
||||
r_refdef.vrect.width = (cmapsize+0.99)*vid.width/glwidth;
|
||||
r_refdef.vrect.height = (cmapsize+0.99)*vid.height/glheight;
|
||||
r_refdef.vrect.x = 0;
|
||||
r_refdef.vrect.y = vid.height - r_refdef.vrect.height;
|
||||
|
||||
ang[0][0] = -saveang[0];
|
||||
ang[0][1] = -90;
|
||||
ang[0][2] = -saveang[0];
|
||||
|
||||
ang[1][0] = -saveang[0];
|
||||
ang[1][1] = 90;
|
||||
ang[1][2] = saveang[0];
|
||||
ang[5][0] = -saveang[0]*2;
|
||||
for (i = 0; i < numsides; i++)
|
||||
{
|
||||
mirror = false;
|
||||
|
||||
r_refdef.fov_x = 90;
|
||||
r_refdef.fov_y = 90;
|
||||
r_refdef.viewangles[0] = saveang[0]+ang[order[i]][0];
|
||||
r_refdef.viewangles[1] = saveang[1]+ang[order[i]][1];
|
||||
r_refdef.viewangles[2] = saveang[2]+ang[order[i]][2];
|
||||
|
||||
R_Clear ();
|
||||
|
||||
// GLR_SetupFog ();
|
||||
|
||||
r_alpha_surfaces = NULL;
|
||||
|
||||
GL_SetShaderState2D(false);
|
||||
|
||||
// render normal view
|
||||
R_RenderScene ();
|
||||
|
||||
GLR_DrawWaterSurfaces ();
|
||||
GLR_DrawAlphaSurfaces ();
|
||||
|
||||
// render mirror view
|
||||
R_Mirror ();
|
||||
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
qglEnable(GL_TEXTURE_CUBE_MAP_ARB);
|
||||
GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture);
|
||||
qglCopyTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + order[i], 0, 0, 0, 0, 0, cmapsize, cmapsize);
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
qglDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
||||
}
|
||||
|
||||
//qglClear (GL_COLOR_BUFFER_BIT);
|
||||
qglViewport (glx, gly, glwidth, glheight);
|
||||
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture);
|
||||
qglEnable(GL_TEXTURE_CUBE_MAP_ARB);
|
||||
|
||||
if (scenepp_panorama_program && ffov.value < 0)
|
||||
{
|
||||
GLSlang_UseProgram(scenepp_panorama_program);
|
||||
GLSlang_SetUniform1f(scenepp_panorama_parm_fov, -ffov.value*3.1415926535897932384626433832795/180);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLSlang_UseProgram(scenepp_fisheye_program);
|
||||
GLSlang_SetUniform1f(scenepp_fisheye_parm_fov, ffov.value*3.1415926535897932384626433832795/180);
|
||||
}
|
||||
|
||||
|
||||
// go 2d
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
qglOrtho (0, glwidth, 0, glheight, -99999, 99999);
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
|
||||
qglDisable (GL_DEPTH_TEST);
|
||||
qglDisable (GL_CULL_FACE);
|
||||
qglDisable (GL_ALPHA_TEST);
|
||||
qglDisable(GL_BLEND);
|
||||
qglBegin(GL_QUADS);
|
||||
qglTexCoord2f(-0.5, -0.5);
|
||||
qglVertex2f(0, 0);
|
||||
qglTexCoord2f(0.5, -0.5);
|
||||
qglVertex2f(glwidth, 0);
|
||||
qglTexCoord2f(0.5, 0.5);
|
||||
qglVertex2f(glwidth, glheight);
|
||||
qglTexCoord2f(-0.5, 0.5);
|
||||
qglVertex2f(0, glheight);
|
||||
qglEnd();
|
||||
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPopMatrix();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPopMatrix();
|
||||
|
||||
qglDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
|
||||
GLSlang_UseProgram(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
================
|
||||
R_RenderView
|
||||
|
@ -1576,7 +2050,6 @@ r_refdef must be set before the first call
|
|||
*/
|
||||
void GLR_RenderView (void)
|
||||
{
|
||||
extern msurface_t *r_alpha_surfaces;
|
||||
double time1 = 0, time2;
|
||||
|
||||
if (qglGetError())
|
||||
|
@ -1627,24 +2100,31 @@ void GLR_RenderView (void)
|
|||
c_alias_polys = 0;
|
||||
}
|
||||
|
||||
mirror = false;
|
||||
if (ffov.value && cls.allow_fish && !(r_refdef.flags & Q2RDF_NOWORLDMODEL) && R_RenderScene_Fish())
|
||||
{
|
||||
//fisheye does its own rendering.
|
||||
}
|
||||
else
|
||||
{
|
||||
mirror = false;
|
||||
|
||||
R_Clear ();
|
||||
R_Clear ();
|
||||
|
||||
// GLR_SetupFog ();
|
||||
// GLR_SetupFog ();
|
||||
|
||||
r_alpha_surfaces = NULL;
|
||||
r_alpha_surfaces = NULL;
|
||||
|
||||
GL_SetShaderState2D(false);
|
||||
GL_SetShaderState2D(false);
|
||||
|
||||
// render normal view
|
||||
R_RenderScene ();
|
||||
// render normal view
|
||||
R_RenderScene ();
|
||||
|
||||
GLR_DrawWaterSurfaces ();
|
||||
GLR_DrawAlphaSurfaces ();
|
||||
GLR_DrawWaterSurfaces ();
|
||||
GLR_DrawAlphaSurfaces ();
|
||||
|
||||
// render mirror view
|
||||
R_Mirror ();
|
||||
// render mirror view
|
||||
R_Mirror ();
|
||||
}
|
||||
|
||||
R_BloomBlend();
|
||||
|
||||
|
@ -1674,196 +2154,12 @@ void GLR_RenderView (void)
|
|||
// we check if we need to use any shaders - currently it's just waterwarp
|
||||
if (scenepp_ww_program)
|
||||
if ((r_waterwarp.value>0 && r_viewleaf && r_viewleaf->contents <= Q1CONTENTS_WATER))
|
||||
{
|
||||
float vwidth = 1, vheight = 1;
|
||||
float vs, vt;
|
||||
|
||||
// get the powers of 2 for the size of the texture that will hold the scene
|
||||
while (vwidth < glwidth)
|
||||
{
|
||||
vwidth *= 2;
|
||||
}
|
||||
while (vheight < glheight)
|
||||
{
|
||||
vheight *= 2;
|
||||
}
|
||||
|
||||
// get the maxtexcoords while we're at it
|
||||
vs = glwidth / vwidth;
|
||||
vt = glheight / vheight;
|
||||
|
||||
// 2d mode, but upside down to quake's normal 2d drawing
|
||||
// this makes grabbing the sreen a lot easier
|
||||
qglViewport (glx, gly, glwidth, glheight);
|
||||
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
// Push the matrices to go into 2d mode, that matches opengl's mode
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
// TODO: use actual window width and height
|
||||
qglOrtho (0, glwidth, 0, glheight, -99999, 99999);
|
||||
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
|
||||
qglDisable (GL_DEPTH_TEST);
|
||||
qglDisable (GL_CULL_FACE);
|
||||
qglDisable (GL_BLEND);
|
||||
qglEnable (GL_ALPHA_TEST);
|
||||
|
||||
// copy the scene to texture
|
||||
GL_Bind(scenepp_texture);
|
||||
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
if (qglGetError())
|
||||
Con_Printf(CON_ERROR "GL Error after qglCopyTexImage2D\n");
|
||||
|
||||
// Here we apply the shaders - currently just waterwarp
|
||||
GLSlang_UseProgram(scenepp_ww_program);
|
||||
//keep the amp proportional to the size of the scene in texture coords
|
||||
// WARNING - waterwarp can change the amplitude, but if it's too big it'll exceed
|
||||
// the size determined by the edge texture, after which black bits will be shown.
|
||||
// Suggest clamping to a suitable range.
|
||||
if (r_waterwarp.value<0)
|
||||
{
|
||||
GLSlang_SetUniform1f(scenepp_ww_parm_ampscalef, (0.005 / 0.625) * vs*(-r_waterwarp.value));
|
||||
}
|
||||
else
|
||||
{
|
||||
GLSlang_SetUniform1f(scenepp_ww_parm_ampscalef, (0.005 / 0.625) * vs*r_waterwarp.value);
|
||||
}
|
||||
|
||||
if (qglGetError())
|
||||
Con_Printf("GL Error after GLSlang_UseProgram\n");
|
||||
|
||||
{
|
||||
float xmin, xmax, ymin, ymax;
|
||||
|
||||
xmin = cl.time * 0.25;
|
||||
ymin = cl.time * 0.25;
|
||||
xmax = xmin + 1;
|
||||
ymax = ymin + 1/vt*vs;
|
||||
|
||||
GL_EnableMultitexture();
|
||||
GL_Bind (scenepp_texture_warp);
|
||||
|
||||
GL_SelectTexture(mtexid1+1);
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
GL_Bind(scenepp_texture_edge);
|
||||
|
||||
qglBegin(GL_QUADS);
|
||||
|
||||
qglMTexCoord2fSGIS (mtexid0, 0, 0);
|
||||
qglMTexCoord2fSGIS (mtexid1, xmin, ymin);
|
||||
qglMTexCoord2fSGIS (mtexid1+1, 0, 0);
|
||||
qglVertex2f(0, 0);
|
||||
|
||||
qglMTexCoord2fSGIS (mtexid0, vs, 0);
|
||||
qglMTexCoord2fSGIS (mtexid1, xmax, ymin);
|
||||
qglMTexCoord2fSGIS (mtexid1+1, 1, 0);
|
||||
qglVertex2f(glwidth, 0);
|
||||
|
||||
qglMTexCoord2fSGIS (mtexid0, vs, vt);
|
||||
qglMTexCoord2fSGIS (mtexid1, xmax, ymax);
|
||||
qglMTexCoord2fSGIS (mtexid1+1, 1, 1);
|
||||
qglVertex2f(glwidth, glheight);
|
||||
|
||||
qglMTexCoord2fSGIS (mtexid0, 0, vt);
|
||||
qglMTexCoord2fSGIS (mtexid1, xmin, ymax);
|
||||
qglMTexCoord2fSGIS (mtexid1+1, 0, 1);
|
||||
qglVertex2f(0, glheight);
|
||||
|
||||
qglEnd();
|
||||
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
GL_SelectTexture(mtexid1);
|
||||
|
||||
GL_DisableMultitexture();
|
||||
}
|
||||
|
||||
// Disable shaders
|
||||
GLSlang_UseProgram(0);
|
||||
|
||||
// After all the post processing, pop the matrices
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPopMatrix();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPopMatrix();
|
||||
|
||||
if (qglGetError())
|
||||
Con_Printf("GL Error after drawing with shaderobjects\n");
|
||||
}
|
||||
R_RenderWaterWarp();
|
||||
|
||||
|
||||
|
||||
if (gl_motionblur.value>0 && gl_motionblur.value < 1 && qglCopyTexImage2D)
|
||||
{
|
||||
int vwidth = 1, vheight = 1;
|
||||
float vs, vt, cs, ct;
|
||||
|
||||
if (gl_config.arb_texture_non_power_of_two)
|
||||
{ //we can use any size, supposedly
|
||||
vwidth = glwidth;
|
||||
vheight = glheight;
|
||||
}
|
||||
else
|
||||
{ //limit the texture size to square and use padding.
|
||||
while (vwidth < glwidth)
|
||||
vwidth *= 2;
|
||||
while (vheight < glheight)
|
||||
vheight *= 2;
|
||||
}
|
||||
|
||||
qglViewport (glx, gly, glwidth, glheight);
|
||||
|
||||
GL_Bind(sceneblur_texture);
|
||||
|
||||
// go 2d
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
qglOrtho (0, glwidth, 0, glheight, -99999, 99999);
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
|
||||
//blend the last frame onto the scene
|
||||
//the maths is because our texture is over-sized (must be power of two)
|
||||
cs = vs = (float)glwidth / vwidth * 0.5;
|
||||
ct = vt = (float)glheight / vheight * 0.5;
|
||||
vs *= gl_motionblurscale.value;
|
||||
vt *= gl_motionblurscale.value;
|
||||
|
||||
qglDisable (GL_DEPTH_TEST);
|
||||
qglDisable (GL_CULL_FACE);
|
||||
qglDisable (GL_ALPHA_TEST);
|
||||
qglEnable(GL_BLEND);
|
||||
qglColor4f(1, 1, 1, gl_motionblur.value);
|
||||
qglBegin(GL_QUADS);
|
||||
qglTexCoord2f(cs-vs, ct-vt);
|
||||
qglVertex2f(0, 0);
|
||||
qglTexCoord2f(cs+vs, ct-vt);
|
||||
qglVertex2f(glwidth, 0);
|
||||
qglTexCoord2f(cs+vs, ct+vt);
|
||||
qglVertex2f(glwidth, glheight);
|
||||
qglTexCoord2f(cs-vs, ct+vt);
|
||||
qglVertex2f(0, glheight);
|
||||
qglEnd();
|
||||
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPopMatrix();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPopMatrix();
|
||||
|
||||
|
||||
//copy the image into the texture so that we can play with it next frame too!
|
||||
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
R_RenderMotionBlur();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue