mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-18 09:51:40 +00:00
[glsl] Implement screen warp when in liquids
Finally, after a decade :P Looks pretty good, too, and is (almost) properly scaled to the resolution (almost because the effect is a little squashed, but I think the sw renderer does the same).
This commit is contained in:
parent
e263521330
commit
18aae8205e
9 changed files with 240 additions and 2 deletions
|
@ -57,6 +57,8 @@ QFGL_NEED (void, glDepthMask, (GLboolean flag))
|
||||||
QFGL_NEED (void, glDepthRangef, (GLclampf zNear, GLclampf zFar))
|
QFGL_NEED (void, glDepthRangef, (GLclampf zNear, GLclampf zFar))
|
||||||
QFGL_NEED (void, glDetachShader, (GLuint program, GLuint shader))
|
QFGL_NEED (void, glDetachShader, (GLuint program, GLuint shader))
|
||||||
QFGL_NEED (void, glDisable, (GLenum cap))
|
QFGL_NEED (void, glDisable, (GLenum cap))
|
||||||
|
QFGL_NEED (void, glCreateVertexArrays, (GLsizei n, GLuint *arrays))
|
||||||
|
QFGL_NEED (void, glBindVertexArray, (GLuint array))
|
||||||
QFGL_NEED (void, glDisableVertexAttribArray, (GLuint index))
|
QFGL_NEED (void, glDisableVertexAttribArray, (GLuint index))
|
||||||
QFGL_NEED (void, glDrawArrays, (GLenum mode, GLint first, GLsizei count))
|
QFGL_NEED (void, glDrawArrays, (GLenum mode, GLint first, GLsizei count))
|
||||||
QFGL_NEED (void, glDrawElements, (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices))
|
QFGL_NEED (void, glDrawElements, (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices))
|
||||||
|
|
37
include/QF/GLSL/qf_warp.h
Normal file
37
include/QF/GLSL/qf_warp.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
qf_warp.h
|
||||||
|
|
||||||
|
GLSL screen warp
|
||||||
|
|
||||||
|
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
|
||||||
|
|
||||||
|
Author: Bill Currie <bill@taniwha.org>
|
||||||
|
Date: 2022/3/24
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to:
|
||||||
|
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330
|
||||||
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
*/
|
||||||
|
#ifndef __QF_GLSL_qf_warp_h
|
||||||
|
#define __QF_GLSL_qf_warp_h
|
||||||
|
|
||||||
|
void glsl_InitWarp (void);
|
||||||
|
struct framebuffer_s;
|
||||||
|
void glsl_WarpScreen (struct framebuffer_s *fb);
|
||||||
|
|
||||||
|
#endif//__QF_GLSL_qf_warp_h
|
|
@ -109,6 +109,7 @@ include_qf_glsl = \
|
||||||
include/QF/GLSL/qf_sprite.h \
|
include/QF/GLSL/qf_sprite.h \
|
||||||
include/QF/GLSL/qf_textures.h \
|
include/QF/GLSL/qf_textures.h \
|
||||||
include/QF/GLSL/qf_vid.h \
|
include/QF/GLSL/qf_vid.h \
|
||||||
|
include/QF/GLSL/qf_warp.h \
|
||||||
include/QF/GLSL/types.h
|
include/QF/GLSL/types.h
|
||||||
|
|
||||||
include_qf_input = \
|
include_qf_input = \
|
||||||
|
|
|
@ -118,6 +118,7 @@ libs_video_renderer_librender_glsl_la_SOURCES = \
|
||||||
libs/video/renderer/glsl/glsl_shader.c \
|
libs/video/renderer/glsl/glsl_shader.c \
|
||||||
libs/video/renderer/glsl/glsl_sprite.c \
|
libs/video/renderer/glsl/glsl_sprite.c \
|
||||||
libs/video/renderer/glsl/glsl_textures.c \
|
libs/video/renderer/glsl/glsl_textures.c \
|
||||||
|
libs/video/renderer/glsl/glsl_warp.c \
|
||||||
libs/video/renderer/glsl/qfglsl.c \
|
libs/video/renderer/glsl/qfglsl.c \
|
||||||
libs/video/renderer/glsl/quakeforge.glsl \
|
libs/video/renderer/glsl/quakeforge.glsl \
|
||||||
libs/video/renderer/glsl/vid_common_glsl.c
|
libs/video/renderer/glsl/vid_common_glsl.c
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include "QF/GLSL/qf_particles.h"
|
#include "QF/GLSL/qf_particles.h"
|
||||||
#include "QF/GLSL/qf_sprite.h"
|
#include "QF/GLSL/qf_sprite.h"
|
||||||
#include "QF/GLSL/qf_textures.h"
|
#include "QF/GLSL/qf_textures.h"
|
||||||
|
#include "QF/GLSL/qf_warp.h"
|
||||||
|
|
||||||
#include "mod_internal.h"
|
#include "mod_internal.h"
|
||||||
#include "r_internal.h"
|
#include "r_internal.h"
|
||||||
|
@ -211,6 +212,7 @@ glsl_R_Init (void)
|
||||||
glsl_R_InitIQM ();
|
glsl_R_InitIQM ();
|
||||||
glsl_R_InitSprites ();
|
glsl_R_InitSprites ();
|
||||||
glsl_R_InitParticles ();
|
glsl_R_InitParticles ();
|
||||||
|
glsl_InitWarp ();
|
||||||
Skin_Init ();
|
Skin_Init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
114
libs/video/renderer/glsl/glsl_warp.c
Normal file
114
libs/video/renderer/glsl/glsl_warp.c
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
glsl_warp.c
|
||||||
|
|
||||||
|
GLSL screen warp
|
||||||
|
|
||||||
|
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
|
||||||
|
|
||||||
|
Author: Bill Currie <bill@taniwha.org>
|
||||||
|
Date: 2022/3/24
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to:
|
||||||
|
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330
|
||||||
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRINGS_H
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "QF/cvar.h"
|
||||||
|
#include "QF/render.h"
|
||||||
|
#include "QF/sys.h"
|
||||||
|
|
||||||
|
#include "QF/GLSL/defines.h"
|
||||||
|
#include "QF/GLSL/funcs.h"
|
||||||
|
#include "QF/GLSL/qf_vid.h"
|
||||||
|
#include "QF/GLSL/qf_warp.h"
|
||||||
|
|
||||||
|
#include "r_internal.h"
|
||||||
|
#include "vid_gl.h"
|
||||||
|
|
||||||
|
static const char *warp_vert_effects[] =
|
||||||
|
{
|
||||||
|
"QuakeForge.Vertex.fstri",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *warp_frag_effects[] =
|
||||||
|
{
|
||||||
|
"QuakeForge.Math.const",
|
||||||
|
"QuakeForge.Fragment.screen.warp",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
int program;
|
||||||
|
GLuint vao;
|
||||||
|
shaderparam_t screenTex;
|
||||||
|
shaderparam_t time;
|
||||||
|
} warp = {
|
||||||
|
.screenTex = {"screenTex", 1},
|
||||||
|
.time = {"time", 1},
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
glsl_InitWarp (void)
|
||||||
|
{
|
||||||
|
shader_t *vert_shader, *frag_shader;
|
||||||
|
int vert;
|
||||||
|
int frag;
|
||||||
|
|
||||||
|
vert_shader = GLSL_BuildShader (warp_vert_effects);
|
||||||
|
frag_shader = GLSL_BuildShader (warp_frag_effects);
|
||||||
|
vert = GLSL_CompileShader ("scrwarp.vert", vert_shader, GL_VERTEX_SHADER);
|
||||||
|
frag = GLSL_CompileShader ("scrwarp.frag", frag_shader, GL_FRAGMENT_SHADER);
|
||||||
|
warp.program = GLSL_LinkProgram ("scrwarp", vert, frag);
|
||||||
|
GLSL_ResolveShaderParam (warp.program, &warp.screenTex);
|
||||||
|
GLSL_ResolveShaderParam (warp.program, &warp.time);
|
||||||
|
GLSL_FreeShader (vert_shader);
|
||||||
|
GLSL_FreeShader (frag_shader);
|
||||||
|
|
||||||
|
qfeglCreateVertexArrays (1, &warp.vao);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glsl_WarpScreen (framebuffer_t *fb)
|
||||||
|
{
|
||||||
|
qfeglUseProgram (warp.program);
|
||||||
|
|
||||||
|
qfeglUniform1f (warp.time.location, vr_data.realtime);
|
||||||
|
|
||||||
|
gl_framebuffer_t *buffer = fb->buffer;
|
||||||
|
qfeglActiveTexture (GL_TEXTURE0 + 0);
|
||||||
|
qfeglBindTexture (GL_TEXTURE_2D, buffer->color);
|
||||||
|
|
||||||
|
qfeglBindVertexArray (warp.vao);
|
||||||
|
qfeglDrawArrays (GL_TRIANGLES, 0, 3);
|
||||||
|
qfeglBindVertexArray (0);
|
||||||
|
|
||||||
|
qfeglActiveTexture (GL_TEXTURE0 + 0);
|
||||||
|
qfeglDisable (GL_TEXTURE_2D);
|
||||||
|
}
|
|
@ -551,3 +551,38 @@ main (void)
|
||||||
col = texture2D (texture, st) * color * vec4 (l, 1.0);
|
col = texture2D (texture, st) * color * vec4 (l, 1.0);
|
||||||
gl_FragColor = fogBlend (col);
|
gl_FragColor = fogBlend (col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Vertex.fstri
|
||||||
|
#version 130
|
||||||
|
|
||||||
|
out vec2 uv;
|
||||||
|
|
||||||
|
void
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
// quake uses clockwise triangle order
|
||||||
|
float x = (gl_VertexID & 2);
|
||||||
|
float y = (gl_VertexID & 1);
|
||||||
|
uv = vec2(x, y*2);
|
||||||
|
gl_Position = vec4 (2, 4, 0, 0) * vec4 (x, y, 0, 0) - vec4 (1, 1, 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Fragment.screen.warp
|
||||||
|
|
||||||
|
uniform sampler2D screenTex;
|
||||||
|
uniform float time;
|
||||||
|
|
||||||
|
in vec2 uv;
|
||||||
|
|
||||||
|
const float S = 0.15625;
|
||||||
|
const float F = 2.5;
|
||||||
|
const float A = 0.01;
|
||||||
|
const vec2 B = vec2 (1, 1);
|
||||||
|
|
||||||
|
void
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
uv = uv * (1.0 - 2.0*A) + A * (B + sin ((time * S + F * uv.yx) * 2.0*PI));
|
||||||
|
vec4 c = texture2D (screenTex, uv);
|
||||||
|
gl_FragColor = c;//vec4(uv, c.x, 1);
|
||||||
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "QF/GLSL/qf_main.h"
|
#include "QF/GLSL/qf_main.h"
|
||||||
#include "QF/GLSL/qf_particles.h"
|
#include "QF/GLSL/qf_particles.h"
|
||||||
#include "QF/GLSL/qf_vid.h"
|
#include "QF/GLSL/qf_vid.h"
|
||||||
|
#include "QF/GLSL/qf_warp.h"
|
||||||
|
|
||||||
#include "mod_internal.h"
|
#include "mod_internal.h"
|
||||||
#include "r_internal.h"
|
#include "r_internal.h"
|
||||||
|
@ -229,6 +230,15 @@ glsl_draw_transparent (void)
|
||||||
static void
|
static void
|
||||||
glsl_post_process (framebuffer_t *src)
|
glsl_post_process (framebuffer_t *src)
|
||||||
{
|
{
|
||||||
|
qfeglBindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||||
|
if (r_dowarp) {
|
||||||
|
glsl_WarpScreen (src);
|
||||||
|
|
||||||
|
gl_framebuffer_t *buffer = src->buffer;
|
||||||
|
qfeglBindFramebuffer (GL_FRAMEBUFFER, buffer->handle);
|
||||||
|
qfeglClear (GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
qfeglBindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -258,12 +268,49 @@ glsl_create_cube_map (int size)
|
||||||
static framebuffer_t *
|
static framebuffer_t *
|
||||||
glsl_create_frame_buffer (int width, int height)
|
glsl_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;
|
||||||
|
qfeglGenFramebuffers (1, &buffer->handle);
|
||||||
|
|
||||||
|
GLuint tex[2];
|
||||||
|
qfeglGenTextures (2, tex);
|
||||||
|
|
||||||
|
buffer->color = tex[0];
|
||||||
|
buffer->depth = tex[1];
|
||||||
|
|
||||||
|
qfeglBindTexture (GL_TEXTURE_2D, buffer->color);
|
||||||
|
qfeglTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
qfeglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
qfeglBindTexture (GL_TEXTURE_2D, buffer->depth);
|
||||||
|
qfeglTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0,
|
||||||
|
GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
||||||
|
|
||||||
|
qfeglBindFramebuffer (GL_FRAMEBUFFER, buffer->handle);
|
||||||
|
qfeglFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
|
GL_TEXTURE_2D, buffer->color, 0);
|
||||||
|
qfeglFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||||
|
GL_TEXTURE_2D, buffer->depth, 0);
|
||||||
|
|
||||||
|
qfeglBindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||||
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
glsl_bind_framebuffer (framebuffer_t *framebuffer)
|
glsl_bind_framebuffer (framebuffer_t *framebuffer)
|
||||||
{
|
{
|
||||||
|
gl_framebuffer_t *buffer = framebuffer->buffer;
|
||||||
|
qfeglBindFramebuffer (GL_FRAMEBUFFER, buffer->handle);
|
||||||
|
|
||||||
|
vrect_t r = { 0, 0, framebuffer->width, framebuffer->height };
|
||||||
|
R_SetVrect (&r, &r_refdef.vrect, 0);
|
||||||
|
R_ViewChanged ();
|
||||||
}
|
}
|
||||||
|
|
||||||
vid_render_funcs_t glsl_vid_render_funcs = {
|
vid_render_funcs_t glsl_vid_render_funcs = {
|
||||||
|
|
|
@ -189,7 +189,6 @@ glx_choose_visual (gl_ctx_t *ctx)
|
||||||
Sys_Error ("Error couldn't get an RGB, Double-buffered, Depth visual");
|
Sys_Error ("Error couldn't get an RGB, Double-buffered, Depth visual");
|
||||||
}
|
}
|
||||||
x_vis = x_visinfo->visual;
|
x_vis = x_visinfo->visual;
|
||||||
printf ("%p\n", x_vis);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue