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
|
@ -70,6 +70,7 @@ qboolean mirror;
|
||||||
mplane_t *mirror_plane;
|
mplane_t *mirror_plane;
|
||||||
msurface_t *r_mirror_chain;
|
msurface_t *r_mirror_chain;
|
||||||
qboolean r_inmirror; //or out-of-body
|
qboolean r_inmirror; //or out-of-body
|
||||||
|
extern msurface_t *r_alpha_surfaces;
|
||||||
|
|
||||||
//
|
//
|
||||||
// view origin
|
// view origin
|
||||||
|
@ -121,6 +122,8 @@ cvar_t gl_maxdist = SCVAR("gl_maxdist", "8192");
|
||||||
extern cvar_t gl_contrast;
|
extern cvar_t gl_contrast;
|
||||||
extern cvar_t gl_mindist;
|
extern cvar_t gl_mindist;
|
||||||
|
|
||||||
|
extern cvar_t ffov;
|
||||||
|
|
||||||
extern cvar_t gl_motionblur;
|
extern cvar_t gl_motionblur;
|
||||||
extern cvar_t gl_motionblurscale;
|
extern cvar_t gl_motionblurscale;
|
||||||
|
|
||||||
|
@ -154,6 +157,12 @@ int scenepp_mt_parm_texture0i;
|
||||||
int scenepp_mt_parm_colorf;
|
int scenepp_mt_parm_colorf;
|
||||||
int scenepp_mt_parm_inverti;
|
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
|
// 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
|
// I put it here so that only this file need be changed when messing with the post
|
||||||
// processing shaders
|
// processing shaders
|
||||||
|
@ -223,6 +232,67 @@ void GL_InitSceneProcessingShaders_WaterWarp (void)
|
||||||
Con_Printf(CON_ERROR "GL Error initing shader object\n");
|
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)
|
void GL_InitSceneProcessingShaders_MenuTint(void)
|
||||||
{
|
{
|
||||||
char *vshader = "\
|
char *vshader = "\
|
||||||
|
@ -273,6 +343,7 @@ void GL_InitSceneProcessingShaders_MenuTint(void)
|
||||||
void GL_InitSceneProcessingShaders (void)
|
void GL_InitSceneProcessingShaders (void)
|
||||||
{
|
{
|
||||||
GL_InitSceneProcessingShaders_WaterWarp();
|
GL_InitSceneProcessingShaders_WaterWarp();
|
||||||
|
GL_InitFisheyeFov();
|
||||||
GL_InitSceneProcessingShaders_MenuTint();
|
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_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];
|
unsigned char pp_edge_tex[PP_AMP_TEX_SIZE*PP_AMP_TEX_SIZE*3];
|
||||||
|
|
||||||
|
scenepp_fisheye_texture = 0;
|
||||||
|
|
||||||
sceneblur_texture = GL_AllocNewTexture();
|
sceneblur_texture = GL_AllocNewTexture();
|
||||||
|
|
||||||
if (!gl_config.arb_shader_objects)
|
if (!gl_config.arb_shader_objects)
|
||||||
|
@ -1567,118 +1640,86 @@ void GLR_SetupFog (void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
static void R_RenderMotionBlur(void)
|
||||||
================
|
|
||||||
R_RenderView
|
|
||||||
|
|
||||||
r_refdef must be set before the first call
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
void GLR_RenderView (void)
|
|
||||||
{
|
{
|
||||||
extern msurface_t *r_alpha_surfaces;
|
int vwidth = 1, vheight = 1;
|
||||||
double time1 = 0, time2;
|
float vs, vt, cs, ct;
|
||||||
|
|
||||||
if (qglGetError())
|
if (gl_config.arb_texture_non_power_of_two)
|
||||||
Con_Printf("GL Error before drawing scene\n");
|
{ //we can use any size, supposedly
|
||||||
|
vwidth = glwidth;
|
||||||
if (r_norefresh.value || !glwidth || !glheight)
|
vheight = glheight;
|
||||||
{
|
|
||||||
GL_DoSwap();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
|
|
||||||
if (!r_worldentity.model || !cl.worldmodel)
|
|
||||||
{
|
|
||||||
GL_DoSwap();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Sys_Error ("R_RenderView: NULL worldmodel");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (qglPNTrianglesiATI)
|
|
||||||
{
|
|
||||||
if (gl_ati_truform_type.value)
|
|
||||||
{ //linear
|
|
||||||
qglPNTrianglesiATI(GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI);
|
|
||||||
qglPNTrianglesiATI(GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //quadric
|
{ //limit the texture size to square and use padding.
|
||||||
qglPNTrianglesiATI(GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI);
|
while (vwidth < glwidth)
|
||||||
qglPNTrianglesiATI(GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI);
|
vwidth *= 2;
|
||||||
}
|
while (vheight < glheight)
|
||||||
qglPNTrianglesfATI(GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, gl_ati_truform_tesselation.value);
|
vheight *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gl_finish.value)
|
qglViewport (glx, gly, glwidth, glheight);
|
||||||
{
|
|
||||||
RSpeedMark();
|
|
||||||
qglFinish ();
|
|
||||||
RSpeedEnd(RSPEED_FINISH);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r_speeds.value)
|
GL_Bind(sceneblur_texture);
|
||||||
{
|
|
||||||
time1 = Sys_DoubleTime ();
|
|
||||||
c_brush_polys = 0;
|
|
||||||
c_alias_polys = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mirror = false;
|
// go 2d
|
||||||
|
qglMatrixMode(GL_PROJECTION);
|
||||||
|
qglPushMatrix();
|
||||||
|
qglLoadIdentity ();
|
||||||
|
qglOrtho (0, glwidth, 0, glheight, -99999, 99999);
|
||||||
|
qglMatrixMode(GL_MODELVIEW);
|
||||||
|
qglPushMatrix();
|
||||||
|
qglLoadIdentity ();
|
||||||
|
|
||||||
R_Clear ();
|
//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;
|
||||||
|
|
||||||
// GLR_SetupFog ();
|
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();
|
||||||
|
|
||||||
r_alpha_surfaces = NULL;
|
qglMatrixMode(GL_PROJECTION);
|
||||||
|
qglPopMatrix();
|
||||||
|
qglMatrixMode(GL_MODELVIEW);
|
||||||
|
qglPopMatrix();
|
||||||
|
|
||||||
GL_SetShaderState2D(false);
|
|
||||||
|
|
||||||
// render normal view
|
//copy the image into the texture so that we can play with it next frame too!
|
||||||
R_RenderScene ();
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
GLR_DrawWaterSurfaces ();
|
static void R_RenderWaterWarp(void)
|
||||||
GLR_DrawAlphaSurfaces ();
|
{
|
||||||
|
|
||||||
// render mirror view
|
|
||||||
R_Mirror ();
|
|
||||||
|
|
||||||
R_BloomBlend();
|
|
||||||
|
|
||||||
R_PolyBlend ();
|
|
||||||
|
|
||||||
// qglDisable(GL_FOG);
|
|
||||||
|
|
||||||
if (r_speeds.value)
|
|
||||||
{
|
|
||||||
// glFinish ();
|
|
||||||
time2 = Sys_DoubleTime ();
|
|
||||||
|
|
||||||
RQuantAdd(RQUANT_MSECS, (int)((time2-time1)*1000000));
|
|
||||||
|
|
||||||
RQuantAdd(RQUANT_WPOLYS, c_brush_polys);
|
|
||||||
RQuantAdd(RQUANT_EPOLYS, c_alias_polys);
|
|
||||||
// Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qglGetError())
|
|
||||||
Con_Printf("GL Error drawing scene\n");
|
|
||||||
|
|
||||||
if (r_refdef.flags & Q2RDF_NOWORLDMODEL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// SCENE POST PROCESSING
|
|
||||||
// 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 vwidth = 1, vheight = 1;
|
||||||
float vs, vt;
|
float vs, vt;
|
||||||
|
|
||||||
// get the powers of 2 for the size of the texture that will hold the scene
|
// 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)
|
while (vwidth < glwidth)
|
||||||
{
|
{
|
||||||
vwidth *= 2;
|
vwidth *= 2;
|
||||||
|
@ -1687,6 +1728,7 @@ void GLR_RenderView (void)
|
||||||
{
|
{
|
||||||
vheight *= 2;
|
vheight *= 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// get the maxtexcoords while we're at it
|
// get the maxtexcoords while we're at it
|
||||||
vs = glwidth / vwidth;
|
vs = glwidth / vwidth;
|
||||||
|
@ -1795,31 +1837,173 @@ void GLR_RenderView (void)
|
||||||
|
|
||||||
if (qglGetError())
|
if (qglGetError())
|
||||||
Con_Printf("GL Error after drawing with shaderobjects\n");
|
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)
|
||||||
if (gl_motionblur.value>0 && gl_motionblur.value < 1 && qglCopyTexImage2D)
|
return false;
|
||||||
{
|
|
||||||
int vwidth = 1, vheight = 1;
|
|
||||||
float vs, vt, cs, ct;
|
|
||||||
|
|
||||||
if (gl_config.arb_texture_non_power_of_two)
|
if (gl_config.arb_texture_non_power_of_two)
|
||||||
{ //we can use any size, supposedly
|
{
|
||||||
vwidth = glwidth;
|
if (glwidth < glheight)
|
||||||
vheight = glheight;
|
cmapsize = glwidth;
|
||||||
|
else
|
||||||
|
cmapsize = glheight;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //limit the texture size to square and use padding.
|
{
|
||||||
while (vwidth < glwidth)
|
while (cmapsize > glwidth || cmapsize > glheight)
|
||||||
vwidth *= 2;
|
{
|
||||||
while (vheight < glheight)
|
cmapsize /= 2;
|
||||||
vheight *= 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);
|
qglViewport (glx, gly, glwidth, glheight);
|
||||||
|
|
||||||
GL_Bind(sceneblur_texture);
|
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
|
// go 2d
|
||||||
qglMatrixMode(GL_PROJECTION);
|
qglMatrixMode(GL_PROJECTION);
|
||||||
|
@ -1830,26 +2014,18 @@ void GLR_RenderView (void)
|
||||||
qglPushMatrix();
|
qglPushMatrix();
|
||||||
qglLoadIdentity ();
|
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_DEPTH_TEST);
|
||||||
qglDisable (GL_CULL_FACE);
|
qglDisable (GL_CULL_FACE);
|
||||||
qglDisable (GL_ALPHA_TEST);
|
qglDisable (GL_ALPHA_TEST);
|
||||||
qglEnable(GL_BLEND);
|
qglDisable(GL_BLEND);
|
||||||
qglColor4f(1, 1, 1, gl_motionblur.value);
|
|
||||||
qglBegin(GL_QUADS);
|
qglBegin(GL_QUADS);
|
||||||
qglTexCoord2f(cs-vs, ct-vt);
|
qglTexCoord2f(-0.5, -0.5);
|
||||||
qglVertex2f(0, 0);
|
qglVertex2f(0, 0);
|
||||||
qglTexCoord2f(cs+vs, ct-vt);
|
qglTexCoord2f(0.5, -0.5);
|
||||||
qglVertex2f(glwidth, 0);
|
qglVertex2f(glwidth, 0);
|
||||||
qglTexCoord2f(cs+vs, ct+vt);
|
qglTexCoord2f(0.5, 0.5);
|
||||||
qglVertex2f(glwidth, glheight);
|
qglVertex2f(glwidth, glheight);
|
||||||
qglTexCoord2f(cs-vs, ct+vt);
|
qglTexCoord2f(-0.5, 0.5);
|
||||||
qglVertex2f(0, glheight);
|
qglVertex2f(0, glheight);
|
||||||
qglEnd();
|
qglEnd();
|
||||||
|
|
||||||
|
@ -1858,12 +2034,132 @@ void GLR_RenderView (void)
|
||||||
qglMatrixMode(GL_MODELVIEW);
|
qglMatrixMode(GL_MODELVIEW);
|
||||||
qglPopMatrix();
|
qglPopMatrix();
|
||||||
|
|
||||||
|
qglDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
||||||
|
qglEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
//copy the image into the texture so that we can play with it next frame too!
|
GLSlang_UseProgram(0);
|
||||||
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0);
|
|
||||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
return true;
|
||||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
}
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
R_RenderView
|
||||||
|
|
||||||
|
r_refdef must be set before the first call
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void GLR_RenderView (void)
|
||||||
|
{
|
||||||
|
double time1 = 0, time2;
|
||||||
|
|
||||||
|
if (qglGetError())
|
||||||
|
Con_Printf("GL Error before drawing scene\n");
|
||||||
|
|
||||||
|
if (r_norefresh.value || !glwidth || !glheight)
|
||||||
|
{
|
||||||
|
GL_DoSwap();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
|
||||||
|
if (!r_worldentity.model || !cl.worldmodel)
|
||||||
|
{
|
||||||
|
GL_DoSwap();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Sys_Error ("R_RenderView: NULL worldmodel");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (qglPNTrianglesiATI)
|
||||||
|
{
|
||||||
|
if (gl_ati_truform_type.value)
|
||||||
|
{ //linear
|
||||||
|
qglPNTrianglesiATI(GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI);
|
||||||
|
qglPNTrianglesiATI(GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ //quadric
|
||||||
|
qglPNTrianglesiATI(GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI);
|
||||||
|
qglPNTrianglesiATI(GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI);
|
||||||
|
}
|
||||||
|
qglPNTrianglesfATI(GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, gl_ati_truform_tesselation.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gl_finish.value)
|
||||||
|
{
|
||||||
|
RSpeedMark();
|
||||||
|
qglFinish ();
|
||||||
|
RSpeedEnd(RSPEED_FINISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r_speeds.value)
|
||||||
|
{
|
||||||
|
time1 = Sys_DoubleTime ();
|
||||||
|
c_brush_polys = 0;
|
||||||
|
c_alias_polys = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ffov.value && cls.allow_fish && !(r_refdef.flags & Q2RDF_NOWORLDMODEL) && R_RenderScene_Fish())
|
||||||
|
{
|
||||||
|
//fisheye does its own rendering.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mirror = false;
|
||||||
|
|
||||||
|
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 ();
|
||||||
|
}
|
||||||
|
|
||||||
|
R_BloomBlend();
|
||||||
|
|
||||||
|
R_PolyBlend ();
|
||||||
|
|
||||||
|
// qglDisable(GL_FOG);
|
||||||
|
|
||||||
|
if (r_speeds.value)
|
||||||
|
{
|
||||||
|
// glFinish ();
|
||||||
|
time2 = Sys_DoubleTime ();
|
||||||
|
|
||||||
|
RQuantAdd(RQUANT_MSECS, (int)((time2-time1)*1000000));
|
||||||
|
|
||||||
|
RQuantAdd(RQUANT_WPOLYS, c_brush_polys);
|
||||||
|
RQuantAdd(RQUANT_EPOLYS, c_alias_polys);
|
||||||
|
// Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qglGetError())
|
||||||
|
Con_Printf("GL Error drawing scene\n");
|
||||||
|
|
||||||
|
if (r_refdef.flags & Q2RDF_NOWORLDMODEL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// SCENE POST PROCESSING
|
||||||
|
// 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))
|
||||||
|
R_RenderWaterWarp();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (gl_motionblur.value>0 && gl_motionblur.value < 1 && qglCopyTexImage2D)
|
||||||
|
R_RenderMotionBlur();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue