/*
* write the full path of the addon's folder into the vg_str
*/
-static int addon_get_content_folder( addon_reg *reg, vg_str *folder ){
+static int addon_get_content_folder( addon_reg *reg, vg_str *folder, int async){
if( reg->alias.workshop_id ){
- vg_async_item *call =
- vg_async_alloc( sizeof(struct async_workshop_filepath_info) );
- struct async_workshop_filepath_info *info = call->payload;
+ struct async_workshop_filepath_info *info = NULL;
+ vg_async_item *call = NULL;
+
+ if( async ){
+ call = vg_async_alloc( sizeof(struct async_workshop_filepath_info) );
+ info = call->payload;
+ }
+ else
+ info = alloca( sizeof(struct async_workshop_filepath_info) );
+
info->buf = folder->buffer;
info->id = reg->alias.workshop_id;
info->len = folder->len;
- vg_async_dispatch( call, async_workshop_get_filepath );
- vg_async_stall(); /* too bad! */
+
+ if( async ){
+ vg_async_dispatch( call, async_workshop_get_filepath );
+ vg_async_stall(); /* too bad! */
+ }
+ else {
+ async_workshop_get_filepath( info, 0 );
+ }
+
if( info->buf[0] == '\0' ){
vg_error( "Failed SteamAPI_GetItemInstallInfo(" PRINTF_U64 ")\n",
reg->alias.workshop_id );
vg_str folder;
vg_strnull( &folder, path_buf, 4096 );
- if( addon_get_content_folder( reg, &folder ) ){
+ if( addon_get_content_folder( reg, &folder, 1 ) ){
if( addon_cache_load_request( type, id, reg, folder ) ){
vg_async_call( async_addon_setstate,
entry, k_addon_cache_state_loaded );
static addon_reg *get_addon_from_index( enum addon_type type, u32 index,
u32 ignoreflags );
static u32 get_index_from_addon( enum addon_type type, addon_reg *a );
-static int addon_get_content_folder( addon_reg *reg, vg_str *folder );
+static int addon_get_content_folder( addon_reg *reg, vg_str *folder, int async);
/* scanning routines */
static u32 addon_match( addon_alias *alias );
m.tex_diffuse = sr_compile_texture(inf['tex_diffuse'])
#}
+ if mat.SR_data.tex_diffuse_rt >= 0:#{
+ m.tex_diffuse = 0x80000000 | mat.SR_data.tex_diffuse_rt
+ #}
+
sr_compile.material_data.extend( bytearray(m) )
return index
#}
_.layout.prop( active_mat.SR_data, "shader" )
_.layout.prop( active_mat.SR_data, "surface_prop" )
_.layout.prop( active_mat.SR_data, "collision" )
+ _.layout.prop( active_mat.SR_data, "tex_diffuse_rt" )
if active_mat.SR_data.collision:#{
box = _.layout.box()
cubemap: bpy.props.PointerProperty( \
type=bpy.types.Object, name="cubemap", \
poll=lambda self,obj: sr_filter_ent_type(obj,['ent_cubemap']))
+
+ tex_diffuse_rt: bpy.props.IntProperty( name="diffuse: RT index", default=-1 )
#}
# ---------------------------------------------------------------------------- #
}
}
+struct async_preview_load_thread_data{
+ void *data;
+ addon_reg *reg;
+};
+
+static void skateshop_async_preview_imageload( void *data, u32 len ){
+ struct async_preview_load_thread_data *inf = data;
+
+ if( inf->data ){
+ glBindTexture( GL_TEXTURE_2D, global_skateshop.tex_preview );
+ glTexSubImage2D( GL_TEXTURE_2D, 0,0,0,
+ WORKSHOP_PREVIEW_WIDTH, WORKSHOP_PREVIEW_HEIGHT,
+ GL_RGB, GL_UNSIGNED_BYTE, inf->data );
+ glGenerateMipmap( GL_TEXTURE_2D );
+ stbi_image_free( inf->data );
+
+ skaterift.rt_textures[k_skaterift_rt_workshop_preview] =
+ global_skateshop.tex_preview;
+ }
+ else {
+ skaterift.rt_textures[k_skaterift_rt_workshop_preview] =
+ global_skateshop.tex_preview_err;
+ }
+
+ SDL_AtomicLock( &addon_system.sl_cache_using_resources );
+ global_skateshop.reg_loaded_preview = inf->reg;
+ SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
+}
+
+static void skateshop_update_preview_image_thread(void *_args){
+ char path_buf[4096];
+ vg_str folder;
+ vg_strnull( &folder, path_buf, sizeof(path_buf) );
+
+ SDL_AtomicLock( &addon_system.sl_cache_using_resources );
+ addon_reg *reg_preview = global_skateshop.reg_preview;
+ SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
+
+ if( !addon_get_content_folder( reg_preview, &folder, 1 ) ){
+ SDL_AtomicLock( &addon_system.sl_cache_using_resources );
+ global_skateshop.reg_loaded_preview = reg_preview;
+ SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
+ return;
+ }
+
+ vg_strcat( &folder, "/preview.jpg" );
+ vg_async_item *call =
+ vg_async_alloc( sizeof(struct async_preview_load_thread_data) );
+ struct async_preview_load_thread_data *inf = call->payload;
+
+ inf->reg = reg_preview;
+
+ if( vg_strgood( &folder ) ){
+ stbi_set_flip_vertically_on_load(1);
+ int x, y, nc;
+ inf->data = stbi_load( folder.buffer, &x, &y, &nc, 3 );
+
+ if( inf->data ){
+ if( (x != WORKSHOP_PREVIEW_WIDTH) || (y != WORKSHOP_PREVIEW_HEIGHT) ){
+ vg_error( "Resolution does not match framebuffer, so we can't"
+ " show it\n" );
+ stbi_image_free( inf->data );
+ inf->data = NULL;
+ }
+ }
+
+ vg_async_dispatch( call, skateshop_async_preview_imageload );
+ }
+}
+
/*
* op/subroutine: k_workshop_op_item_load
* -----------------------------------------------------------------------------
if( !vg_loader_availible() ) return;
SDL_AtomicLock( &addon_system.sl_cache_using_resources );
+ if( global_skateshop.reg_preview != global_skateshop.reg_loaded_preview ){
+ SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
+ vg_loader_start( skateshop_update_preview_image_thread, NULL );
+ return;
+ }
+
for( u32 type=0; type<k_addon_type_max; type++ ){
struct addon_cache *cache = &addon_system.cache[type];
addon_cache_entry *entry = vg_pool_item( &cache->pool, id );
if( entry->state == k_addon_cache_state_load_request ){
SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
- goto launch;
+ vg_loader_start( board_processview_thread, NULL );
+ return;
}
}
}
SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
- return;
-launch:
- vg_loader_start( board_processview_thread, NULL );
}
/*
* -----------------------------------------------------------------------------
*/
+static void skateshop_init_async(void *_data,u32 size){
+ glGenTextures( 1, &global_skateshop.tex_preview );
+ glBindTexture( GL_TEXTURE_2D, global_skateshop.tex_preview );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB,
+ WORKSHOP_PREVIEW_WIDTH, WORKSHOP_PREVIEW_HEIGHT,
+ 0, GL_RGB, GL_UNSIGNED_BYTE, NULL );
+
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+}
+
/*
* VG event init
*/
static void skateshop_init(void){
+ vg_async_call( skateshop_init_async, NULL, 0 );
+ vg_tex2d_replace_with_error( &global_skateshop.tex_preview_err );
+ vg_async_stall();
+
+ skaterift.rt_textures[ k_skaterift_rt_workshop_preview ] =
+ global_skateshop.tex_preview_err;
}
static u16 skateshop_selected_cache_id(void){
global_skateshop.helper_browse->greyed = !browseable;
global_skateshop.helper_pick->greyed = !loadable;
- int change = 0;
+ addon_reg *selected_world = NULL;
+ int change = 0;
if( browseable ){
if( button_down( k_srbind_mleft ) ){
if( global_skateshop.selected_world_id > 0 ){
change = 1;
}
}
+
+ selected_world = get_addon_from_index( k_addon_type_world,
+ global_skateshop.selected_world_id, ADDON_REG_HIDDEN );
+
+ if( change || (global_skateshop.reg_preview == NULL) ){
+ SDL_AtomicLock( &addon_system.sl_cache_using_resources );
+ global_skateshop.reg_preview = selected_world;
+ SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
+ }
}
if( loadable ){
if( button_down( k_srbind_maccept ) ){
- skaterift_change_world_start(
- get_addon_from_index( k_addon_type_world,
- global_skateshop.selected_world_id,
- ADDON_REG_HIDDEN ));
+ skaterift_change_world_start( selected_world );
}
}
}
render;
struct gui_helper *helper_pick, *helper_browse;
+
+ addon_reg *reg_preview, *reg_loaded_preview;
+ GLuint tex_preview, tex_preview_err;
}
-static global_skateshop={.render={.reg_id=0xffffffff,.world_reg=0xffffffff}};
+static global_skateshop={
+ .render={.reg_id=0xffffffff,.world_reg=0xffffffff}
+};
static void ent_skateshop_preupdate( ent_skateshop *shop, int active );
static void skateshop_render( ent_skateshop *shop );
#include "world.h"
#include "addon.h"
+enum skaterift_rt {
+ k_skaterift_rt_workshop_preview,
+ k_skaterift_rt_max
+};
+
struct{
enum async_operation{
k_async_op_none,
activity;
f64 last_autosave;
+ GLuint rt_textures[k_skaterift_rt_max];
}
static skaterift = { .op = k_async_op_clientloading, .time_rate = 1.0f };
vg_strnull( &path, path_buf, 4096 );
assert( reg );
- addon_get_content_folder( reg, &path );
+ addon_get_content_folder( reg, &path, 1 );
vg_str folder = path;
if( !vg_strgood( &folder ) ) {
#include "respawn.h"
#include "ent_miniworld.h"
#include "player_remote.h"
+#include "ent_skateshop.h"
static int ccmd_set_time( int argc, const char *argv[] ){
world_instance *world = world_current_instance();
glEnable( GL_CULL_FACE );
}
+static GLuint world_get_texture( world_instance *world, u32 id ){
+ if( id & 0x80000000 )
+ return skaterift.rt_textures[id & ~0x80000000];
+ else
+ return world->textures[ id ];
+}
+
static void bindpoint_diffuse_texture1( world_instance *world,
- struct world_surface *mat )
-
-{
+ struct world_surface *mat ){
glActiveTexture( GL_TEXTURE1 );
- glBindTexture( GL_TEXTURE_2D, world->textures[ mat->info.tex_diffuse ] );
+ glBindTexture( GL_TEXTURE_2D,
+ world_get_texture(world,mat->info.tex_diffuse) );
}
static void bindpoint_diffuse1_and_cubemap10( world_instance *world,
struct world_surface *mat ){
glActiveTexture( GL_TEXTURE1 );
- glBindTexture( GL_TEXTURE_2D, world->textures[ mat->info.tex_diffuse ] );
+ glBindTexture( GL_TEXTURE_2D,
+ world_get_texture(world,mat->info.tex_diffuse) );
u32 cubemap_id = mat->info.tex_none0,
cubemap_index = 0;
struct world_surface *mat )
{
glActiveTexture( GL_TEXTURE1 );
- glBindTexture( GL_TEXTURE_2D, world->textures[ mat->info.tex_diffuse ] );
+ glBindTexture( GL_TEXTURE_2D,
+ world_get_texture(world,mat->info.tex_diffuse) );
shader_scene_terrain_uSandColour( mat->info.colour );
shader_scene_terrain_uBlendOffset( mat->info.colour1 );
}
else{
glActiveTexture( GL_TEXTURE1 );
- glBindTexture( GL_TEXTURE_2D, world->textures[ mat->info.tex_diffuse ] );
+ glBindTexture( GL_TEXTURE_2D,
+ world_get_texture(world,mat->info.tex_diffuse) );
shader_scene_override_uAlphatest(1);
}
}