// releases resources allocated on the opengl end, storing local copy if requested void opengl_texture::release() { if( id == -1 ) { return; } if( true == Global.ResourceMove ) { // if resource move is enabled we don't keep a cpu side copy after upload // so need to re-acquire the data before release // TBD, TODO: instead of vram-ram transfer fetch the data 'normally' from the disk using worker thread if( type == "make:" ) { // auto generated textures only store a stub make_stub(); } else { ::glBindTexture( GL_TEXTURE_2D, id ); GLint datasize{}; GLint iscompressed{}; ::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &iscompressed ); if( iscompressed == GL_TRUE ) { // texture is compressed on the gpu side // query texture details needed to perform the backup... ::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &data_format ); ::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &datasize ); data.resize( datasize ); // ...fetch the data... ::glGetCompressedTexImage( GL_TEXTURE_2D, 0, &data[ 0 ] ); } else { // for whatever reason texture didn't get compressed during upload // fallback on plain rgba storage... data_format = GL_RGBA; data.resize( data_width * data_height * 4 ); // ...fetch the data... ::glGetTexImage( GL_TEXTURE_2D, 0, data_format, GL_UNSIGNED_BYTE, &data[ 0 ] ); } // ...and update texture object state data_mapcount = 1; // we keep copy of only top mipmap level data_state = resource_state::good; } } // release opengl resources ::glDeleteTextures( 1, &id ); id = -1; is_ready = false; return; }
// loads texture data from specified file // TODO: wrap it in a workitem class, for the job system deferred loading void opengl_texture::load() { if( type == "make:" ) { // for generated texture we delay data creation until texture is bound // this ensures the script will receive all simulation data it might potentially want // as any binding will happen after simulation is loaded, initialized and running // until then we supply data for a tiny 2x2 grey stub make_stub(); } else { WriteLog( "Loading texture data from \"" + name + type + "\"", logtype::texture ); data_state = resource_state::loading; if( type == ".dds" ) { load_DDS(); } else if( type == ".tga" ) { load_TGA(); } else if( type == ".png" ) { load_PNG(); } else if( type == ".bmp" ) { load_BMP(); } else if( type == ".tex" ) { load_TEX(); } else { goto fail; } } // data state will be set by called loader, so we're all done here if( data_state == resource_state::good ) { has_alpha = ( data_components == GL_RGBA ? true : false ); size = data.size() / 1024; return; } fail: data_state = resource_state::failed; ErrorLog( "Bad texture: failed to load texture \"" + name + type + "\"" ); // NOTE: temporary workaround for texture assignment errors id = 0; return; }
init_ws() { #ifndef GEM extern alice_window main_win; curr_window = &main_win; #endif curr_workspace = ws_list = Tptr(main_ws); #ifndef GEM main_win.wspace = curr_workspace; #endif linkup( curr_workspace, 0, make_stub( C_ROOT ) ); work_name(curr_workspace) = "main"; work_debug( curr_workspace ) = 0; #ifdef GEM do_gdupdate(); #endif printt1( "Initialize workspaces - main_ws is %x\n", Tptr(main_ws) ); /* an init_pwork will be done later if we decide to clip */ }
nodep comstub() { return make_stub( C_COMMENT ); }