Added cubemap helpers and the 'buildcubemaps' command.

This commit is contained in:
Marco Cawthorne 2019-03-21 21:50:51 +01:00
parent 059cc72f3d
commit ebb2a7bad8
9 changed files with 289 additions and 88 deletions

View file

@ -35,6 +35,7 @@ void CSQC_Init(float apilevel, string enginename, float engineversion)
registercommand("invprev");
registercommand("+showscores");
registercommand("-showscores");
registercommand("buildcubemaps");
precache_model("sprites/640_pain.spr");
precache_model("sprites/crosshairs.spr");
@ -97,6 +98,18 @@ void CSQC_UpdateView(float w, float h, float focus)
video_res[0] = w;
video_res[1] = h;
if ( g_iCubeProcess == TRUE ) {
clearscene();
setproperty( VF_DRAWWORLD, TRUE );
setproperty( VF_DRAWENGINESBAR, FALSE );
setproperty( VF_DRAWCROSSHAIR, FALSE );
setproperty( VF_ENVMAP, "$whiteimage" );
setproperty( VF_ORIGIN, g_vecCubePos );
setproperty( VF_AFOV, 90 );
renderscene();
return;
}
clearscene();
setproperty(VF_DRAWENGINESBAR, 0);
@ -463,80 +476,83 @@ float CSQC_ConsoleCommand(string sCMD)
tokenize(sCMD);
switch (argv(0)) {
case "vox_test":
Sound_PlayVOX(sCMD);
break;
case "+attack2":
pSeat->iInputAttack2 = TRUE;
break;
case "-attack2":
pSeat->iInputAttack2 = FALSE;
break;
case "+reload":
pSeat->iInputReload = TRUE;
break;
case "-reload":
pSeat->iInputReload = FALSE;
break;
case "+use":
pSeat->iInputUse = TRUE;
break;
case "-use":
pSeat->iInputUse = FALSE;
break;
case "+duck":
pSeat->iInputDuck = TRUE;
break;
case "-duck":
pSeat->iInputDuck = FALSE;
break;
case "invnext":
HUD_DrawWeaponSelect_Back();
break;
case "invprev":
HUD_DrawWeaponSelect_Forward();
break;
case "lastinv":
HUD_DrawWeaponSelect_Last();
break;
case "+showscores":
pSeat->iShowScores = TRUE;
break;
case "-showscores":
pSeat->iShowScores = FALSE;
break;
case "slot1":
localcmd("impulse 1\n");
break;
case "slot2":
localcmd("impulse 2\n");
break;
case "slot3":
localcmd("impulse 3\n");
break;
case "slot4":
localcmd("impulse 4\n");
break;
case "slot5":
localcmd("impulse 5\n");
break;
case "slot6":
localcmd("impulse 6\n");
break;
case "slot7":
localcmd("impulse 7\n");
break;
case "slot8":
localcmd("impulse 8\n");
break;
case "slot9":
localcmd("impulse 9\n");
break;
case "slot10":
localcmd("impulse 10\n");
break;
default:
return Game_ConsoleCommand();
case "buildcubemaps":
CMap_Build();
break;
case "vox_test":
Sound_PlayVOX(sCMD);
break;
case "+attack2":
pSeat->iInputAttack2 = TRUE;
break;
case "-attack2":
pSeat->iInputAttack2 = FALSE;
break;
case "+reload":
pSeat->iInputReload = TRUE;
break;
case "-reload":
pSeat->iInputReload = FALSE;
break;
case "+use":
pSeat->iInputUse = TRUE;
break;
case "-use":
pSeat->iInputUse = FALSE;
break;
case "+duck":
pSeat->iInputDuck = TRUE;
break;
case "-duck":
pSeat->iInputDuck = FALSE;
break;
case "invnext":
HUD_DrawWeaponSelect_Back();
break;
case "invprev":
HUD_DrawWeaponSelect_Forward();
break;
case "lastinv":
HUD_DrawWeaponSelect_Last();
break;
case "+showscores":
pSeat->iShowScores = TRUE;
break;
case "-showscores":
pSeat->iShowScores = FALSE;
break;
case "slot1":
localcmd("impulse 1\n");
break;
case "slot2":
localcmd("impulse 2\n");
break;
case "slot3":
localcmd("impulse 3\n");
break;
case "slot4":
localcmd("impulse 4\n");
break;
case "slot5":
localcmd("impulse 5\n");
break;
case "slot6":
localcmd("impulse 6\n");
break;
case "slot7":
localcmd("impulse 7\n");
break;
case "slot8":
localcmd("impulse 8\n");
break;
case "slot9":
localcmd("impulse 9\n");
break;
case "slot10":
localcmd("impulse 10\n");
break;
default:
return Game_ConsoleCommand();
}
return TRUE;
}
@ -639,6 +655,10 @@ float CSQC_Ent_ParseMapEntity(void)
eEnt = spawn(env_sound);
iClass = TRUE;
break;
case "env_cubemap":
eEnt = spawn(env_cubemap);
iClass = TRUE;
break;
#ifdef REWOLF
case "decore_asteroid":
eEnt = spawn(decore_asteroid);

