rtx: add metalness and roughness map support
overrides existing textures. loads override data from pbr/materials.map
This commit is contained in:
parent
e8359b12e8
commit
bd4de6128c
|
@ -95,19 +95,6 @@ static struct {
|
||||||
|
|
||||||
} g_lights_bsp = {0};
|
} g_lights_bsp = {0};
|
||||||
|
|
||||||
static int lookupTextureF( const char *fmt, ...) {
|
|
||||||
int tex_id = 0;
|
|
||||||
char buffer[1024];
|
|
||||||
va_list argptr;
|
|
||||||
va_start( argptr, fmt );
|
|
||||||
vsnprintf( buffer, sizeof buffer, fmt, argptr );
|
|
||||||
va_end( argptr );
|
|
||||||
|
|
||||||
tex_id = VK_FindTexture(buffer);
|
|
||||||
gEngine.Con_Reportf("Looked up texture %s -> %d\n", buffer, tex_id);
|
|
||||||
return tex_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void loadRadData( const model_t *map, const char *fmt, ... ) {
|
static void loadRadData( const model_t *map, const char *fmt, ... ) {
|
||||||
fs_offset_t size;
|
fs_offset_t size;
|
||||||
char *data;
|
char *data;
|
||||||
|
@ -183,19 +170,21 @@ static void loadRadData( const model_t *map, const char *fmt, ... ) {
|
||||||
texture_name += 1;
|
texture_name += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME replace this with findTexturesNamedLike from vk_materials.c
|
||||||
|
|
||||||
// Try bsp texture first
|
// Try bsp texture first
|
||||||
tex_id = lookupTextureF("#%s:%s.mip", map->name, texture_name);
|
tex_id = XVK_TextureLookupF("#%s:%s.mip", map->name, texture_name);
|
||||||
|
|
||||||
// Try wad texture if bsp is not there
|
// Try wad texture if bsp is not there
|
||||||
if (!tex_id && wad_name) {
|
if (!tex_id && wad_name) {
|
||||||
tex_id = lookupTextureF("%s.wad/%s.mip", wad_name, texture_name);
|
tex_id = XVK_TextureLookupF("%s.wad/%s.mip", wad_name, texture_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tex_id) {
|
if (!tex_id) {
|
||||||
const char *wad = g_map_entities.wadlist;
|
const char *wad = g_map_entities.wadlist;
|
||||||
for (; *wad;) {
|
for (; *wad;) {
|
||||||
const char *const wad_end = Q_strchr(wad, ';');
|
const char *const wad_end = Q_strchr(wad, ';');
|
||||||
tex_id = lookupTextureF("%.*s/%s.mip", wad_end - wad, wad, texture_name);
|
tex_id = XVK_TextureLookupF("%.*s/%s.mip", wad_end - wad, wad, texture_name);
|
||||||
if (tex_id)
|
if (tex_id)
|
||||||
break;
|
break;
|
||||||
wad = wad_end + 1;
|
wad = wad_end + 1;
|
||||||
|
|
|
@ -1,25 +1,146 @@
|
||||||
#include "vk_materials.h"
|
#include "vk_materials.h"
|
||||||
#include "vk_textures.h"
|
#include "vk_textures.h"
|
||||||
|
#include "vk_mapents.h"
|
||||||
#include "vk_const.h"
|
#include "vk_const.h"
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
xvk_material_t materials[MAX_TEXTURES];
|
xvk_material_t materials[MAX_TEXTURES];
|
||||||
} g_materials;
|
} g_materials;
|
||||||
|
|
||||||
|
static int findTextureNamedLike( const char *texture_name ) {
|
||||||
|
const model_t *map = gEngine.pfnGetModelByIndex( 1 );
|
||||||
|
string texname;
|
||||||
|
int tex_id;
|
||||||
|
|
||||||
|
// Try bsp texture first
|
||||||
|
tex_id = XVK_TextureLookupF("#%s:%s.mip", map->name, texture_name);
|
||||||
|
|
||||||
|
if (!tex_id) {
|
||||||
|
const char *wad = g_map_entities.wadlist;
|
||||||
|
for (; *wad;) {
|
||||||
|
const char *const wad_end = Q_strchr(wad, ';');
|
||||||
|
tex_id = XVK_TextureLookupF("%.*s/%s.mip", wad_end - wad, wad, texture_name);
|
||||||
|
if (tex_id)
|
||||||
|
break;
|
||||||
|
wad = wad_end + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tex_id ? tex_id : -1;
|
||||||
|
}
|
||||||
|
static int loadTextureF( const char *fmt, ... ) {
|
||||||
|
int tex_id = 0;
|
||||||
|
char buffer[1024];
|
||||||
|
va_list argptr;
|
||||||
|
|
||||||
|
va_start( argptr, fmt );
|
||||||
|
vsnprintf( buffer, sizeof buffer, fmt, argptr );
|
||||||
|
va_end( argptr );
|
||||||
|
|
||||||
|
tex_id = VK_LoadTexture( buffer, NULL, 0, 0);
|
||||||
|
gEngine.Con_Reportf("Loading texture %s => %d\n", buffer, tex_id);
|
||||||
|
return tex_id ? tex_id : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loadMaterialsFromFile( const char *filename ) {
|
||||||
|
fs_offset_t size;
|
||||||
|
const char *const path_begin = filename;
|
||||||
|
const char *path_end = Q_strrchr(filename, '/');
|
||||||
|
byte *data = gEngine.COM_LoadFile( filename, 0, false );
|
||||||
|
char *pos = data;
|
||||||
|
xvk_material_t current_material = {
|
||||||
|
.base_color = -1,
|
||||||
|
.metalness = tglob.blackTexture,
|
||||||
|
.roughness = tglob.whiteTexture,
|
||||||
|
.normalmap = tglob.grayTexture,
|
||||||
|
};
|
||||||
|
int current_material_index = -1;
|
||||||
|
|
||||||
|
if ( !data )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( !path_end )
|
||||||
|
path_end = path_begin;
|
||||||
|
else
|
||||||
|
path_end++;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
char key[1024];
|
||||||
|
char value[1024];
|
||||||
|
|
||||||
|
pos = COM_ParseFile(pos, key, sizeof(key));
|
||||||
|
ASSERT(Q_strlen(key) < sizeof(key));
|
||||||
|
if (!pos)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (key[0] == '{') {
|
||||||
|
current_material = (xvk_material_t){
|
||||||
|
.base_color = -1,
|
||||||
|
.metalness = tglob.blackTexture,
|
||||||
|
.roughness = tglob.whiteTexture,
|
||||||
|
.normalmap = tglob.grayTexture,
|
||||||
|
};
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key[0] == '}') {
|
||||||
|
if (current_material_index >= 0 && current_material.base_color >= 0) {
|
||||||
|
g_materials.materials[current_material_index] = current_material;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = COM_ParseFile(pos, value, sizeof(value));
|
||||||
|
if (!pos)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (Q_stricmp(key, "for") == 0) {
|
||||||
|
current_material_index = findTextureNamedLike(value);
|
||||||
|
} else if (Q_stricmp(key, "basecolor_map") == 0) {
|
||||||
|
if ((current_material.base_color = loadTextureF("%.*s%s", path_end - path_begin, path_begin, value)) < 0) {
|
||||||
|
gEngine.Con_Printf(S_ERROR "Failed to load basecolor_map texture %s\n", value);
|
||||||
|
}
|
||||||
|
} else if (Q_stricmp(key, "normal_map") == 0) {
|
||||||
|
if ((current_material.normalmap = loadTextureF("%.*s%s", path_end - path_begin, path_begin, value)) < 0) {
|
||||||
|
gEngine.Con_Printf(S_ERROR "Failed to load normal_map texture %s\n", value);
|
||||||
|
current_material.normalmap = tglob.grayTexture;
|
||||||
|
}
|
||||||
|
} else if (Q_stricmp(key, "metal_map") == 0) {
|
||||||
|
if ((current_material.metalness = loadTextureF("%.*s%s", path_end - path_begin, path_begin, value)) < 0) {
|
||||||
|
gEngine.Con_Printf(S_ERROR "Failed to load metal_map texture %s\n", value);
|
||||||
|
current_material.metalness = tglob.blackTexture;
|
||||||
|
}
|
||||||
|
} else if (Q_stricmp(key, "roughness_map") == 0) {
|
||||||
|
if ((current_material.roughness = loadTextureF("%.*s%s", path_end - path_begin, path_begin, value)) < 0) {
|
||||||
|
gEngine.Con_Printf(S_ERROR "Failed to load roughness_map texture %s\n", value);
|
||||||
|
current_material.roughness = tglob.whiteTexture;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gEngine.Con_Printf(S_ERROR "Unknown material key %s\n", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem_Free( data );
|
||||||
|
}
|
||||||
|
|
||||||
void XVK_ReloadMaterials( void ) {
|
void XVK_ReloadMaterials( void ) {
|
||||||
for (int i = 0; i < MAX_TEXTURES; ++i) {
|
for (int i = 0; i < MAX_TEXTURES; ++i) {
|
||||||
xvk_material_t *const mat = g_materials.materials + i;
|
xvk_material_t *const mat = g_materials.materials + i;
|
||||||
const vk_texture_t *const tex = findTexture( i );
|
const vk_texture_t *const tex = findTexture( i );
|
||||||
|
|
||||||
if (tex) {
|
if (!tex) {
|
||||||
mat->base_color = i;
|
|
||||||
mat->metalness = tglob.blackTexture;
|
|
||||||
mat->roughness = tglob.whiteTexture;
|
|
||||||
mat->normalmap = tglob.blackTexture;
|
|
||||||
} else {
|
|
||||||
mat->base_color = -1;
|
mat->base_color = -1;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat->base_color = i;
|
||||||
|
mat->metalness = tglob.blackTexture;
|
||||||
|
mat->roughness = tglob.whiteTexture;
|
||||||
|
mat->normalmap = tglob.grayTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadMaterialsFromFile( "pbr/materials.mat" );
|
||||||
|
// TODO map-specific
|
||||||
}
|
}
|
||||||
|
|
||||||
xvk_material_t* XVK_GetMaterialForTextureIndex( int tex_index ) {
|
xvk_material_t* XVK_GetMaterialForTextureIndex( int tex_index ) {
|
||||||
|
|
|
@ -108,11 +108,8 @@ void R_NewMap( void )
|
||||||
|
|
||||||
VK_LightsNewMap();
|
VK_LightsNewMap();
|
||||||
|
|
||||||
if (vk_core.rtx) {
|
if (vk_core.rtx)
|
||||||
VK_RayNewMap();
|
VK_RayNewMap();
|
||||||
XVK_ReloadMaterials();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// RTX map loading requires command buffer for building blases
|
// RTX map loading requires command buffer for building blases
|
||||||
if (vk_core.rtx)
|
if (vk_core.rtx)
|
||||||
|
@ -146,6 +143,7 @@ void R_NewMap( void )
|
||||||
|
|
||||||
// After we've loaded map brush model, we can proceed with loading static surface lights
|
// After we've loaded map brush model, we can proceed with loading static surface lights
|
||||||
VK_LightsLoadMapStaticLights();
|
VK_LightsLoadMapStaticLights();
|
||||||
|
XVK_ReloadMaterials(); // requires wadlist from entities, which are parsed in lights loading routine ....
|
||||||
|
|
||||||
if (vk_core.rtx)
|
if (vk_core.rtx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -878,3 +878,16 @@ void VK_ImageDestroy(vk_image_t *img) {
|
||||||
freeDeviceMemory(&img->devmem);
|
freeDeviceMemory(&img->devmem);
|
||||||
*img = (vk_image_t){0};
|
*img = (vk_image_t){0};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int XVK_TextureLookupF( const char *fmt, ...) {
|
||||||
|
int tex_id = 0;
|
||||||
|
char buffer[1024];
|
||||||
|
va_list argptr;
|
||||||
|
va_start( argptr, fmt );
|
||||||
|
vsnprintf( buffer, sizeof buffer, fmt, argptr );
|
||||||
|
va_end( argptr );
|
||||||
|
|
||||||
|
tex_id = VK_FindTexture(buffer);
|
||||||
|
gEngine.Con_Reportf("Looked up texture %s -> %d\n", buffer, tex_id);
|
||||||
|
return tex_id;
|
||||||
|
}
|
||||||
|
|
|
@ -63,6 +63,8 @@ int VK_CreateTextureArray( const char *name, int width, int height, int depth,
|
||||||
void VK_FreeTexture( unsigned int texnum );
|
void VK_FreeTexture( unsigned int texnum );
|
||||||
int VK_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update );
|
int VK_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update );
|
||||||
|
|
||||||
|
int XVK_TextureLookupF( const char *fmt, ...);
|
||||||
|
|
||||||
#define VK_LoadTextureInternal( name, pic, flags ) VK_LoadTextureFromBuffer( name, pic, flags, false )
|
#define VK_LoadTextureInternal( name, pic, flags ) VK_LoadTextureFromBuffer( name, pic, flags, false )
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
Loading…
Reference in New Issue