This code was not tested and breaks in Release builds, reverting to restore
functionality of the nightly. All in-game menus do not work and generating
a world crashes.
This reverts commit a9be52c41a.
285 lines
12 KiB
C++
285 lines
12 KiB
C++
#include "stdafx.h"
|
|
#include "Orbis_UIController.h"
|
|
|
|
// Temp
|
|
#include "..\Minecraft.h"
|
|
#include "..\Textures.h"
|
|
|
|
#define _ENABLEIGGY
|
|
|
|
ConsoleUIController ui;
|
|
|
|
void ConsoleUIController::init(S32 w, S32 h)
|
|
{
|
|
#ifdef _ENABLEIGGY
|
|
|
|
// Shared init
|
|
preInit(w,h);
|
|
|
|
/* Now that Iggy is ready, we need to create a set of draw
|
|
callbacks for it to use to draw things on the target platform.
|
|
We're using the GNM GDraw implementation that's included with
|
|
the Iggy SDK. To get it set up, we need to provide it with
|
|
memory for the different resource type. GDraw needs memory
|
|
for render targets (color buffers), textures, and vertex buffers.
|
|
There's also command buffers and the staging buffer; we'll get to
|
|
them later.
|
|
|
|
We recommend that all resource pools be allocated in Garlic memory
|
|
for performance reasons.
|
|
|
|
Note that render target memory is really only used while Iggy is
|
|
rendering; you can share the memory space with other resources that
|
|
aren't in use while Iggy is rendering - for example, post-processing
|
|
render targets or shadow maps.
|
|
|
|
The texture and vertex buffer pools contain multiple textures and
|
|
vertex buffers. Each object requires a bit of main memory for management
|
|
overhead. We need to specify how many object handles can be in use at
|
|
the same time in any given pool. If Iggy runs out of GDraw handles, it
|
|
won't crash, but instead throw out old cache data in a LRU fashion.
|
|
If the number of handles is too small, this will happen frequently, and
|
|
textures will need to decoded multiple times (or vertex buffers re-generated
|
|
multiple times), which causes a performance hit. */
|
|
|
|
// Size of the various memory pools. All these values are intentionally
|
|
// picked to be way larger than necessary for typical Flash files.
|
|
S32 rt_mem_size = 32*1024*1024; // Render target space
|
|
S32 tex_mem_size = 30*1024*1024; // Texture pool
|
|
S32 vert_mem_size = 2*1024*1024; // Vertex buffer pool
|
|
|
|
S32 tex_handles = 200;
|
|
S32 vert_handles = 1000;
|
|
|
|
/* SetResourceMemory is the call that actually sets up the location and size
|
|
of a resource pool. */
|
|
gdraw_orbis_SetResourceMemory(GDRAW_ORBIS_RESOURCE_rendertarget, // Pool type
|
|
0, // Number of handles (unused for render targets)
|
|
RenderManager.MemoryAllocateGPUMem(GDRAW_ORBIS_TEXTURE_ALIGNMENT,rt_mem_size), // Pointer
|
|
rt_mem_size); // Size
|
|
gdraw_orbis_SetResourceMemory(GDRAW_ORBIS_RESOURCE_texture, tex_handles,
|
|
RenderManager.MemoryAllocateGPUMem(GDRAW_ORBIS_TEXTURE_ALIGNMENT,tex_mem_size), tex_mem_size);
|
|
gdraw_orbis_SetResourceMemory(GDRAW_ORBIS_RESOURCE_vertexbuffer, vert_handles,
|
|
RenderManager.MemoryAllocateGPUMem(GDRAW_ORBIS_VERTEXBUFFER_ALIGNMENT,vert_mem_size), vert_mem_size);
|
|
|
|
/* There's one more resource-related buffer we need to allocate: the staging
|
|
buffer. The staging buffer is used as a staging area for texture and vertex
|
|
buffer uploads. GDraw doesn't write such data directly to resource memory
|
|
from the CPU because doing so would require us to synchronize GPU and CPU such
|
|
that the CPU never accesses memory that the GPU might currently be using. This
|
|
wastes both CPU and GPU time, and makes it very hard to record command buffers
|
|
(GfxContexts) early in the frame and then kick them off later.
|
|
|
|
Instead, GDraw writes all data to the staging buffer, and lets the GPU copy it
|
|
from the there to its final location. While this costs more memory, it avoids
|
|
all need for fine-grained CPU/GPU synchronization and makes it easy to, say,
|
|
have Iggy rendering happen on a second thread.
|
|
|
|
The staging buffer is also where per-frame dynamic vertex data and dynamic
|
|
textures (which in the case of Iggy means animated gradients) get allocated
|
|
from. The right way to think of the staging buffer is just as an extra block
|
|
of memory associated with the Iggy command buffer: if you always use the same
|
|
command buffer for Iggy rendering, you only need one staging buffer, if you
|
|
double-buffer commands, you need to use the same scheme for the staging buffer,
|
|
and so forth. Since this example uses only one GfxContext, we also use a single
|
|
staging buffer.
|
|
|
|
It's not immediately obvious how big the staging buffer should be; this example
|
|
sizes it so it's big enough to replace all resource pools every frame. This keeps
|
|
things simple but is excessive in practice. $gdraw_orbis_End can report back how
|
|
much of the staging buffer was used every frame, so you can use this as a guideline
|
|
to size it appropriately. If the staging buffer is too small, Iggy will issue a
|
|
warning, and some textures or shapes might pop in a frame late (because they
|
|
couldn't be uploaded in time).
|
|
*/
|
|
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!
|
|
staging_buf[0] = RenderManager.MemoryAllocateCPUMem(Gnm::kAlignmentOfBufferInBytes,staging_buf_size);
|
|
staging_buf[1] = RenderManager.MemoryAllocateCPUMem(Gnm::kAlignmentOfBufferInBytes,staging_buf_size);
|
|
currentStagingBuf = 0;
|
|
|
|
/* Whew! Now that the GDraw memory configuration is set up, we need to initialize
|
|
GDraw. But first, we need to allocate yet another block of video memory for
|
|
GDraw to store its shaders etc. in. Unlike the rest of the memory configuration,
|
|
the work area is reserved to GDraw and can't be freed or relocated afterwards
|
|
without shutting GDraw and all attached Iggys down completely. But it's fairly
|
|
small (64k as of this writing) so this shouldn't be much of a problem. It should
|
|
be allocated in Garlic memory. */
|
|
void *gdraw_context_mem = RenderManager.MemoryAllocateGPUMem(1,GDRAW_ORBIS_CONTEXT_MEM_SIZE);
|
|
|
|
/* Finally, we can actually create the GDraw GNM driver and pass it to Iggy. */
|
|
gdraw_funcs = gdraw_orbis_CreateContext(
|
|
w,
|
|
h,
|
|
gdraw_context_mem);
|
|
IggySetGDraw(gdraw_funcs);
|
|
|
|
/* Flash content can have audio embedded. We'd like to be able
|
|
to play back any audio there is in the Flash that we load,
|
|
but in this tutorial we don't care about processing the sound
|
|
ourselves. So we call $IggyAudioUseDefault to tell Iggy
|
|
to go ahead and use the default sound driver. */
|
|
//IggyAudioUseDefault();
|
|
|
|
// Shared init
|
|
postInit();
|
|
#endif
|
|
}
|
|
|
|
void ConsoleUIController::render()
|
|
{
|
|
#ifdef _ENABLEIGGY
|
|
/* Tell GDraw which command buffer and staging buffer to use
|
|
for rendering. GDraw can either render to its own command
|
|
buffer or resume writing to a GfxContext you're already
|
|
using. In this example, we render only Iggy content, so
|
|
we have the command buffer to ourselves. Between this
|
|
call and $gdraw_orbis_End, you are not allowed to write
|
|
to the command buffer ("gfxc" in this case). */
|
|
gdraw_orbis_Begin(RenderManager.GetCurrentBackBufferContext(), staging_buf[currentStagingBuf], staging_buf_size);
|
|
currentStagingBuf ^= 1;
|
|
|
|
/* We need to tell GDraw which surface to render to.
|
|
This tutorial just uses our main color and depth buffers,
|
|
but for in-game UI usage, you might want to use another
|
|
render target (like a texture) instead. */
|
|
gdraw_orbis_SetTileOrigin(RenderManager.GetCurrentBackBufferTarget(), RenderManager.GetCurrentBackBufferDepthTarget(), 0, 0);
|
|
|
|
renderScenes();
|
|
|
|
/* That's it for this frame, so tell GDraw we're done rendering.
|
|
This function can optionally return $gdraw_orbis_staging_stats
|
|
to track staging buffer usage, which is useful information to
|
|
size the buffer appropriately. In this example though, we
|
|
don't bother.
|
|
|
|
After this call, you may resume writing to the command buffer
|
|
passed to $gdraw_orbis_Begin ("gfxc" in this example). */
|
|
|
|
#if 0
|
|
gdraw_orbis_staging_stats stagingStats;
|
|
gdraw_orbis_End(&stagingStats);
|
|
|
|
static int throttle = 0;
|
|
static int maxAttempted = 0;
|
|
static int maxSucceeded = 0;
|
|
|
|
if( stagingStats.bytes_attempted > maxAttempted ) maxAttempted = stagingStats.bytes_attempted;
|
|
if( stagingStats.bytes_succeeded > maxSucceeded ) maxSucceeded = stagingStats.bytes_succeeded;
|
|
|
|
if( ( throttle & 400 ) == 0 )
|
|
{
|
|
app.DebugPrintf("\nIGGY END DRAW\n");
|
|
app.DebugPrintf(" - allocs_attempted = %d\n", stagingStats.allocs_attempted); // number of allocations attempted from the staging buffer
|
|
app.DebugPrintf(" - allocs_succeeded = %d\n", stagingStats.allocs_succeeded);// number of allocations that succeeded
|
|
app.DebugPrintf(" - bytes_attempted = %d\n", stagingStats.bytes_attempted);// number of bytes attempted to allocate
|
|
app.DebugPrintf(" - bytes_succeeded = %d\n", stagingStats.bytes_succeeded);// number of bytes successfully allocated
|
|
app.DebugPrintf(" - max bytes_attempted = %d\n", maxAttempted);
|
|
app.DebugPrintf(" - max bytes_succeeded = %d\n", maxSucceeded);
|
|
app.DebugPrintf(" - largest_bytes_attempted = %d\n", stagingStats.largest_bytes_attempted);// number of bytes in largest attempted alloc
|
|
app.DebugPrintf(" - largest_bytes_succeeded = %d\n", stagingStats.largest_bytes_succeeded);// number of bytes in lagrest successful allo
|
|
app.DebugPrintf("\n\n");
|
|
}
|
|
throttle++;
|
|
|
|
#else
|
|
gdraw_orbis_End(NULL);
|
|
#endif
|
|
|
|
#endif
|
|
}
|
|
|
|
void ConsoleUIController::beginIggyCustomDraw4J(IggyCustomDrawCallbackRegion *region, CustomDrawData *customDrawRegion)
|
|
{
|
|
PIXBeginNamedEvent(0,"Starting Iggy custom draw\n");
|
|
|
|
PIXBeginNamedEvent(0,"Gdraw setup");
|
|
// get the correct object-to-world matrix from GDraw, and set the render state to a normal state
|
|
gdraw_orbis_BeginCustomDraw(region, customDrawRegion->mat);
|
|
PIXEndNamedEvent();
|
|
}
|
|
|
|
CustomDrawData *ConsoleUIController::setupCustomDraw(UIScene *scene, IggyCustomDrawCallbackRegion *region)
|
|
{
|
|
CustomDrawData *customDrawRegion = new CustomDrawData();
|
|
customDrawRegion->x0 = region->x0;
|
|
customDrawRegion->x1 = region->x1;
|
|
customDrawRegion->y0 = region->y0;
|
|
customDrawRegion->y1 = region->y1;
|
|
|
|
// get the correct object-to-world matrix from GDraw, and set the render state to a normal state
|
|
gdraw_orbis_BeginCustomDraw(region, customDrawRegion->mat);
|
|
|
|
setupCustomDrawGameStateAndMatrices(scene, customDrawRegion);
|
|
|
|
return customDrawRegion;
|
|
}
|
|
|
|
CustomDrawData *ConsoleUIController::calculateCustomDraw(IggyCustomDrawCallbackRegion *region)
|
|
{
|
|
CustomDrawData *customDrawRegion = new CustomDrawData();
|
|
customDrawRegion->x0 = region->x0;
|
|
customDrawRegion->x1 = region->x1;
|
|
customDrawRegion->y0 = region->y0;
|
|
customDrawRegion->y1 = region->y1;
|
|
|
|
gdraw_orbis_CalculateCustomDraw_4J(region, customDrawRegion->mat);
|
|
|
|
return customDrawRegion;
|
|
}
|
|
|
|
void ConsoleUIController::endCustomDraw(IggyCustomDrawCallbackRegion *region)
|
|
{
|
|
endCustomDrawGameStateAndMatrices();
|
|
|
|
gdraw_orbis_EndCustomDraw(region);
|
|
}
|
|
|
|
void ConsoleUIController::setTileOrigin(S32 xPos, S32 yPos)
|
|
{
|
|
gdraw_orbis_SetTileOrigin(RenderManager.GetCurrentBackBufferTarget(), RenderManager.GetCurrentBackBufferDepthTarget(), xPos, yPos);
|
|
}
|
|
|
|
GDrawTexture *ConsoleUIController::getSubstitutionTexture(int textureId)
|
|
{
|
|
/* Create a wrapped texture from a shader resource view.
|
|
A wrapped texture can be used to let Iggy draw using the contents of a texture
|
|
you create and manage on your own. For example, you might render to this texture,
|
|
or stream video into it. Wrapped textures take up a handle. They will never be
|
|
freed or otherwise modified by GDraw; nor will GDraw change any reference counts.
|
|
All this is up to the application. */
|
|
|
|
sce::Gnm::Texture *tex = RenderManager.TextureGetTexture(textureId);
|
|
GDrawTexture *gdrawTex = gdraw_orbis_WrappedTextureCreate(tex);
|
|
return gdrawTex;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void ConsoleUIController::destroySubstitutionTexture(void *destroyCallBackData, GDrawTexture *handle)
|
|
{
|
|
/* Destroys the GDraw wrapper for a wrapped texture object. This will free up
|
|
a GDraw texture handle but not release the associated D3D texture; that is
|
|
up to you. */
|
|
gdraw_orbis_WrappedTextureDestroy(handle);
|
|
}
|
|
|
|
void ConsoleUIController::shutdown()
|
|
{
|
|
#ifdef _ENABLEIGGY
|
|
/* Destroy the GDraw context. This frees all resources, shaders etc.
|
|
allocated by GDraw. Note this is only safe to call after all
|
|
active Iggy player have been destroyed! */
|
|
gdraw_orbis_DestroyContext();
|
|
#endif
|
|
}
|
|
|
|
|
|
void ConsoleUIController::handleUnlockFullVersionCallback()
|
|
{
|
|
for(unsigned int i = 0; i < eUIGroup_COUNT; ++i)
|
|
{
|
|
ui.m_groups[i]->handleUnlockFullVersion();
|
|
}
|
|
}
|
|
|