View file

@ -4,6 +4,7 @@
../gs-entbase/client/fade.cpp
../gs-entbase/client/sprite.cpp
../gs-entbase/client/text.cpp
../gs-entbase/client/env_cubemap.cpp
../gs-entbase/client/env_sound.cpp
../gs-entbase/client/worldspawn.cpp
#endlist

View file

@ -0,0 +1,136 @@
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
/*
===============================================================================
Cubemap Entity Development Functions
===============================================================================
*/
int g_iCubeProcess;
entity g_eCubeCycle;
vector g_vecCubePos;
void CMap_Check(void);
void CMap_Shoot(void);
class env_cubemap:CBaseEntity {
int m_iSize;
void() env_cubemap;
virtual void(string, string) SpawnKey;
};
void env_cubemap::SpawnKey(string strField, string strKey)
{
switch (strField) {
case "scale":
m_iSize = stoi(strKey);
if (m_iSize <= 16) {
m_iSize = 16;
} else if (m_iSize <= 32) {
m_iSize = 32;
} else if (m_iSize <= 64) {
m_iSize = 64;
} else if (m_iSize <= 128) {
m_iSize = 128;
} else {
m_iSize = 256;
}
break;
default:
CBaseEntity::SpawnKey(strField, strKey);
}
}
void env_cubemap::env_cubemap(void)
{
m_iSize = 32;
Init();
}
/*
=================
CMap_Check
Checks whether or not a specific cubemap file was dumped, goes to the next
=================
*/
void CMap_Shoot(void)
{
string strReflectcube;
if ( self.owner ) {
env_cubemap tmp = (env_cubemap) self.owner;
print( "^3Cubemap processing...\n" );
g_vecCubePos = tmp.origin;
strReflectcube = sprintf(
"env/%s_%d_%d_%d.dds",
mapname,
g_vecCubePos[0],
g_vecCubePos[1],
g_vecCubePos[2]);
localcmd(sprintf(
"screenshot_cubemap %s %i\n",
strReflectcube,
tmp.m_iSize));
self.think = CMap_Check;
self.nextthink = time;
} else {
print( "^2Cubemaps done...\n" );
localcmd( "mod_findcubemaps\nvid_reload\n" );
g_iCubeProcess = FALSE;
remove( self );
}
}
/*
=================
CMap_Check
Checks whether or not a specific cubemap file was dumped, goes to the next
=================
*/
void CMap_Check(void)
{
if (whichpack(sprintf(
"textures/env/%s_%d_%d_%d.dds",
mapname,
g_vecCubePos[0],
g_vecCubePos[1],
g_vecCubePos[2]))) {
self.owner = find( self.owner, classname, "env_cubemap" );
self.think = CMap_Shoot;
}
self.nextthink = time;
}
/*
=================
CMap_Build
Called upon 'dev_buildcubemaps'
=================
*/
void CMap_Build(void)
{
if (g_iCubeProcess == TRUE) {
return;
}
print("^4Building cubemaps...\n");
g_eCubeCycle = spawn();
g_eCubeCycle.owner = find(world, classname, "env_cubemap");
if (g_eCubeCycle.owner) {
g_eCubeCycle.think = CMap_Shoot;
g_eCubeCycle.nextthink = time;
g_iCubeProcess = TRUE;
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -2,7 +2,7 @@
!!permu FRAMEBLEND
!!permu SKELETAL
!!permu FOG
!!samps diffuse
!!samps diffuse reflectcube
!!cvardf gl_affinemodels=0
!!cvardf gl_fake16bit=0
!!cvardf gl_monochrome=0
@ -16,6 +16,11 @@
#define affine
#endif
#ifdef REFLECTCUBE
varying vec3 eyevector;
varying mat3 invsurface;
#endif
affine varying vec2 tex_c;
varying vec3 light;
@ -60,16 +65,16 @@ varying vec3 light;
tex_c.x = 0.5 + reflected.y * 0.5;
tex_c.y = 0.5 - reflected.z * 0.5;
#endif
if (light.r > 1.0f) {
light.r = 1.0f;
}
if (light.g > 1.0f) {
light.g = 1.0f;
}
if (light.b > 1.0f) {
light.b = 1.0f;
}
#ifdef REFLECTCUBE
invsurface[0] = v_svector;
invsurface[1] = v_tvector;
invsurface[2] = v_normal;
vec3 eyeminusvertex = e_eyepos - v_position.xyz;
eyevector.x = dot( eyeminusvertex, v_svector.xyz );
eyevector.y = dot( eyeminusvertex, v_tvector.xyz );
eyevector.z = dot( eyeminusvertex, v_normal.xyz );
#endif
}
#endif
@ -79,6 +84,17 @@ varying vec3 light;
{
vec4 diffuse_f = texture2D(s_diffuse, tex_c);
diffuse_f.rgb *= light;
#ifdef REFLECTCUBE
vec3 cube_c;
vec4 out_f = vec4( 1.0, 1.0, 1.0, 1.0 );
cube_c = reflect( normalize( -eyevector ), vec3( 0, 0, 1 ) );
cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2];
cube_c = ( m_model * vec4( cube_c.xyz, 0.0 ) ).xyz;
out_f.rgb = mix( textureCube( s_reflectcube, cube_c ).rgb, diffuse_f.rgb, diffuse_f.a );
diffuse_f = out_f;
#endif
diffuse_f *= e_colourident;
#if gl_brighten == 1

View file

@ -1,5 +1,5 @@
!!ver 110
!!samps diffuse lightmap
!!samps diffuse lightmap reflectcube
!!cvardf gl_fake16bit=0
!!cvardf gl_monochrome=0
!!cvardf gl_brighten=0
@ -9,12 +9,27 @@
varying vec2 tex_c;
varying vec2 lm_c;
#ifdef REFLECTCUBE
varying vec3 eyevector;
varying mat3 invsurface;
#endif
#ifdef VERTEX_SHADER
void main ()
{
tex_c = v_texcoord;
lm_c = v_lmcoord;
gl_Position = ftetransform();
#ifdef REFLECTCUBE
invsurface[0] = v_svector;
invsurface[1] = v_tvector;
invsurface[2] = v_normal;
vec3 eyeminusvertex = e_eyepos - v_position.xyz;
eyevector.x = dot( eyeminusvertex, v_svector.xyz );
eyevector.y = dot( eyeminusvertex, v_tvector.xyz );
eyevector.z = dot( eyeminusvertex, v_normal.xyz );
#endif
}
#endif
@ -29,11 +44,24 @@ varying vec2 lm_c;
discard;
}
#ifdef REFLECTCUBE
vec3 cube_c;
vec4 out_f = vec4( 1.0, 1.0, 1.0, 1.0 );
// Modulate the final pixel with the lightmap value
diffuse_f.rgb *= light.rgb * e_lmscale.rgb;
cube_c = reflect( normalize(-eyevector), vec3(0, 0, 1));
cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2];
cube_c = ( m_model * vec4(cube_c.xyz, 0.0)).xyz;
out_f.rgb = mix( textureCube(s_reflectcube, cube_c ).rgb, diffuse_f.rgb, diffuse_f.a);
diffuse_f = out_f;
#else
diffuse_f.rgb *= light.rgb;
if (diffuse_f.a < 0.5) {
discard;
}
diffuse_f.rgb *= light.rgb;
#endif
diffuse_f *= e_colourident;
#if gl_brighten == 1