the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 284 lines 12 kB view raw
1#include "stdafx.h" 2#include "Orbis_UIController.h" 3 4// Temp 5#include "..\Minecraft.h" 6#include "..\Textures.h" 7 8#define _ENABLEIGGY 9 10ConsoleUIController ui; 11 12void ConsoleUIController::init(S32 w, S32 h) 13{ 14#ifdef _ENABLEIGGY 15 16 // Shared init 17 preInit(w,h); 18 19 /* Now that Iggy is ready, we need to create a set of draw 20 callbacks for it to use to draw things on the target platform. 21 We're using the GNM GDraw implementation that's included with 22 the Iggy SDK. To get it set up, we need to provide it with 23 memory for the different resource type. GDraw needs memory 24 for render targets (color buffers), textures, and vertex buffers. 25 There's also command buffers and the staging buffer; we'll get to 26 them later. 27 28 We recommend that all resource pools be allocated in Garlic memory 29 for performance reasons. 30 31 Note that render target memory is really only used while Iggy is 32 rendering; you can share the memory space with other resources that 33 aren't in use while Iggy is rendering - for example, post-processing 34 render targets or shadow maps. 35 36 The texture and vertex buffer pools contain multiple textures and 37 vertex buffers. Each object requires a bit of main memory for management 38 overhead. We need to specify how many object handles can be in use at 39 the same time in any given pool. If Iggy runs out of GDraw handles, it 40 won't crash, but instead throw out old cache data in a LRU fashion. 41 If the number of handles is too small, this will happen frequently, and 42 textures will need to decoded multiple times (or vertex buffers re-generated 43 multiple times), which causes a performance hit. */ 44 45 // Size of the various memory pools. All these values are intentionally 46 // picked to be way larger than necessary for typical Flash files. 47 S32 rt_mem_size = 32*1024*1024; // Render target space 48 S32 tex_mem_size = 30*1024*1024; // Texture pool 49 S32 vert_mem_size = 2*1024*1024; // Vertex buffer pool 50 51 S32 tex_handles = 200; 52 S32 vert_handles = 1000; 53 54 /* SetResourceMemory is the call that actually sets up the location and size 55 of a resource pool. */ 56 gdraw_orbis_SetResourceMemory(GDRAW_ORBIS_RESOURCE_rendertarget, // Pool type 57 0, // Number of handles (unused for render targets) 58 RenderManager.MemoryAllocateGPUMem(GDRAW_ORBIS_TEXTURE_ALIGNMENT,rt_mem_size), // Pointer 59 rt_mem_size); // Size 60 gdraw_orbis_SetResourceMemory(GDRAW_ORBIS_RESOURCE_texture, tex_handles, 61 RenderManager.MemoryAllocateGPUMem(GDRAW_ORBIS_TEXTURE_ALIGNMENT,tex_mem_size), tex_mem_size); 62 gdraw_orbis_SetResourceMemory(GDRAW_ORBIS_RESOURCE_vertexbuffer, vert_handles, 63 RenderManager.MemoryAllocateGPUMem(GDRAW_ORBIS_VERTEXBUFFER_ALIGNMENT,vert_mem_size), vert_mem_size); 64 65 /* There's one more resource-related buffer we need to allocate: the staging 66 buffer. The staging buffer is used as a staging area for texture and vertex 67 buffer uploads. GDraw doesn't write such data directly to resource memory 68 from the CPU because doing so would require us to synchronize GPU and CPU such 69 that the CPU never accesses memory that the GPU might currently be using. This 70 wastes both CPU and GPU time, and makes it very hard to record command buffers 71 (GfxContexts) early in the frame and then kick them off later. 72 73 Instead, GDraw writes all data to the staging buffer, and lets the GPU copy it 74 from the there to its final location. While this costs more memory, it avoids 75 all need for fine-grained CPU/GPU synchronization and makes it easy to, say, 76 have Iggy rendering happen on a second thread. 77 78 The staging buffer is also where per-frame dynamic vertex data and dynamic 79 textures (which in the case of Iggy means animated gradients) get allocated 80 from. The right way to think of the staging buffer is just as an extra block 81 of memory associated with the Iggy command buffer: if you always use the same 82 command buffer for Iggy rendering, you only need one staging buffer, if you 83 double-buffer commands, you need to use the same scheme for the staging buffer, 84 and so forth. Since this example uses only one GfxContext, we also use a single 85 staging buffer. 86 87 It's not immediately obvious how big the staging buffer should be; this example 88 sizes it so it's big enough to replace all resource pools every frame. This keeps 89 things simple but is excessive in practice. $gdraw_orbis_End can report back how 90 much of the staging buffer was used every frame, so you can use this as a guideline 91 to size it appropriately. If the staging buffer is too small, Iggy will issue a 92 warning, and some textures or shapes might pop in a frame late (because they 93 couldn't be uploaded in time). 94 */ 95 staging_buf_size = 12 * 1024 * 1024; // This value determined by experimentation - was (with original comment): tex_mem_size + vert_mem_size; // This is very generous! 96 staging_buf[0] = RenderManager.MemoryAllocateCPUMem(Gnm::kAlignmentOfBufferInBytes,staging_buf_size); 97 staging_buf[1] = RenderManager.MemoryAllocateCPUMem(Gnm::kAlignmentOfBufferInBytes,staging_buf_size); 98 currentStagingBuf = 0; 99 100 /* Whew! Now that the GDraw memory configuration is set up, we need to initialize 101 GDraw. But first, we need to allocate yet another block of video memory for 102 GDraw to store its shaders etc. in. Unlike the rest of the memory configuration, 103 the work area is reserved to GDraw and can't be freed or relocated afterwards 104 without shutting GDraw and all attached Iggys down completely. But it's fairly 105 small (64k as of this writing) so this shouldn't be much of a problem. It should 106 be allocated in Garlic memory. */ 107 void *gdraw_context_mem = RenderManager.MemoryAllocateGPUMem(1,GDRAW_ORBIS_CONTEXT_MEM_SIZE); 108 109 /* Finally, we can actually create the GDraw GNM driver and pass it to Iggy. */ 110 gdraw_funcs = gdraw_orbis_CreateContext( 111 w, 112 h, 113 gdraw_context_mem); 114 IggySetGDraw(gdraw_funcs); 115 116 /* Flash content can have audio embedded. We'd like to be able 117 to play back any audio there is in the Flash that we load, 118 but in this tutorial we don't care about processing the sound 119 ourselves. So we call $IggyAudioUseDefault to tell Iggy 120 to go ahead and use the default sound driver. */ 121 //IggyAudioUseDefault(); 122 123 // Shared init 124 postInit(); 125#endif 126} 127 128void ConsoleUIController::render() 129{ 130#ifdef _ENABLEIGGY 131 /* Tell GDraw which command buffer and staging buffer to use 132 for rendering. GDraw can either render to its own command 133 buffer or resume writing to a GfxContext you're already 134 using. In this example, we render only Iggy content, so 135 we have the command buffer to ourselves. Between this 136 call and $gdraw_orbis_End, you are not allowed to write 137 to the command buffer ("gfxc" in this case). */ 138 gdraw_orbis_Begin(RenderManager.GetCurrentBackBufferContext(), staging_buf[currentStagingBuf], staging_buf_size); 139 currentStagingBuf ^= 1; 140 141 /* We need to tell GDraw which surface to render to. 142 This tutorial just uses our main color and depth buffers, 143 but for in-game UI usage, you might want to use another 144 render target (like a texture) instead. */ 145 gdraw_orbis_SetTileOrigin(RenderManager.GetCurrentBackBufferTarget(), RenderManager.GetCurrentBackBufferDepthTarget(), 0, 0); 146 147 renderScenes(); 148 149 /* That's it for this frame, so tell GDraw we're done rendering. 150 This function can optionally return $gdraw_orbis_staging_stats 151 to track staging buffer usage, which is useful information to 152 size the buffer appropriately. In this example though, we 153 don't bother. 154 155 After this call, you may resume writing to the command buffer 156 passed to $gdraw_orbis_Begin ("gfxc" in this example). */ 157 158#if 0 159 gdraw_orbis_staging_stats stagingStats; 160 gdraw_orbis_End(&stagingStats); 161 162 static int throttle = 0; 163 static int maxAttempted = 0; 164 static int maxSucceeded = 0; 165 166 if( stagingStats.bytes_attempted > maxAttempted ) maxAttempted = stagingStats.bytes_attempted; 167 if( stagingStats.bytes_succeeded > maxSucceeded ) maxSucceeded = stagingStats.bytes_succeeded; 168 169 if( ( throttle & 400 ) == 0 ) 170 { 171 app.DebugPrintf("\nIGGY END DRAW\n"); 172 app.DebugPrintf(" - allocs_attempted = %d\n", stagingStats.allocs_attempted); // number of allocations attempted from the staging buffer 173 app.DebugPrintf(" - allocs_succeeded = %d\n", stagingStats.allocs_succeeded);// number of allocations that succeeded 174 app.DebugPrintf(" - bytes_attempted = %d\n", stagingStats.bytes_attempted);// number of bytes attempted to allocate 175 app.DebugPrintf(" - bytes_succeeded = %d\n", stagingStats.bytes_succeeded);// number of bytes successfully allocated 176 app.DebugPrintf(" - max bytes_attempted = %d\n", maxAttempted); 177 app.DebugPrintf(" - max bytes_succeeded = %d\n", maxSucceeded); 178 app.DebugPrintf(" - largest_bytes_attempted = %d\n", stagingStats.largest_bytes_attempted);// number of bytes in largest attempted alloc 179 app.DebugPrintf(" - largest_bytes_succeeded = %d\n", stagingStats.largest_bytes_succeeded);// number of bytes in lagrest successful allo 180 app.DebugPrintf("\n\n"); 181 } 182 throttle++; 183 184#else 185 gdraw_orbis_End(NULL); 186#endif 187 188#endif 189} 190 191void ConsoleUIController::beginIggyCustomDraw4J(IggyCustomDrawCallbackRegion *region, CustomDrawData *customDrawRegion) 192{ 193 PIXBeginNamedEvent(0,"Starting Iggy custom draw\n"); 194 195 PIXBeginNamedEvent(0,"Gdraw setup"); 196 // get the correct object-to-world matrix from GDraw, and set the render state to a normal state 197 gdraw_orbis_BeginCustomDraw(region, customDrawRegion->mat); 198 PIXEndNamedEvent(); 199} 200 201CustomDrawData *ConsoleUIController::setupCustomDraw(UIScene *scene, IggyCustomDrawCallbackRegion *region) 202{ 203 CustomDrawData *customDrawRegion = new CustomDrawData(); 204 customDrawRegion->x0 = region->x0; 205 customDrawRegion->x1 = region->x1; 206 customDrawRegion->y0 = region->y0; 207 customDrawRegion->y1 = region->y1; 208 209 // get the correct object-to-world matrix from GDraw, and set the render state to a normal state 210 gdraw_orbis_BeginCustomDraw(region, customDrawRegion->mat); 211 212 setupCustomDrawGameStateAndMatrices(scene, customDrawRegion); 213 214 return customDrawRegion; 215} 216 217CustomDrawData *ConsoleUIController::calculateCustomDraw(IggyCustomDrawCallbackRegion *region) 218{ 219 CustomDrawData *customDrawRegion = new CustomDrawData(); 220 customDrawRegion->x0 = region->x0; 221 customDrawRegion->x1 = region->x1; 222 customDrawRegion->y0 = region->y0; 223 customDrawRegion->y1 = region->y1; 224 225 gdraw_orbis_CalculateCustomDraw_4J(region, customDrawRegion->mat); 226 227 return customDrawRegion; 228} 229 230void ConsoleUIController::endCustomDraw(IggyCustomDrawCallbackRegion *region) 231{ 232 endCustomDrawGameStateAndMatrices(); 233 234 gdraw_orbis_EndCustomDraw(region); 235} 236 237void ConsoleUIController::setTileOrigin(S32 xPos, S32 yPos) 238{ 239 gdraw_orbis_SetTileOrigin(RenderManager.GetCurrentBackBufferTarget(), RenderManager.GetCurrentBackBufferDepthTarget(), xPos, yPos); 240} 241 242GDrawTexture *ConsoleUIController::getSubstitutionTexture(int textureId) 243{ 244 /* Create a wrapped texture from a shader resource view. 245 A wrapped texture can be used to let Iggy draw using the contents of a texture 246 you create and manage on your own. For example, you might render to this texture, 247 or stream video into it. Wrapped textures take up a handle. They will never be 248 freed or otherwise modified by GDraw; nor will GDraw change any reference counts. 249 All this is up to the application. */ 250 251 sce::Gnm::Texture *tex = RenderManager.TextureGetTexture(textureId); 252 GDrawTexture *gdrawTex = gdraw_orbis_WrappedTextureCreate(tex); 253 return gdrawTex; 254 255 return NULL; 256} 257 258void ConsoleUIController::destroySubstitutionTexture(void *destroyCallBackData, GDrawTexture *handle) 259{ 260 /* Destroys the GDraw wrapper for a wrapped texture object. This will free up 261 a GDraw texture handle but not release the associated D3D texture; that is 262 up to you. */ 263 gdraw_orbis_WrappedTextureDestroy(handle); 264} 265 266void ConsoleUIController::shutdown() 267{ 268#ifdef _ENABLEIGGY 269 /* Destroy the GDraw context. This frees all resources, shaders etc. 270 allocated by GDraw. Note this is only safe to call after all 271 active Iggy player have been destroyed! */ 272 gdraw_orbis_DestroyContext(); 273#endif 274} 275 276 277void ConsoleUIController::handleUnlockFullVersionCallback() 278{ 279 for(unsigned int i = 0; i < eUIGroup_COUNT; ++i) 280 { 281 ui.m_groups[i]->handleUnlockFullVersion(); 282 } 283} 284