mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-29 23:52:22 +00:00
[gl] Implement screen warping for liquids
It's not the most efficient code (uses sin() directly), but at least it works (and with about 75% cpu headroom at 72fps on my machine).
This commit is contained in:
parent
a0adca011f
commit
12776e487a
3 changed files with 98 additions and 4 deletions
|
@ -56,4 +56,7 @@ void gl_R_AddTexture (struct texture_s *tx);
|
||||||
void gl_R_ClearTextures (void);
|
void gl_R_ClearTextures (void);
|
||||||
void gl_R_InitSurfaceChains (struct mod_brush_s *brush);
|
void gl_R_InitSurfaceChains (struct mod_brush_s *brush);
|
||||||
|
|
||||||
|
struct framebuffer_s;
|
||||||
|
void gl_WarpScreen (struct framebuffer_s *fb);
|
||||||
|
|
||||||
#endif // __QF_GL_rsurf_h
|
#endif // __QF_GL_rsurf_h
|
||||||
|
|
|
@ -31,12 +31,13 @@
|
||||||
#include "QF/cvar.h"
|
#include "QF/cvar.h"
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
|
|
||||||
#include "r_internal.h"
|
|
||||||
|
|
||||||
#include "QF/GL/defines.h"
|
#include "QF/GL/defines.h"
|
||||||
#include "QF/GL/funcs.h"
|
#include "QF/GL/funcs.h"
|
||||||
#include "QF/GL/qf_rsurf.h"
|
#include "QF/GL/qf_rsurf.h"
|
||||||
|
|
||||||
|
#include "r_internal.h"
|
||||||
|
#include "vid_gl.h"
|
||||||
|
|
||||||
// speed up sin calculations - Ed
|
// speed up sin calculations - Ed
|
||||||
static float turbsin[] = {
|
static float turbsin[] = {
|
||||||
# include "gl_warp_sin.h"
|
# include "gl_warp_sin.h"
|
||||||
|
@ -81,3 +82,59 @@ GL_EmitWaterPolys (msurface_t *surf)
|
||||||
qfglEnd ();
|
qfglEnd ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float S = 0.15625;
|
||||||
|
const float F = 2.5;
|
||||||
|
const float A = 0.01;
|
||||||
|
|
||||||
|
static void
|
||||||
|
warp_uv (float *uv, float time)
|
||||||
|
{
|
||||||
|
float p1 = (time * S + F * uv[1]) * 2 * M_PI;
|
||||||
|
float p2 = (time * S + F * uv[0]) * 2 * M_PI;
|
||||||
|
uv[0] = uv[0] * (1 - 2 * A) + A * (1 + sin (p1));
|
||||||
|
uv[1] = uv[1] * (1 - 2 * A) + A * (1 + sin (p2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gl_WarpScreen (framebuffer_t *fb)
|
||||||
|
{
|
||||||
|
gl_framebuffer_t *buffer = fb->buffer;
|
||||||
|
|
||||||
|
qfglMatrixMode (GL_PROJECTION);
|
||||||
|
qfglLoadIdentity ();
|
||||||
|
qfglOrtho (0, r_refdef.vrect.width, r_refdef.vrect.height, 0, -9999, 9999);
|
||||||
|
qfglMatrixMode (GL_MODELVIEW);
|
||||||
|
qfglLoadIdentity ();
|
||||||
|
qfglColor3ubv (color_white);
|
||||||
|
|
||||||
|
qfglDisable (GL_DEPTH_TEST);
|
||||||
|
qfglFrontFace (GL_CCW);
|
||||||
|
|
||||||
|
qfglBindTexture (GL_TEXTURE_2D, buffer->color);
|
||||||
|
|
||||||
|
int base_x = r_refdef.vrect.x;
|
||||||
|
int base_y = r_refdef.vrect.y;
|
||||||
|
int width = r_refdef.vrect.width;
|
||||||
|
int height = r_refdef.vrect.height;
|
||||||
|
|
||||||
|
float time = vr_data.realtime;
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y += 40) {
|
||||||
|
qfglBegin (GL_QUAD_STRIP);
|
||||||
|
for (int x = 0; x <= width; x+= 40) {
|
||||||
|
int y2 = y + 40;
|
||||||
|
int xy1[] = { base_x + x, base_y + y };
|
||||||
|
int xy2[] = { base_x + x, base_y + y2};
|
||||||
|
float uv1[] = { (float) x / width, 1 - (float) y / height };
|
||||||
|
float uv2[] = { (float) x / width, 1 - (float) y2 / height };
|
||||||
|
warp_uv (uv1, time);
|
||||||
|
warp_uv (uv2, time);
|
||||||
|
qfglTexCoord2fv (uv2);
|
||||||
|
qfglVertex2iv (xy2);
|
||||||
|
qfglTexCoord2fv (uv1);
|
||||||
|
qfglVertex2iv (xy1);
|
||||||
|
}
|
||||||
|
qfglEnd ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -276,7 +276,7 @@ gl_post_process (framebuffer_t *src)
|
||||||
if (scr_fisheye->int_val) {
|
if (scr_fisheye->int_val) {
|
||||||
gl_FisheyeScreen (src);
|
gl_FisheyeScreen (src);
|
||||||
} else if (r_dowarp) {
|
} else if (r_dowarp) {
|
||||||
//gl_WarpScreen (src);
|
gl_WarpScreen (src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +367,41 @@ gl_create_cube_map (int side)
|
||||||
static framebuffer_t *
|
static framebuffer_t *
|
||||||
gl_create_frame_buffer (int width, int height)
|
gl_create_frame_buffer (int width, int height)
|
||||||
{
|
{
|
||||||
Sys_Error ("not implemented");
|
size_t size = sizeof (framebuffer_t) + sizeof (gl_framebuffer_t);
|
||||||
|
|
||||||
|
framebuffer_t *fb = malloc (size);
|
||||||
|
fb->width = width;
|
||||||
|
fb->height = height;
|
||||||
|
__auto_type buffer = (gl_framebuffer_t *) &fb[1];
|
||||||
|
fb->buffer = buffer;
|
||||||
|
qfglGenFramebuffers (1, &buffer->handle);
|
||||||
|
|
||||||
|
GLuint tex[2];
|
||||||
|
qfglGenTextures (2, tex);
|
||||||
|
|
||||||
|
buffer->color = tex[0];
|
||||||
|
buffer->depth = tex[1];
|
||||||
|
|
||||||
|
qfglBindTexture (GL_TEXTURE_2D, buffer->color);
|
||||||
|
qfglTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
qfglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
qfglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
qfglBindTexture (GL_TEXTURE_2D, buffer->depth);
|
||||||
|
qfglTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0,
|
||||||
|
GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
||||||
|
qfglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
qfglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
qfglBindFramebuffer (GL_FRAMEBUFFER, buffer->handle);
|
||||||
|
qfglFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
|
GL_TEXTURE_2D, buffer->color, 0);
|
||||||
|
qfglFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||||
|
GL_TEXTURE_2D, buffer->depth, 0);
|
||||||
|
|
||||||
|
qfglBindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||||
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue