mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Implement skyboxes.
The texture assignments are incorrect, but it's otherwise working.
This commit is contained in:
parent
8bcef272e6
commit
a66fcb8448
4 changed files with 163 additions and 22 deletions
|
@ -5,11 +5,12 @@ INCLUDES= -I$(top_srcdir)/include $(GLX_CFLAGS)
|
|||
|
||||
shader_src= \
|
||||
quake2d.frag quakebsp.frag quakebsp.vert quakeico.vert quakemdl.frag \
|
||||
quakemdl.vert quakeski.frag quakesky.vert quakespr.frag quakespr.vert \
|
||||
quaketrb.frag quaketxt.vert
|
||||
quakemdl.vert quakeskb.frag quakeski.frag quakesky.vert \
|
||||
quakespr.frag quakespr.vert quaketrb.frag quaketxt.vert
|
||||
shader_gen= \
|
||||
quake2d.fc quakebsp.fc quakebsp.vc quakeico.vc quakemdl.fc quakemdl.vc \
|
||||
quakeski.fc quakesky.vc quakespr.fc quakespr.vc quaketrb.fc quaketxt.vc
|
||||
quakeskb.fc quakeski.fc quakesky.vc quakespr.fc quakespr.vc quaketrb.fc \
|
||||
quaketxt.vc
|
||||
|
||||
glsl_src = \
|
||||
glsl_alias.c glsl_bsp.c glsl_draw.c glsl_lightmap.c glsl_main.c \
|
||||
|
|
|
@ -43,8 +43,10 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$";
|
|||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/image.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
#include "QF/vrect.h"
|
||||
|
||||
#include "QF/GLSL/defines.h"
|
||||
|
@ -92,6 +94,9 @@ static instsurf_t *free_instsurfs;
|
|||
static GLuint bsp_vbo;
|
||||
static mat4_t bsp_vp;
|
||||
|
||||
static GLuint skybox_tex;
|
||||
static qboolean skybox_loaded;
|
||||
|
||||
static const char quakebsp_vert[] =
|
||||
#include "quakebsp.vc"
|
||||
;
|
||||
|
@ -112,6 +117,10 @@ static const char quakeskyid_frag[] =
|
|||
#include "quakeski.fc"
|
||||
;
|
||||
|
||||
static const char quakeskybox_frag[] =
|
||||
#include "quakeskb.fc"
|
||||
;
|
||||
|
||||
static struct {
|
||||
int program;
|
||||
shaderparam_t mvp_matrix;
|
||||
|
@ -170,6 +179,20 @@ static struct {
|
|||
{"realtime", 1},
|
||||
};
|
||||
|
||||
static struct {
|
||||
int program;
|
||||
shaderparam_t mvp_matrix;
|
||||
shaderparam_t origin;
|
||||
shaderparam_t vertex;
|
||||
shaderparam_t sky;
|
||||
} quake_skybox = {
|
||||
0,
|
||||
{"mvp_mat", 1},
|
||||
{"origin", 1},
|
||||
{"vertex", 0},
|
||||
{"sky", 1},
|
||||
};
|
||||
|
||||
#define CHAIN_SURF_F2B(surf,chain) \
|
||||
do { \
|
||||
instsurf_t *inst = (surf)->instsurf; \
|
||||
|
@ -874,6 +897,35 @@ skyid_end (void)
|
|||
qfglBindBuffer (GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
skybox_begin (void)
|
||||
{
|
||||
Mat4Mult (glsl_projection, glsl_view, bsp_vp);
|
||||
|
||||
qfglUseProgram (quake_skybox.program);
|
||||
qfglEnableVertexAttribArray (quake_skybox.vertex.location);
|
||||
|
||||
qfglUniform3fv (quake_skybox.origin.location, 1, r_origin);
|
||||
|
||||
qfglUniform1i (quake_skybox.sky.location, 0);
|
||||
qfglActiveTexture (GL_TEXTURE0 + 0);
|
||||
qfglEnable (GL_TEXTURE_CUBE_MAP);
|
||||
qfglBindTexture (GL_TEXTURE_CUBE_MAP, skybox_tex);
|
||||
|
||||
qfglBindBuffer (GL_ARRAY_BUFFER, bsp_vbo);
|
||||
}
|
||||
|
||||
static void
|
||||
skybox_end (void)
|
||||
{
|
||||
qfglDisableVertexAttribArray (quake_skybox.vertex.location);
|
||||
|
||||
qfglActiveTexture (GL_TEXTURE0 + 0);
|
||||
qfglDisable (GL_TEXTURE_CUBE_MAP);
|
||||
|
||||
qfglBindBuffer (GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
add_surf_elements (texture_t *tex, instsurf_t *is,
|
||||
elechain_t **ec, elements_t **el)
|
||||
|
@ -1020,22 +1072,33 @@ R_DrawSky (void)
|
|||
texture_t *tex = 0;
|
||||
elechain_t *ec = 0;
|
||||
elements_t *el = 0;
|
||||
shaderparam_t *matrix;
|
||||
shaderparam_t *vertex;
|
||||
|
||||
if (!sky_chain)
|
||||
return;
|
||||
|
||||
skyid_begin ();
|
||||
if (skybox_loaded) {
|
||||
skybox_begin ();
|
||||
matrix = &quake_skybox.mvp_matrix;
|
||||
vertex = &quake_skybox.vertex;
|
||||
} else {
|
||||
skyid_begin ();
|
||||
matrix = &quake_skyid.mvp_matrix;
|
||||
vertex = &quake_skyid.vertex;
|
||||
}
|
||||
for (is = sky_chain; is; is = is->tex_chain) {
|
||||
surf = is->surface;
|
||||
if (tex != surf->texinfo->texture) {
|
||||
if (tex) {
|
||||
qfglActiveTexture (GL_TEXTURE0 + 0);
|
||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[0]);
|
||||
qfglActiveTexture (GL_TEXTURE0 + 1);
|
||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[1]);
|
||||
if (!skybox_loaded) {
|
||||
qfglActiveTexture (GL_TEXTURE0 + 0);
|
||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[0]);
|
||||
qfglActiveTexture (GL_TEXTURE0 + 1);
|
||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[1]);
|
||||
}
|
||||
for (ec = tex->elechain; ec; ec = ec->next)
|
||||
draw_elechain (ec, quake_skyid.mvp_matrix.location,
|
||||
quake_skyid.vertex.location, -1);
|
||||
draw_elechain (ec, matrix->location, vertex->location, -1);
|
||||
tex->elechain = 0;
|
||||
tex->elechain_tail = &tex->elechain;
|
||||
}
|
||||
|
@ -1044,17 +1107,21 @@ R_DrawSky (void)
|
|||
add_surf_elements (tex, is, &ec, &el);
|
||||
}
|
||||
if (tex) {
|
||||
qfglActiveTexture (GL_TEXTURE0 + 0);
|
||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[0]);
|
||||
qfglActiveTexture (GL_TEXTURE0 + 1);
|
||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[1]);
|
||||
if (!skybox_loaded) {
|
||||
qfglActiveTexture (GL_TEXTURE0 + 0);
|
||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[0]);
|
||||
qfglActiveTexture (GL_TEXTURE0 + 1);
|
||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[1]);
|
||||
}
|
||||
for (ec = tex->elechain; ec; ec = ec->next)
|
||||
draw_elechain (ec, quake_skyid.mvp_matrix.location,
|
||||
quake_skyid.vertex.location, -1);
|
||||
draw_elechain (ec, matrix->location, vertex->location, -1);
|
||||
tex->elechain = 0;
|
||||
tex->elechain_tail = &tex->elechain;
|
||||
}
|
||||
skyid_end ();
|
||||
if (skybox_loaded)
|
||||
skybox_end ();
|
||||
else
|
||||
skyid_end ();
|
||||
|
||||
sky_chain = 0;
|
||||
sky_chain_tail = &sky_chain;
|
||||
|
@ -1099,4 +1166,70 @@ R_InitBsp (void)
|
|||
GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.solid);
|
||||
GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.trans);
|
||||
GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.realtime);
|
||||
|
||||
frag = GL_CompileShader ("quakeskb.frag", quakeskybox_frag,
|
||||
GL_FRAGMENT_SHADER);
|
||||
quake_skybox.program = GL_LinkProgram ("quakeskybox", vert, frag);
|
||||
GL_ResolveShaderParam (quake_skybox.program, &quake_skybox.mvp_matrix);
|
||||
GL_ResolveShaderParam (quake_skybox.program, &quake_skybox.origin);
|
||||
GL_ResolveShaderParam (quake_skybox.program, &quake_skybox.vertex);
|
||||
GL_ResolveShaderParam (quake_skybox.program, &quake_skybox.sky);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
R_LoadSkys (const char *sky)
|
||||
{
|
||||
const char *name;
|
||||
int i;
|
||||
static const char *sky_suffix[] = { "ft", "bk", "lf", "rt", "up", "dn"};
|
||||
static int sky_target[] = {
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
|
||||
};
|
||||
|
||||
if (!sky || !*sky)
|
||||
sky = r_skyname->string;
|
||||
|
||||
if (!*sky || !strcasecmp (sky, "none")) {
|
||||
skybox_loaded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!skybox_tex)
|
||||
qfglGenTextures (1, &skybox_tex);
|
||||
|
||||
qfglBindTexture (GL_TEXTURE_CUBE_MAP, skybox_tex);
|
||||
|
||||
skybox_loaded = true;
|
||||
for (i = 0; i < 6; i++) {
|
||||
tex_t *tex;
|
||||
|
||||
tex = LoadImage (name = va ("env/%s%s", sky, sky_suffix[i]));
|
||||
if (!tex || tex->format < 3) { // FIXME pcx support
|
||||
Sys_MaskPrintf (SYS_GLSL, "Couldn't load %s\n", name);
|
||||
// also look in gfx/env, where Darkplaces looks for skies
|
||||
tex = LoadImage (name = va ("gfx/env/%s%s", sky, sky_suffix[i]));
|
||||
if (!tex || tex->format < 3) { // FIXME pcx support
|
||||
Sys_MaskPrintf (SYS_GLSL, "Couldn't load %s\n", name);
|
||||
skybox_loaded = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Sys_MaskPrintf (SYS_GLSL, "Loaded %s\n", name);
|
||||
qfglTexImage2D (sky_target[i], 0, tex->format == 3 ? GL_RGB : GL_RGBA,
|
||||
tex->width, tex->height, 0,
|
||||
tex->format == 3 ? GL_RGB : GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, tex->data);
|
||||
}
|
||||
qfglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
qfglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
qfglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
qfglTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
qfglGenerateMipmap (GL_TEXTURE_CUBE_MAP);
|
||||
}
|
||||
|
|
|
@ -229,11 +229,6 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
|
|||
R_BuildDisplayLists (models, num_models);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
R_LoadSkys (const char *sky)
|
||||
{
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
Fog_Update (float density, float red, float green, float blue, float time)
|
||||
{
|
||||
|
|
12
libs/video/renderer/glsl/quakeskb.frag
Normal file
12
libs/video/renderer/glsl/quakeskb.frag
Normal file
|
@ -0,0 +1,12 @@
|
|||
uniform samplerCube sky;
|
||||
|
||||
varying vec3 direction;
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
vec3 dir = direction;
|
||||
|
||||
dir *= inversesqrt (dot (dir, dir));
|
||||
gl_FragColor = textureCube(sky, dir);
|
||||
}
|
Loading…
Reference in a new issue