mirror of
https://github.com/w23/xash3d-fwgs
synced 2024-11-05 01:51:55 +01:00
commit
2ebae2f4e1
@ -193,7 +193,7 @@ void XVK_CameraDebugPrintCenterEntity( void ) {
|
|||||||
ent = gEngine.GetEntityByIndex( (physent && physent->info > 0) ? physent->info : 0 );
|
ent = gEngine.GetEntityByIndex( (physent && physent->info > 0) ? physent->info : 0 );
|
||||||
|
|
||||||
p += Q_snprintf(p, end - p,
|
p += Q_snprintf(p, end - p,
|
||||||
"o\n"
|
"^\n"
|
||||||
"cam.origin: %.03f %.03f %.03f\n",
|
"cam.origin: %.03f %.03f %.03f\n",
|
||||||
// TODO cam dir
|
// TODO cam dir
|
||||||
// TODO hit pos
|
// TODO hit pos
|
||||||
|
@ -222,7 +222,8 @@ void computePointLights(uint cluster_index, vec3 throughput, vec3 view_dir, Mate
|
|||||||
#if 1
|
#if 1
|
||||||
const float d2 = dot(light_dir, light_dir);
|
const float d2 = dot(light_dir, light_dir);
|
||||||
const float r2 = origin_r.w * origin_r.w;
|
const float r2 = origin_r.w * origin_r.w;
|
||||||
light_dist = sqrt(d2);
|
//light_dist = sqrt(d2);
|
||||||
|
light_dist = sqrt(d2) - origin_r.w;
|
||||||
fdist = 2.f / (r2 + d2 + light_dist * sqrt(d2 + r2));
|
fdist = 2.f / (r2 + d2 + light_dist * sqrt(d2 + r2));
|
||||||
#else
|
#else
|
||||||
const float d2 = dot(light_dir, light_dir);
|
const float d2 = dot(light_dir, light_dir);
|
||||||
|
@ -390,9 +390,10 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f
|
|||||||
|
|
||||||
.element_count = total_indices,
|
.element_count = total_indices,
|
||||||
.index_offset = index_buffer.buffer.unit.offset,
|
.index_offset = index_buffer.buffer.unit.offset,
|
||||||
|
|
||||||
|
.emissive = { color[0], color[1], color[2] },
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME .emissive = { color[0], color[1], color[2] },
|
|
||||||
|
|
||||||
VK_RenderModelDynamicBegin( render_mode, "beam" /* TODO its name */ );
|
VK_RenderModelDynamicBegin( render_mode, "beam" /* TODO its name */ );
|
||||||
VK_RenderModelDynamicAddGeometry( &geometry );
|
VK_RenderModelDynamicAddGeometry( &geometry );
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "vk_scene.h"
|
#include "vk_scene.h"
|
||||||
#include "vk_render.h"
|
#include "vk_render.h"
|
||||||
#include "vk_light.h"
|
#include "vk_light.h"
|
||||||
|
#include "vk_mapents.h"
|
||||||
|
|
||||||
#include "ref_params.h"
|
#include "ref_params.h"
|
||||||
#include "eiface.h"
|
#include "eiface.h"
|
||||||
@ -279,9 +280,9 @@ R_TextureAnimation
|
|||||||
Returns the proper texture for a given time and surface
|
Returns the proper texture for a given time and surface
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
texture_t *R_TextureAnimation( const cl_entity_t *ent, const msurface_t *s )
|
static const texture_t *R_TextureAnimation( const cl_entity_t *ent, const msurface_t *s, const struct texture_s *base_override )
|
||||||
{
|
{
|
||||||
texture_t *base = s->texinfo->texture;
|
const texture_t *base = base_override ? base_override : s->texinfo->texture;
|
||||||
int count, reletive;
|
int count, reletive;
|
||||||
|
|
||||||
if( ent && ent->curstate.frame )
|
if( ent && ent->curstate.frame )
|
||||||
@ -344,11 +345,14 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode )
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < bmodel->render_model.num_geometries; ++i) {
|
for (int i = 0; i < bmodel->render_model.num_geometries; ++i) {
|
||||||
texture_t *t = R_TextureAnimation(ent, bmodel->render_model.geometries[i].surf);
|
vk_render_geometry_t *geom = bmodel->render_model.geometries + i;
|
||||||
|
const int surface_index = geom->surf - mod->surfaces;
|
||||||
|
const struct texture_s *override = g_map_entities.patch.surfaces ? g_map_entities.patch.surfaces[surface_index].tex : NULL;
|
||||||
|
const texture_t *t = R_TextureAnimation(ent, geom->surf, override);
|
||||||
if (t->gl_texturenum < 0)
|
if (t->gl_texturenum < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bmodel->render_model.geometries[i].texture = t->gl_texturenum;
|
geom->texture = t->gl_texturenum;
|
||||||
}
|
}
|
||||||
|
|
||||||
bmodel->render_model.render_mode = render_mode;
|
bmodel->render_model.render_mode = render_mode;
|
||||||
@ -373,6 +377,9 @@ static qboolean renderableSurface( const msurface_t *surf, int i ) {
|
|||||||
// PRINTFLAGS(PRINTFLAG)
|
// PRINTFLAGS(PRINTFLAG)
|
||||||
// gEngine.Con_Reportf("\n");
|
// gEngine.Con_Reportf("\n");
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
|
if (g_map_entities.patch.surfaces && g_map_entities.patch.surfaces[i].flags & Patch_Surface_Delete)
|
||||||
|
return false;
|
||||||
|
|
||||||
//if( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB | SURF_CONVEYOR | SURF_DRAWTURB_QUADS ) ) {
|
//if( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB | SURF_CONVEYOR | SURF_DRAWTURB_QUADS ) ) {
|
||||||
if( surf->flags & ( SURF_DRAWTURB | SURF_DRAWTURB_QUADS ) ) {
|
if( surf->flags & ( SURF_DRAWTURB | SURF_DRAWTURB_QUADS ) ) {
|
||||||
@ -457,11 +464,16 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
|||||||
const float sample_size = gEngine.Mod_SampleSizeForFace( surf );
|
const float sample_size = gEngine.Mod_SampleSizeForFace( surf );
|
||||||
int index_count = 0;
|
int index_count = 0;
|
||||||
vec3_t tangent;
|
vec3_t tangent;
|
||||||
|
int tex_id = surf->texinfo->texture->gl_texturenum;
|
||||||
|
const xvk_patch_surface_t *const psurf = g_map_entities.patch.surfaces ? g_map_entities.patch.surfaces + surface_index : NULL;
|
||||||
|
|
||||||
if (!renderableSurface(surf, -1))
|
if (!renderableSurface(surf, -1))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (t != surf->texinfo->texture->gl_texturenum)
|
if (psurf && psurf->flags & Patch_Surface_Texture)
|
||||||
|
tex_id = psurf->tex_id;
|
||||||
|
|
||||||
|
if (t != tex_id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
++num_geometries;
|
++num_geometries;
|
||||||
@ -476,7 +488,7 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model_geometry->surf = surf;
|
model_geometry->surf = surf;
|
||||||
model_geometry->texture = surf->texinfo->texture->gl_texturenum;
|
model_geometry->texture = tex_id;
|
||||||
|
|
||||||
model_geometry->vertex_offset = vertex_buffer.buffer.unit.offset;
|
model_geometry->vertex_offset = vertex_buffer.buffer.unit.offset;
|
||||||
model_geometry->max_vertex = vertex_offset + surf->numedges;
|
model_geometry->max_vertex = vertex_offset + surf->numedges;
|
||||||
@ -496,6 +508,12 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
|||||||
model_geometry->material = kXVkMaterialConveyor;
|
model_geometry->material = kXVkMaterialConveyor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME material should be flags
|
||||||
|
if (psurf && psurf->flags & Patch_Surface_Emissive) {
|
||||||
|
model_geometry->material = kXVkMaterialEmissive;
|
||||||
|
VectorCopy(psurf->emissive, model_geometry->emissive);
|
||||||
|
}
|
||||||
|
|
||||||
VectorCopy(surf->texinfo->vecs[0], tangent);
|
VectorCopy(surf->texinfo->vecs[0], tangent);
|
||||||
VectorNormalize(tangent);
|
VectorNormalize(tangent);
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ static void clusterBitMapClear( void ) {
|
|||||||
// Returns true if wasn't set
|
// Returns true if wasn't set
|
||||||
static qboolean clusterBitMapCheckOrSet( int cell_index ) {
|
static qboolean clusterBitMapCheckOrSet( int cell_index ) {
|
||||||
uint32_t *const bits = g_lights_tmp.clusters_bit_map + (cell_index / 32);
|
uint32_t *const bits = g_lights_tmp.clusters_bit_map + (cell_index / 32);
|
||||||
const uint32_t bit = 1 << (cell_index % 32);
|
const uint32_t bit = 1u << (cell_index % 32);
|
||||||
|
|
||||||
if ((*bits) & bit)
|
if ((*bits) & bit)
|
||||||
return false;
|
return false;
|
||||||
@ -604,7 +604,7 @@ void VK_LightsAddEmissiveSurface( const struct vk_render_geometry_s *geom, const
|
|||||||
if (!geom->surf)
|
if (!geom->surf)
|
||||||
goto fin; // TODO break? no surface means that model is not brush
|
goto fin; // TODO break? no surface means that model is not brush
|
||||||
|
|
||||||
if (/* geom->material != kXVkMaterialSky && */geom->material != kXVkMaterialEmissive && !g_lights.map.emissive_textures[texture_num].set)
|
if (geom->material != kXVkMaterialEmissive && !g_lights.map.emissive_textures[texture_num].set)
|
||||||
goto fin;
|
goto fin;
|
||||||
|
|
||||||
if (g_lights.num_emissive_surfaces >= 256)
|
if (g_lights.num_emissive_surfaces >= 256)
|
||||||
@ -634,11 +634,10 @@ void VK_LightsAddEmissiveSurface( const struct vk_render_geometry_s *geom, const
|
|||||||
|
|
||||||
// Insert into emissive surfaces
|
// Insert into emissive surfaces
|
||||||
esurf->kusok_index = geom->kusok_index;
|
esurf->kusok_index = geom->kusok_index;
|
||||||
if (/* geom->material != kXVkMaterialSky && */geom->material != kXVkMaterialEmissive) {
|
if (geom->material != kXVkMaterialEmissive) {
|
||||||
VectorCopy(g_lights.map.emissive_textures[texture_num].emissive, esurf->emissive);
|
VectorCopy(g_lights.map.emissive_textures[texture_num].emissive, esurf->emissive);
|
||||||
} else {
|
} else {
|
||||||
// TODO see #227
|
VectorCopy(geom->emissive, esurf->emissive);
|
||||||
VectorSet(esurf->emissive, 0.f, 0.f, 0.f);
|
|
||||||
}
|
}
|
||||||
Matrix3x4_Copy(esurf->transform, *transform_row);
|
Matrix3x4_Copy(esurf->transform, *transform_row);
|
||||||
|
|
||||||
@ -864,17 +863,22 @@ static void processStaticPointLights( void ) {
|
|||||||
const float default_radius = 50.f; // FIXME tune
|
const float default_radius = 50.f; // FIXME tune
|
||||||
const float hack_attenuation = 100.f; // FIXME tune
|
const float hack_attenuation = 100.f; // FIXME tune
|
||||||
const float hack_attenuation_spot = 100.f; // FIXME tune
|
const float hack_attenuation_spot = 100.f; // FIXME tune
|
||||||
|
float radius = le->radius > 0.f ? le->radius : default_radius;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
switch (le->type) {
|
switch (le->type) {
|
||||||
case LightTypePoint:
|
case LightTypePoint:
|
||||||
index = addPointLight(le->origin, le->color, default_radius, le->style, hack_attenuation);
|
index = addPointLight(le->origin, le->color, radius, le->style, hack_attenuation);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LightTypeSpot:
|
case LightTypeSpot:
|
||||||
case LightTypeEnvironment:
|
case LightTypeEnvironment:
|
||||||
index = addSpotLight(le, default_radius, le->style, hack_attenuation_spot, i == g_map_entities.single_environment_index);
|
index = addSpotLight(le, radius, le->style, hack_attenuation_spot, i == g_map_entities.single_environment_index);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ASSERT(!"Unexpected light type");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
@ -902,7 +906,6 @@ void VK_LightsLoadMapStaticLights( void ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XVK_ParseMapEntities();
|
|
||||||
processStaticPointLights();
|
processStaticPointLights();
|
||||||
|
|
||||||
// Load RAD data based on map name
|
// Load RAD data based on map name
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
#include "vk_common.h"
|
#include "vk_common.h"
|
||||||
#include "vk_mapents.h"
|
#include "vk_mapents.h"
|
||||||
|
#include "vk_core.h" // TODO we need only pool from there, not the entire vulkan garbage
|
||||||
|
#include "vk_textures.h"
|
||||||
|
|
||||||
#include "eiface.h" // ARRAYSIZE
|
#include "eiface.h" // ARRAYSIZE
|
||||||
#include "xash3d_mathlib.h"
|
#include "xash3d_mathlib.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
xvk_map_entities_t g_map_entities;
|
xvk_map_entities_t g_map_entities;
|
||||||
|
|
||||||
@ -144,7 +147,65 @@ static void parseStopDot( const entity_props_t *props, vk_light_entity_t *le) {
|
|||||||
le->stopdot2 = cosf(le->stopdot2 * M_PI / 180.f);
|
le->stopdot2 = cosf(le->stopdot2 * M_PI / 180.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addLightEntity( const entity_props_t *props, unsigned have_fields ) {
|
static void fillLightFromProps( vk_light_entity_t *le, const entity_props_t *props, unsigned have_fields, qboolean patch, int entity_index ) {
|
||||||
|
switch (le->type) {
|
||||||
|
case LightTypePoint:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LightTypeSpot:
|
||||||
|
case LightTypeEnvironment:
|
||||||
|
if (!patch || (have_fields & Field_pitch) || (have_fields & Field_angles) || (have_fields & Field_angle)) {
|
||||||
|
parseAngles(props, le);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!patch || (have_fields & Field__cone) || (have_fields & Field__cone2)) {
|
||||||
|
parseStopDot(props, le);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_fields & Field_target)
|
||||||
|
Q_strcpy(le->target_entity, props->target);
|
||||||
|
|
||||||
|
if (have_fields & Field_origin)
|
||||||
|
VectorCopy(props->origin, le->origin);
|
||||||
|
|
||||||
|
if (have_fields & Field__light)
|
||||||
|
{
|
||||||
|
VectorCopy(props->_light, le->color);
|
||||||
|
} else if (!patch) {
|
||||||
|
// same as qrad
|
||||||
|
VectorSet(le->color, 300, 300, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_fields & Field_radius) {
|
||||||
|
le->radius = props->radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_fields & Field_style) {
|
||||||
|
le->style = props->style;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (le->type != LightEnvironment && (!patch || (have_fields & Field__light))) {
|
||||||
|
weirdGoldsrcLightScaling(le->color);
|
||||||
|
}
|
||||||
|
|
||||||
|
gEngine.Con_Reportf("%s light %d (ent=%d): %s targetname=%s color=(%f %f %f) origin=(%f %f %f) style=%d dir=(%f %f %f) stopdot=(%f %f)\n",
|
||||||
|
patch ? "Patch" : "Added",
|
||||||
|
g_map_entities.num_lights, entity_index,
|
||||||
|
le->type == LightTypeEnvironment ? "environment" : le->type == LightTypeSpot ? "spot" : "point",
|
||||||
|
props->targetname,
|
||||||
|
le->color[0], le->color[1], le->color[2],
|
||||||
|
le->origin[0], le->origin[1], le->origin[2],
|
||||||
|
le->style,
|
||||||
|
le->dir[0], le->dir[1], le->dir[2],
|
||||||
|
le->stopdot, le->stopdot2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addLightEntity( const entity_props_t *props, unsigned have_fields, int entity_index ) {
|
||||||
const int index = g_map_entities.num_lights;
|
const int index = g_map_entities.num_lights;
|
||||||
vk_light_entity_t *le = g_map_entities.lights + index;
|
vk_light_entity_t *le = g_map_entities.lights + index;
|
||||||
unsigned expected_fields = 0;
|
unsigned expected_fields = 0;
|
||||||
@ -170,61 +231,32 @@ static void addLightEntity( const entity_props_t *props, unsigned have_fields )
|
|||||||
le->type = LightTypeSpot;
|
le->type = LightTypeSpot;
|
||||||
expected_fields = Field_origin | Field__cone | Field__cone2;
|
expected_fields = Field_origin | Field__cone | Field__cone2;
|
||||||
}
|
}
|
||||||
parseAngles(props, le);
|
|
||||||
parseStopDot(props, le);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LightEnvironment:
|
case LightEnvironment:
|
||||||
le->type = LightTypeEnvironment;
|
le->type = LightTypeEnvironment;
|
||||||
parseAngles(props, le);
|
|
||||||
parseStopDot(props, le);
|
|
||||||
|
|
||||||
if (g_map_entities.single_environment_index == NoEnvironmentLights) {
|
|
||||||
g_map_entities.single_environment_index = index;
|
|
||||||
} else {
|
|
||||||
g_map_entities.single_environment_index = MoreThanOneEnvironmentLight;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (have_fields & Field_target)
|
default:
|
||||||
Q_strcpy(le->target_entity, props->target);
|
ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
if ((have_fields & expected_fields) != expected_fields) {
|
if ((have_fields & expected_fields) != expected_fields) {
|
||||||
gEngine.Con_Printf(S_ERROR "Missing some fields for light entity\n");
|
gEngine.Con_Printf(S_ERROR "Missing some fields for light entity\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorCopy(props->origin, le->origin);
|
if (le->type == LightTypeEnvironment) {
|
||||||
|
if (g_map_entities.single_environment_index == NoEnvironmentLights) {
|
||||||
if ( (have_fields & Field__light) == 0 )
|
g_map_entities.single_environment_index = index;
|
||||||
{
|
|
||||||
// same as qrad
|
|
||||||
VectorSet(le->color, 300, 300, 300);
|
|
||||||
} else {
|
} else {
|
||||||
VectorCopy(props->_light, le->color);
|
g_map_entities.single_environment_index = MoreThanOneEnvironmentLight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (have_fields & Field_style) != 0) {
|
fillLightFromProps(le, props, have_fields, false, entity_index);
|
||||||
le->style = props->style;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (le->type != LightEnvironment) {
|
|
||||||
//gEngine.Con_Reportf("Pre scaling: %f %f %f ", values._light[0], values._light[1], values._light[2]);
|
|
||||||
weirdGoldsrcLightScaling(le->color);
|
|
||||||
//gEngine.Con_Reportf("post scaling: %f %f %f\n", values._light[0], values._light[1], values._light[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
gEngine.Con_Reportf("Added light %d: %s targetname=%s color=(%f %f %f) origin=(%f %f %f) style=%d dir=(%f %f %f) stopdot=(%f %f)\n",
|
|
||||||
g_map_entities.num_lights,
|
|
||||||
le->type == LightTypeEnvironment ? "environment" : le->type == LightTypeSpot ? "spot" : "point",
|
|
||||||
props->targetname,
|
|
||||||
le->color[0], le->color[1], le->color[2],
|
|
||||||
le->origin[0], le->origin[1], le->origin[2],
|
|
||||||
le->style,
|
|
||||||
le->dir[0], le->dir[1], le->dir[2],
|
|
||||||
le->stopdot, le->stopdot2);
|
|
||||||
|
|
||||||
|
le->entity_index = entity_index;
|
||||||
g_map_entities.num_lights++;
|
g_map_entities.num_lights++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,33 +277,95 @@ static void addTargetEntity( const entity_props_t *props ) {
|
|||||||
++g_map_entities.num_targets;
|
++g_map_entities.num_targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
const xvk_mapent_target_t *findTargetByName(const char *name) {
|
|
||||||
for (int i = 0; i < g_map_entities.num_targets; ++i) {
|
|
||||||
const xvk_mapent_target_t *target = g_map_entities.targets + i;
|
|
||||||
if (Q_strcmp(name, target->targetname) == 0)
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void readWorldspawn( const entity_props_t *props ) {
|
static void readWorldspawn( const entity_props_t *props ) {
|
||||||
Q_strcpy(g_map_entities.wadlist, props->wad);
|
Q_strcpy(g_map_entities.wadlist, props->wad);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XVK_ParseMapEntities( void ) {
|
static void addPatchSurface( const entity_props_t *props, uint32_t have_fields ) {
|
||||||
const model_t* const map = gEngine.pfnGetModelByIndex( 1 );
|
const model_t* const map = gEngine.pfnGetModelByIndex( 1 );
|
||||||
char *pos;
|
const int num_surfaces = map->numsurfaces;
|
||||||
|
xvk_patch_surface_t *psurf = NULL;
|
||||||
|
if (props->_xvk_surface_id < 0 || props->_xvk_surface_id >= num_surfaces) {
|
||||||
|
gEngine.Con_Printf(S_ERROR "Incorrect patch for surface_index %d where numsurfaces=%d\n", props->_xvk_surface_id, num_surfaces);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_map_entities.patch.surfaces) {
|
||||||
|
g_map_entities.patch.surfaces = Mem_Malloc(vk_core.pool, num_surfaces * sizeof(xvk_patch_surface_t));
|
||||||
|
for (int i = 0; i < num_surfaces; ++i) {
|
||||||
|
g_map_entities.patch.surfaces[i].flags = Patch_Surface_NoPatch;
|
||||||
|
g_map_entities.patch.surfaces[i].tex_id = -1;
|
||||||
|
g_map_entities.patch.surfaces[i].tex = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
psurf = g_map_entities.patch.surfaces + props->_xvk_surface_id;
|
||||||
|
|
||||||
|
if (have_fields & Field__xvk_texture) {
|
||||||
|
if (props->_xvk_texture[0] == '\0') {
|
||||||
|
gEngine.Con_Reportf("Patch: surface %d removed\n", props->_xvk_surface_id);
|
||||||
|
psurf->flags = Patch_Surface_Delete;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
const int tex_id = VK_FindTexture( props->_xvk_texture );
|
||||||
|
gEngine.Con_Reportf("Patch for surface %d with texture \"%s\" -> %d\n", props->_xvk_surface_id, props->_xvk_texture, tex_id);
|
||||||
|
psurf->tex_id = tex_id;
|
||||||
|
|
||||||
|
// Find texture_t for this index
|
||||||
|
for (int i = 0; i < map->numtextures; ++i) {
|
||||||
|
const texture_t* const tex = map->textures[i];
|
||||||
|
if (tex->gl_texturenum == tex_id) {
|
||||||
|
psurf->tex = tex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
psurf->flags |= Patch_Surface_Texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_fields & Field__light) {
|
||||||
|
VectorCopy(props->_light, psurf->emissive);
|
||||||
|
psurf->flags |= Patch_Surface_Emissive;
|
||||||
|
gEngine.Con_Reportf("Patch for surface %d: assign emissive %f %f %f\n", props->_xvk_surface_id,
|
||||||
|
psurf->emissive[0],
|
||||||
|
psurf->emissive[1],
|
||||||
|
psurf->emissive[2]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int findLightEntityWithIndex( int index ) {
|
||||||
|
// TODO could do binary search (entities are sorted by index) but why
|
||||||
|
for (int i = 0; i < g_map_entities.num_lights; ++i) {
|
||||||
|
if (g_map_entities.lights[i].entity_index == index)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addPatchEntity( const entity_props_t *props, uint32_t have_fields ) {
|
||||||
|
const int light_index = findLightEntityWithIndex( props->_xvk_ent_id );
|
||||||
|
if (light_index < 0) {
|
||||||
|
gEngine.Con_Printf(S_ERROR "Patch light entity with index=%d not found\n", props->_xvk_ent_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_fields == Field__xvk_ent_id) {
|
||||||
|
gEngine.Con_Reportf("Deleting light entity (%d of %d) with index=%d\n", light_index, g_map_entities.num_lights, props->_xvk_ent_id);
|
||||||
|
g_map_entities.num_lights--;
|
||||||
|
memmove(g_map_entities.lights + light_index, g_map_entities.lights + light_index + 1, sizeof(*g_map_entities.lights) * g_map_entities.num_lights - light_index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fillLightFromProps(g_map_entities.lights + light_index, props, have_fields, true, props->_xvk_ent_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parseEntities( char *string, int *count ) {
|
||||||
unsigned have_fields = 0;
|
unsigned have_fields = 0;
|
||||||
entity_props_t values;
|
entity_props_t values;
|
||||||
|
char *pos = string;
|
||||||
ASSERT(map);
|
|
||||||
|
|
||||||
g_map_entities.num_targets = 0;
|
|
||||||
g_map_entities.num_lights = 0;
|
|
||||||
g_map_entities.single_environment_index = NoEnvironmentLights;
|
|
||||||
|
|
||||||
pos = map->entities;
|
|
||||||
//gEngine.Con_Reportf("ENTITIES: %s\n", pos);
|
//gEngine.Con_Reportf("ENTITIES: %s\n", pos);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char key[1024];
|
char key[1024];
|
||||||
@ -294,7 +388,7 @@ void XVK_ParseMapEntities( void ) {
|
|||||||
case Light:
|
case Light:
|
||||||
case LightSpot:
|
case LightSpot:
|
||||||
case LightEnvironment:
|
case LightEnvironment:
|
||||||
addLightEntity( &values, have_fields );
|
addLightEntity( &values, have_fields, *count );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Worldspawn:
|
case Worldspawn:
|
||||||
@ -302,10 +396,18 @@ void XVK_ParseMapEntities( void ) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Unknown:
|
case Unknown:
|
||||||
|
if (have_fields & Field__xvk_surface_id) {
|
||||||
|
addPatchSurface( &values, have_fields );
|
||||||
|
} else if (have_fields & Field__xvk_ent_id) {
|
||||||
|
addPatchEntity( &values, have_fields );
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Ignored:
|
case Ignored:
|
||||||
// Skip
|
// Skip
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++(*count);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +429,19 @@ void XVK_ParseMapEntities( void ) {
|
|||||||
}
|
}
|
||||||
#undef CHECK_FIELD
|
#undef CHECK_FIELD
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const xvk_mapent_target_t *findTargetByName(const char *name) {
|
||||||
|
for (int i = 0; i < g_map_entities.num_targets; ++i) {
|
||||||
|
const xvk_mapent_target_t *target = g_map_entities.targets + i;
|
||||||
|
if (Q_strcmp(name, target->targetname) == 0)
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void orientSpotlights( void ) {
|
||||||
// Patch spotlight directions based on target entities
|
// Patch spotlight directions based on target entities
|
||||||
for (int i = 0; i < g_map_entities.num_lights; ++i) {
|
for (int i = 0; i < g_map_entities.num_lights; ++i) {
|
||||||
vk_light_entity_t *const light = g_map_entities.lights + i;
|
vk_light_entity_t *const light = g_map_entities.lights + i;
|
||||||
@ -352,3 +466,40 @@ void XVK_ParseMapEntities( void ) {
|
|||||||
light->dir[0], light->dir[1], light->dir[2]);
|
light->dir[0], light->dir[1], light->dir[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parsePatches( const model_t *const map, int *count) {
|
||||||
|
char filename[256];
|
||||||
|
byte *data;
|
||||||
|
|
||||||
|
if (g_map_entities.patch.surfaces) {
|
||||||
|
Mem_Free(g_map_entities.patch.surfaces);
|
||||||
|
g_map_entities.patch.surfaces = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_snprintf(filename, sizeof(filename), "luchiki/%s.patch", map->name);
|
||||||
|
gEngine.Con_Reportf("Loading patches from file \"%s\"\n", filename);
|
||||||
|
data = gEngine.COM_LoadFile( filename, 0, false );
|
||||||
|
if (!data) {
|
||||||
|
gEngine.Con_Reportf("No patch file \"%s\"\n", filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseEntities( (char*)data, count );
|
||||||
|
Mem_Free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XVK_ParseMapEntities( void ) {
|
||||||
|
const model_t* const map = gEngine.pfnGetModelByIndex( 1 );
|
||||||
|
int entities_count = 0;
|
||||||
|
|
||||||
|
ASSERT(map);
|
||||||
|
|
||||||
|
g_map_entities.num_targets = 0;
|
||||||
|
g_map_entities.num_lights = 0;
|
||||||
|
g_map_entities.single_environment_index = NoEnvironmentLights;
|
||||||
|
|
||||||
|
parseEntities( map->entities, &entities_count );
|
||||||
|
parsePatches( map, &entities_count );
|
||||||
|
|
||||||
|
orientSpotlights();
|
||||||
|
}
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
X(10, string, targetname, String) \
|
X(10, string, targetname, String) \
|
||||||
X(11, string, target, String) \
|
X(11, string, target, String) \
|
||||||
X(12, int, style, Int) \
|
X(12, int, style, Int) \
|
||||||
|
X(13, int, _xvk_surface_id, Int) \
|
||||||
|
X(14, string, _xvk_texture, String) \
|
||||||
|
X(15, int, _xvk_ent_id, Int) \
|
||||||
|
X(16, float, radius, Float) \
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
@ -41,12 +45,15 @@ typedef enum {
|
|||||||
typedef enum { LightTypePoint, LightTypeSurface, LightTypeSpot, LightTypeEnvironment} LightType;
|
typedef enum { LightTypePoint, LightTypeSurface, LightTypeSpot, LightTypeEnvironment} LightType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
int entity_index;
|
||||||
LightType type;
|
LightType type;
|
||||||
|
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
vec3_t color;
|
vec3_t color;
|
||||||
vec3_t dir;
|
vec3_t dir;
|
||||||
|
|
||||||
|
float radius;
|
||||||
|
|
||||||
int style;
|
int style;
|
||||||
float stopdot, stopdot2;
|
float stopdot, stopdot2;
|
||||||
|
|
||||||
@ -58,6 +65,26 @@ typedef struct {
|
|||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
} xvk_mapent_target_t;
|
} xvk_mapent_target_t;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Patch_Surface_NoPatch = 0,
|
||||||
|
Patch_Surface_Delete = 0x01,
|
||||||
|
Patch_Surface_Texture = 0x02,
|
||||||
|
Patch_Surface_Emissive = 0x04,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct texture_s;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t flags;
|
||||||
|
int tex_id;
|
||||||
|
const struct texture_s *tex;
|
||||||
|
vec3_t emissive;
|
||||||
|
} xvk_patch_surface_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
xvk_patch_surface_t *surfaces;
|
||||||
|
} xvk_patch_t;
|
||||||
|
|
||||||
#define MAX_MAPENT_TARGETS 256
|
#define MAX_MAPENT_TARGETS 256
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -70,6 +97,8 @@ typedef struct {
|
|||||||
|
|
||||||
int num_targets;
|
int num_targets;
|
||||||
xvk_mapent_target_t targets[MAX_MAPENT_TARGETS];
|
xvk_mapent_target_t targets[MAX_MAPENT_TARGETS];
|
||||||
|
|
||||||
|
xvk_patch_t patch;
|
||||||
} xvk_map_entities_t;
|
} xvk_map_entities_t;
|
||||||
|
|
||||||
extern xvk_map_entities_t g_map_entities;
|
extern xvk_map_entities_t g_map_entities;
|
||||||
|
@ -125,7 +125,7 @@ static void loadMaterialsFromFile( const char *filename ) {
|
|||||||
Q_snprintf(texture_path, sizeof(texture_path), "pbr%s", value);
|
Q_snprintf(texture_path, sizeof(texture_path), "pbr%s", value);
|
||||||
} else {
|
} else {
|
||||||
// Path relative to current material.mat file
|
// Path relative to current material.mat file
|
||||||
Q_snprintf(texture_path, sizeof(texture_path), "%.*s%s", path_end - path_begin, path_begin, value);
|
Q_snprintf(texture_path, sizeof(texture_path), "%.*s%s", (int)(path_end - path_begin), path_begin, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
tex_id = loadTexture(texture_path, force_reload);
|
tex_id = loadTexture(texture_path, force_reload);
|
||||||
|
@ -391,7 +391,11 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
|
|||||||
|
|
||||||
Vector4Copy(color, kusok->color);
|
Vector4Copy(color, kusok->color);
|
||||||
|
|
||||||
|
if (geom->material == kXVkMaterialEmissive) {
|
||||||
|
VectorCopy( geom->emissive, kusok->emissive );
|
||||||
|
} else {
|
||||||
XVK_GetEmissiveForTexture( kusok->emissive, geom->texture );
|
XVK_GetEmissiveForTexture( kusok->emissive, geom->texture );
|
||||||
|
}
|
||||||
|
|
||||||
if (geom->material == kXVkMaterialConveyor) {
|
if (geom->material == kXVkMaterialConveyor) {
|
||||||
computeConveyorSpeed( entcolor, geom->texture, kusok->uv_speed );
|
computeConveyorSpeed( entcolor, geom->texture, kusok->uv_speed );
|
||||||
|
@ -100,6 +100,9 @@ typedef struct vk_render_geometry_s {
|
|||||||
|
|
||||||
// Index into kusochki buffer for current frame
|
// Index into kusochki buffer for current frame
|
||||||
uint32_t kusok_index;
|
uint32_t kusok_index;
|
||||||
|
|
||||||
|
// for kXVkMaterialEmissive
|
||||||
|
vec3_t emissive;
|
||||||
} vk_render_geometry_t;
|
} vk_render_geometry_t;
|
||||||
|
|
||||||
struct vk_ray_model_s;
|
struct vk_ray_model_s;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "vk_cvar.h"
|
#include "vk_cvar.h"
|
||||||
#include "vk_materials.h"
|
#include "vk_materials.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
#include "vk_mapents.h"
|
||||||
|
|
||||||
#include "com_strings.h"
|
#include "com_strings.h"
|
||||||
#include "ref_params.h"
|
#include "ref_params.h"
|
||||||
@ -132,6 +133,9 @@ void R_NewMap( void )
|
|||||||
XVK_CHECK(vkBeginCommandBuffer(vk_core.cb, &beginfo));
|
XVK_CHECK(vkBeginCommandBuffer(vk_core.cb, &beginfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load light entities and patch data prior to loading map brush model
|
||||||
|
XVK_ParseMapEntities();
|
||||||
|
|
||||||
// Load all models at once
|
// Load all models at once
|
||||||
gEngine.Con_Reportf( "Num models: %d:\n", num_models );
|
gEngine.Con_Reportf( "Num models: %d:\n", num_models );
|
||||||
for( int i = 0; i < num_models; i++ )
|
for( int i = 0; i < num_models; i++ )
|
||||||
|
@ -644,7 +644,7 @@ qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, float *pscale )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec3_t org, vec3_t v_right, vec3_t v_up, float scale, int texture, int render_mode )
|
static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec3_t org, vec3_t v_right, vec3_t v_up, float scale, int texture, int render_mode, vec3_t color )
|
||||||
{
|
{
|
||||||
vec3_t point;
|
vec3_t point;
|
||||||
xvk_render_buffer_allocation_t vertex_buffer, index_buffer;
|
xvk_render_buffer_allocation_t vertex_buffer, index_buffer;
|
||||||
@ -710,6 +710,8 @@ static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec
|
|||||||
|
|
||||||
.element_count = 6,
|
.element_count = 6,
|
||||||
.index_offset = index_buffer.buffer.unit.offset,
|
.index_offset = index_buffer.buffer.unit.offset,
|
||||||
|
|
||||||
|
.emissive = {color[0], color[1], color[2]},
|
||||||
};
|
};
|
||||||
|
|
||||||
VK_RenderModelDynamicBegin( render_mode, "%s", debug_name );
|
VK_RenderModelDynamicBegin( render_mode, "%s", debug_name );
|
||||||
@ -937,7 +939,7 @@ void VK_SpriteDrawModel( cl_entity_t *e )
|
|||||||
ubo->color[3] = tr.blend;
|
ubo->color[3] = tr.blend;
|
||||||
*/
|
*/
|
||||||
VK_RenderStateSetColor( color[0], color[1], color[2], .5f ); // FIXME VK: tr.blend
|
VK_RenderStateSetColor( color[0], color[1], color[2], .5f ); // FIXME VK: tr.blend
|
||||||
R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode );
|
R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode, color );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -949,14 +951,14 @@ void VK_SpriteDrawModel( cl_entity_t *e )
|
|||||||
{
|
{
|
||||||
// FIXME VK make sure we end up with the same values as gl
|
// FIXME VK make sure we end up with the same values as gl
|
||||||
VK_RenderStateSetColor( color[0], color[1], color[2], 1.f * ilerp );
|
VK_RenderStateSetColor( color[0], color[1], color[2], 1.f * ilerp );
|
||||||
R_DrawSpriteQuad( model->name, oldframe, origin, v_right, v_up, scale, oldframe->gl_texturenum, e->curstate.rendermode );
|
R_DrawSpriteQuad( model->name, oldframe, origin, v_right, v_up, scale, oldframe->gl_texturenum, e->curstate.rendermode, color );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( lerp != 0.0f )
|
if( lerp != 0.0f )
|
||||||
{
|
{
|
||||||
// FIXME VK make sure we end up with the same values as gl
|
// FIXME VK make sure we end up with the same values as gl
|
||||||
VK_RenderStateSetColor( color[0], color[1], color[2], 1.f * lerp );
|
VK_RenderStateSetColor( color[0], color[1], color[2], 1.f * lerp );
|
||||||
R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode );
|
R_DrawSpriteQuad( model->name, frame, origin, v_right, v_up, scale, frame->gl_texturenum, e->curstate.rendermode, color );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -902,12 +902,12 @@ static struct {
|
|||||||
|
|
||||||
static int CheckSkybox( const char *name )
|
static int CheckSkybox( const char *name )
|
||||||
{
|
{
|
||||||
const char *skybox_ext[3] = { "dds", "tga", "bmp" };
|
const char *skybox_ext[] = { "png", "dds", "tga", "bmp" };
|
||||||
int i, j, num_checked_sides;
|
int i, j, num_checked_sides;
|
||||||
const char *sidename;
|
const char *sidename;
|
||||||
|
|
||||||
// search for skybox images
|
// search for skybox images
|
||||||
for( i = 0; i < 3; i++ )
|
for( i = 0; i < ARRAYSIZE(skybox_ext); i++ )
|
||||||
{
|
{
|
||||||
num_checked_sides = 0;
|
num_checked_sides = 0;
|
||||||
for( j = 0; j < 6; j++ )
|
for( j = 0; j < 6; j++ )
|
||||||
@ -937,53 +937,25 @@ static int CheckSkybox( const char *name )
|
|||||||
return SKYBOX_MISSED;
|
return SKYBOX_MISSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XVK_SetupSky( const char *skyboxname )
|
static qboolean loadSkybox( const char *prefix, int style ) {
|
||||||
{
|
|
||||||
char loadname[MAX_STRING];
|
|
||||||
char sidename[MAX_STRING];
|
|
||||||
int i, result, len;
|
|
||||||
rgbdata_t *sides[6];
|
rgbdata_t *sides[6];
|
||||||
qboolean success = false;
|
qboolean success = false;
|
||||||
|
int i;
|
||||||
if( !COM_CheckString( skyboxname ))
|
|
||||||
{
|
|
||||||
unloadSkybox();
|
|
||||||
return; // clear old skybox
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_snprintf( loadname, sizeof( loadname ), "gfx/env/%s", skyboxname );
|
|
||||||
COM_StripExtension( loadname );
|
|
||||||
|
|
||||||
// kill the underline suffix to find them manually later
|
|
||||||
len = Q_strlen( loadname );
|
|
||||||
|
|
||||||
if( loadname[len - 1] == '_' )
|
|
||||||
loadname[len - 1] = '\0';
|
|
||||||
result = CheckSkybox( loadname );
|
|
||||||
|
|
||||||
// to prevent infinite recursion if default skybox was missed
|
|
||||||
if( result == SKYBOX_MISSED && Q_stricmp( loadname, DEFAULT_SKYBOX_PATH ))
|
|
||||||
{
|
|
||||||
gEngine.Con_Reportf( S_WARN "missed or incomplete skybox '%s'\n", skyboxname );
|
|
||||||
XVK_SetupSky( "desert" ); // force to default
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// release old skybox
|
// release old skybox
|
||||||
unloadSkybox();
|
unloadSkybox();
|
||||||
gEngine.Con_DPrintf( "SKY: " );
|
gEngine.Con_DPrintf( "SKY: " );
|
||||||
|
|
||||||
for( i = 0; i < 6; i++ )
|
for( i = 0; i < 6; i++ ) {
|
||||||
{
|
char sidename[MAX_STRING];
|
||||||
if( result == SKYBOX_HLSTYLE )
|
if( style == SKYBOX_HLSTYLE )
|
||||||
Q_snprintf( sidename, sizeof( sidename ), "%s%s", loadname, g_skybox_info[i].suffix );
|
Q_snprintf( sidename, sizeof( sidename ), "%s%s", prefix, g_skybox_info[i].suffix );
|
||||||
else Q_snprintf( sidename, sizeof( sidename ), "%s_%s", loadname, g_skybox_info[i].suffix );
|
else Q_snprintf( sidename, sizeof( sidename ), "%s_%s", prefix, g_skybox_info[i].suffix );
|
||||||
|
|
||||||
sides[i] = gEngine.FS_LoadImage( sidename, NULL, 0);
|
sides[i] = gEngine.FS_LoadImage( sidename, NULL, 0);
|
||||||
if (!sides[i] || !sides[i]->buffer)
|
if (!sides[i] || !sides[i]->buffer)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
uint img_flags = g_skybox_info[i].flags;
|
uint img_flags = g_skybox_info[i].flags;
|
||||||
// we need to expand image into RGBA buffer
|
// we need to expand image into RGBA buffer
|
||||||
@ -991,16 +963,16 @@ void XVK_SetupSky( const char *skyboxname )
|
|||||||
img_flags |= IMAGE_FORCE_RGBA;
|
img_flags |= IMAGE_FORCE_RGBA;
|
||||||
gEngine.Image_Process( &sides[i], 0, 0, img_flags, 0.f );
|
gEngine.Image_Process( &sides[i], 0, 0, img_flags, 0.f );
|
||||||
}
|
}
|
||||||
gEngine.Con_DPrintf( "%s%s%s", skyboxname, g_skybox_info[i].suffix, i != 5 ? ", " : ". " );
|
gEngine.Con_DPrintf( "%s%s%s", prefix, g_skybox_info[i].suffix, i != 5 ? ", " : ". " );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i != 6 )
|
if( i != 6 )
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if( !Common_CheckTexName( loadname ))
|
if( !Common_CheckTexName( prefix ))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
Q_strncpy( tglob.skybox_cube.name, loadname, sizeof( tglob.skybox_cube.name ));
|
Q_strncpy( tglob.skybox_cube.name, prefix, sizeof( tglob.skybox_cube.name ));
|
||||||
success = uploadTexture(&tglob.skybox_cube, sides, 6, true);
|
success = uploadTexture(&tglob.skybox_cube, sides, 6, true);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@ -1015,4 +987,40 @@ cleanup:
|
|||||||
gEngine.Con_DPrintf( "^2failed\n" );
|
gEngine.Con_DPrintf( "^2failed\n" );
|
||||||
unloadSkybox();
|
unloadSkybox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *skybox_default = "desert";
|
||||||
|
static const char *skybox_prefixes[] = { "pbr/env/%s", "gfx/env/%s" };
|
||||||
|
|
||||||
|
void XVK_SetupSky( const char *skyboxname ) {
|
||||||
|
if( !COM_CheckString( skyboxname ))
|
||||||
|
{
|
||||||
|
unloadSkybox();
|
||||||
|
return; // clear old skybox
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < ARRAYSIZE(skybox_prefixes); ++i) {
|
||||||
|
char loadname[MAX_STRING];
|
||||||
|
int style, len;
|
||||||
|
|
||||||
|
Q_snprintf( loadname, sizeof( loadname ), skybox_prefixes[i], skyboxname );
|
||||||
|
COM_StripExtension( loadname );
|
||||||
|
|
||||||
|
// kill the underline suffix to find them manually later
|
||||||
|
len = Q_strlen( loadname );
|
||||||
|
|
||||||
|
if( loadname[len - 1] == '_' )
|
||||||
|
loadname[len - 1] = '\0';
|
||||||
|
style = CheckSkybox( loadname );
|
||||||
|
|
||||||
|
if (loadSkybox(loadname, style))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Q_stricmp(skyboxname, skybox_default) != 0) {
|
||||||
|
gEngine.Con_Reportf( S_WARN "missed or incomplete skybox '%s'\n", skyboxname );
|
||||||
|
XVK_SetupSky( "desert" ); // force to default
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user