mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-22 11:41:38 +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= \
|
shader_src= \
|
||||||
quake2d.frag quakebsp.frag quakebsp.vert quakeico.vert quakemdl.frag \
|
quake2d.frag quakebsp.frag quakebsp.vert quakeico.vert quakemdl.frag \
|
||||||
quakemdl.vert quakeski.frag quakesky.vert quakespr.frag quakespr.vert \
|
quakemdl.vert quakeskb.frag quakeski.frag quakesky.vert \
|
||||||
quaketrb.frag quaketxt.vert
|
quakespr.frag quakespr.vert quaketrb.frag quaketxt.vert
|
||||||
shader_gen= \
|
shader_gen= \
|
||||||
quake2d.fc quakebsp.fc quakebsp.vc quakeico.vc quakemdl.fc quakemdl.vc \
|
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_src = \
|
||||||
glsl_alias.c glsl_bsp.c glsl_draw.c glsl_lightmap.c glsl_main.c \
|
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/cvar.h"
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
|
#include "QF/image.h"
|
||||||
#include "QF/render.h"
|
#include "QF/render.h"
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
|
#include "QF/va.h"
|
||||||
#include "QF/vrect.h"
|
#include "QF/vrect.h"
|
||||||
|
|
||||||
#include "QF/GLSL/defines.h"
|
#include "QF/GLSL/defines.h"
|
||||||
|
@ -92,6 +94,9 @@ static instsurf_t *free_instsurfs;
|
||||||
static GLuint bsp_vbo;
|
static GLuint bsp_vbo;
|
||||||
static mat4_t bsp_vp;
|
static mat4_t bsp_vp;
|
||||||
|
|
||||||
|
static GLuint skybox_tex;
|
||||||
|
static qboolean skybox_loaded;
|
||||||
|
|
||||||
static const char quakebsp_vert[] =
|
static const char quakebsp_vert[] =
|
||||||
#include "quakebsp.vc"
|
#include "quakebsp.vc"
|
||||||
;
|
;
|
||||||
|
@ -112,6 +117,10 @@ static const char quakeskyid_frag[] =
|
||||||
#include "quakeski.fc"
|
#include "quakeski.fc"
|
||||||
;
|
;
|
||||||
|
|
||||||
|
static const char quakeskybox_frag[] =
|
||||||
|
#include "quakeskb.fc"
|
||||||
|
;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
int program;
|
int program;
|
||||||
shaderparam_t mvp_matrix;
|
shaderparam_t mvp_matrix;
|
||||||
|
@ -170,6 +179,20 @@ static struct {
|
||||||
{"realtime", 1},
|
{"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) \
|
#define CHAIN_SURF_F2B(surf,chain) \
|
||||||
do { \
|
do { \
|
||||||
instsurf_t *inst = (surf)->instsurf; \
|
instsurf_t *inst = (surf)->instsurf; \
|
||||||
|
@ -874,6 +897,35 @@ skyid_end (void)
|
||||||
qfglBindBuffer (GL_ARRAY_BUFFER, 0);
|
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
|
static inline void
|
||||||
add_surf_elements (texture_t *tex, instsurf_t *is,
|
add_surf_elements (texture_t *tex, instsurf_t *is,
|
||||||
elechain_t **ec, elements_t **el)
|
elechain_t **ec, elements_t **el)
|
||||||
|
@ -1020,22 +1072,33 @@ R_DrawSky (void)
|
||||||
texture_t *tex = 0;
|
texture_t *tex = 0;
|
||||||
elechain_t *ec = 0;
|
elechain_t *ec = 0;
|
||||||
elements_t *el = 0;
|
elements_t *el = 0;
|
||||||
|
shaderparam_t *matrix;
|
||||||
|
shaderparam_t *vertex;
|
||||||
|
|
||||||
if (!sky_chain)
|
if (!sky_chain)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (skybox_loaded) {
|
||||||
|
skybox_begin ();
|
||||||
|
matrix = &quake_skybox.mvp_matrix;
|
||||||
|
vertex = &quake_skybox.vertex;
|
||||||
|
} else {
|
||||||
skyid_begin ();
|
skyid_begin ();
|
||||||
|
matrix = &quake_skyid.mvp_matrix;
|
||||||
|
vertex = &quake_skyid.vertex;
|
||||||
|
}
|
||||||
for (is = sky_chain; is; is = is->tex_chain) {
|
for (is = sky_chain; is; is = is->tex_chain) {
|
||||||
surf = is->surface;
|
surf = is->surface;
|
||||||
if (tex != surf->texinfo->texture) {
|
if (tex != surf->texinfo->texture) {
|
||||||
if (tex) {
|
if (tex) {
|
||||||
|
if (!skybox_loaded) {
|
||||||
qfglActiveTexture (GL_TEXTURE0 + 0);
|
qfglActiveTexture (GL_TEXTURE0 + 0);
|
||||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[0]);
|
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[0]);
|
||||||
qfglActiveTexture (GL_TEXTURE0 + 1);
|
qfglActiveTexture (GL_TEXTURE0 + 1);
|
||||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[1]);
|
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[1]);
|
||||||
|
}
|
||||||
for (ec = tex->elechain; ec; ec = ec->next)
|
for (ec = tex->elechain; ec; ec = ec->next)
|
||||||
draw_elechain (ec, quake_skyid.mvp_matrix.location,
|
draw_elechain (ec, matrix->location, vertex->location, -1);
|
||||||
quake_skyid.vertex.location, -1);
|
|
||||||
tex->elechain = 0;
|
tex->elechain = 0;
|
||||||
tex->elechain_tail = &tex->elechain;
|
tex->elechain_tail = &tex->elechain;
|
||||||
}
|
}
|
||||||
|
@ -1044,16 +1107,20 @@ R_DrawSky (void)
|
||||||
add_surf_elements (tex, is, &ec, &el);
|
add_surf_elements (tex, is, &ec, &el);
|
||||||
}
|
}
|
||||||
if (tex) {
|
if (tex) {
|
||||||
|
if (!skybox_loaded) {
|
||||||
qfglActiveTexture (GL_TEXTURE0 + 0);
|
qfglActiveTexture (GL_TEXTURE0 + 0);
|
||||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[0]);
|
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[0]);
|
||||||
qfglActiveTexture (GL_TEXTURE0 + 1);
|
qfglActiveTexture (GL_TEXTURE0 + 1);
|
||||||
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[1]);
|
qfglBindTexture (GL_TEXTURE_2D, tex->sky_tex[1]);
|
||||||
|
}
|
||||||
for (ec = tex->elechain; ec; ec = ec->next)
|
for (ec = tex->elechain; ec; ec = ec->next)
|
||||||
draw_elechain (ec, quake_skyid.mvp_matrix.location,
|
draw_elechain (ec, matrix->location, vertex->location, -1);
|
||||||
quake_skyid.vertex.location, -1);
|
|
||||||
tex->elechain = 0;
|
tex->elechain = 0;
|
||||||
tex->elechain_tail = &tex->elechain;
|
tex->elechain_tail = &tex->elechain;
|
||||||
}
|
}
|
||||||
|
if (skybox_loaded)
|
||||||
|
skybox_end ();
|
||||||
|
else
|
||||||
skyid_end ();
|
skyid_end ();
|
||||||
|
|
||||||
sky_chain = 0;
|
sky_chain = 0;
|
||||||
|
@ -1099,4 +1166,70 @@ R_InitBsp (void)
|
||||||
GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.solid);
|
GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.solid);
|
||||||
GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.trans);
|
GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.trans);
|
||||||
GL_ResolveShaderParam (quake_skyid.program, &quake_skyid.realtime);
|
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);
|
R_BuildDisplayLists (models, num_models);
|
||||||
}
|
}
|
||||||
|
|
||||||
VISIBLE void
|
|
||||||
R_LoadSkys (const char *sky)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VISIBLE void
|
VISIBLE void
|
||||||
Fog_Update (float density, float red, float green, float blue, float time)
|
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