Add render-to-texture support to Wii U renderer
This commit is contained in:
parent
8377f011cf
commit
4d2a227068
1 changed files with 200 additions and 109 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <gx2/context.h>
|
||||||
#include <gx2/draw.h>
|
#include <gx2/draw.h>
|
||||||
#include <gx2/event.h>
|
#include <gx2/event.h>
|
||||||
#include <gx2/registers.h>
|
#include <gx2/registers.h>
|
||||||
|
@ -24,8 +25,8 @@
|
||||||
|
|
||||||
typedef struct RenderBackend_Surface
|
typedef struct RenderBackend_Surface
|
||||||
{
|
{
|
||||||
bool is_screen;
|
|
||||||
GX2Texture texture;
|
GX2Texture texture;
|
||||||
|
GX2ColorBuffer colour_buffer;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
unsigned char *lock_buffer; // TODO - Dumb
|
unsigned char *lock_buffer; // TODO - Dumb
|
||||||
|
@ -44,54 +45,34 @@ static GX2RBuffer texture_coordinate_buffer;
|
||||||
|
|
||||||
static GX2Sampler sampler;
|
static GX2Sampler sampler;
|
||||||
|
|
||||||
RenderBackend_Surface *framebuffer;
|
static RenderBackend_Surface *framebuffer_surface;
|
||||||
static unsigned int framebuffer_width;
|
|
||||||
static unsigned int framebuffer_height;
|
|
||||||
|
|
||||||
static void StartFrameDraw(void)
|
static GX2ContextState *gx2_context;
|
||||||
{
|
|
||||||
WHBGfxBeginRender();
|
|
||||||
|
|
||||||
// Draw to the gamepad
|
|
||||||
WHBGfxBeginRenderDRC();
|
|
||||||
WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void EndFrameDraw(void)
|
|
||||||
{
|
|
||||||
WHBGfxFinishRenderDRC();
|
|
||||||
|
|
||||||
WHBGfxFinishRender();
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, bool fullscreen)
|
RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, bool fullscreen)
|
||||||
{
|
{
|
||||||
(void)window_title;
|
(void)window_title;
|
||||||
(void)fullscreen;
|
(void)fullscreen;
|
||||||
|
|
||||||
framebuffer_width = screen_width;
|
|
||||||
framebuffer_height = screen_height;
|
|
||||||
|
|
||||||
framebuffer = (RenderBackend_Surface*)malloc(sizeof(RenderBackend_Surface));
|
|
||||||
|
|
||||||
if (framebuffer != NULL)
|
|
||||||
{
|
|
||||||
framebuffer->is_screen = true;
|
|
||||||
|
|
||||||
WHBGfxInit();
|
WHBGfxInit();
|
||||||
|
|
||||||
|
// Initialise the shaders
|
||||||
|
|
||||||
|
// Texture shader
|
||||||
if (WHBGfxLoadGFDShaderGroup(&texture_shader, 0, rtexture))
|
if (WHBGfxLoadGFDShaderGroup(&texture_shader, 0, rtexture))
|
||||||
{
|
{
|
||||||
WHBGfxInitShaderAttribute(&texture_shader, "input_vertex_coordinates", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
|
WHBGfxInitShaderAttribute(&texture_shader, "input_vertex_coordinates", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
|
||||||
WHBGfxInitShaderAttribute(&texture_shader, "input_texture_coordinates", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
|
WHBGfxInitShaderAttribute(&texture_shader, "input_texture_coordinates", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
|
||||||
WHBGfxInitFetchShader(&texture_shader);
|
WHBGfxInitFetchShader(&texture_shader);
|
||||||
|
|
||||||
|
// Texture shader (with colour-key)
|
||||||
if (WHBGfxLoadGFDShaderGroup(&texture_colour_key_shader, 0, rtexture_colour_key))
|
if (WHBGfxLoadGFDShaderGroup(&texture_colour_key_shader, 0, rtexture_colour_key))
|
||||||
{
|
{
|
||||||
WHBGfxInitShaderAttribute(&texture_colour_key_shader, "input_vertex_coordinates", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
|
WHBGfxInitShaderAttribute(&texture_colour_key_shader, "input_vertex_coordinates", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
|
||||||
WHBGfxInitShaderAttribute(&texture_colour_key_shader, "input_texture_coordinates", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
|
WHBGfxInitShaderAttribute(&texture_colour_key_shader, "input_texture_coordinates", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
|
||||||
WHBGfxInitFetchShader(&texture_colour_key_shader);
|
WHBGfxInitFetchShader(&texture_colour_key_shader);
|
||||||
|
|
||||||
|
// Colour-fill shader
|
||||||
if (WHBGfxLoadGFDShaderGroup(&colour_fill_shader, 0, rcolour_fill))
|
if (WHBGfxLoadGFDShaderGroup(&colour_fill_shader, 0, rcolour_fill))
|
||||||
{
|
{
|
||||||
WHBGfxInitShaderAttribute(&colour_fill_shader, "input_vertex_coordinates", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
|
WHBGfxInitShaderAttribute(&colour_fill_shader, "input_vertex_coordinates", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
|
||||||
|
@ -118,7 +99,18 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w
|
||||||
// Initialise sampler
|
// Initialise sampler
|
||||||
GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT);
|
GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT);
|
||||||
|
|
||||||
|
// Create framebuffer surface
|
||||||
|
framebuffer_surface = RenderBackend_CreateSurface(screen_width, screen_height);
|
||||||
|
|
||||||
|
if (framebuffer_surface != NULL)
|
||||||
{
|
{
|
||||||
|
// Create a 'context' (this voodoo magic can be used to undo `GX2SetColorBuffer`,
|
||||||
|
// allowing us to draw to the screen once again).
|
||||||
|
gx2_context = (GX2ContextState*)aligned_alloc(GX2_CONTEXT_STATE_ALIGNMENT, sizeof(GX2ContextState));
|
||||||
|
memset(gx2_context, 0, sizeof(GX2ContextState));
|
||||||
|
GX2SetupContextStateEx(gx2_context, TRUE);
|
||||||
|
GX2SetContextState(gx2_context);
|
||||||
|
|
||||||
// Disable depth-test (enabled by default for some reason)
|
// Disable depth-test (enabled by default for some reason)
|
||||||
GX2SetDepthOnlyControl(FALSE, FALSE, GX2_COMPARE_FUNC_ALWAYS);
|
GX2SetDepthOnlyControl(FALSE, FALSE, GX2_COMPARE_FUNC_ALWAYS);
|
||||||
|
|
||||||
|
@ -138,10 +130,14 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w
|
||||||
GX2_BLEND_COMBINE_MODE_ADD);
|
GX2_BLEND_COMBINE_MODE_ADD);
|
||||||
*/
|
*/
|
||||||
// Do some binding
|
// Do some binding
|
||||||
|
/*
|
||||||
|
WHBGfxBeginRender();
|
||||||
|
|
||||||
StartFrameDraw();
|
// Draw to the gamepad
|
||||||
|
WHBGfxBeginRenderDRC();
|
||||||
return framebuffer;
|
WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
*/
|
||||||
|
return framebuffer_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
GX2RDestroyBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
|
GX2RDestroyBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
|
||||||
|
@ -158,14 +154,15 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w
|
||||||
|
|
||||||
WHBGfxShutdown();
|
WHBGfxShutdown();
|
||||||
|
|
||||||
free(framebuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_Deinit(void)
|
void RenderBackend_Deinit(void)
|
||||||
{
|
{
|
||||||
|
free(gx2_context);
|
||||||
|
|
||||||
|
RenderBackend_FreeSurface(framebuffer_surface);
|
||||||
|
|
||||||
GX2RDestroyBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
|
GX2RDestroyBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
|
||||||
GX2RDestroyBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
|
GX2RDestroyBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
|
||||||
|
|
||||||
|
@ -174,15 +171,84 @@ void RenderBackend_Deinit(void)
|
||||||
WHBGfxFreeShaderGroup(&texture_shader);
|
WHBGfxFreeShaderGroup(&texture_shader);
|
||||||
|
|
||||||
WHBGfxShutdown();
|
WHBGfxShutdown();
|
||||||
|
|
||||||
free(framebuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_DrawScreen(void)
|
void RenderBackend_DrawScreen(void)
|
||||||
{
|
{
|
||||||
EndFrameDraw();
|
// Make sure the buffers aren't currently being used before we modify them
|
||||||
|
GX2DrawDone();
|
||||||
|
|
||||||
StartFrameDraw();
|
// Set buffer to full-screen
|
||||||
|
float *position_pointer = (float*)GX2RLockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
|
||||||
|
position_pointer[0] = -1.0f;
|
||||||
|
position_pointer[1] = -1.0f;
|
||||||
|
position_pointer[2] = 1.0f;
|
||||||
|
position_pointer[3] = -1.0f;
|
||||||
|
position_pointer[4] = 1.0f;
|
||||||
|
position_pointer[5] = 1.0f;
|
||||||
|
position_pointer[6] = -1.0f;
|
||||||
|
position_pointer[7] = 1.0f;
|
||||||
|
GX2RUnlockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
|
||||||
|
|
||||||
|
// Set buffer to full-texture
|
||||||
|
float *texture_coordinate_pointer = (float*)GX2RLockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
|
||||||
|
texture_coordinate_pointer[0] = 0.0f;
|
||||||
|
texture_coordinate_pointer[1] = 1.0f;
|
||||||
|
texture_coordinate_pointer[2] = 1.0f;
|
||||||
|
texture_coordinate_pointer[3] = 1.0f;
|
||||||
|
texture_coordinate_pointer[4] = 1.0f;
|
||||||
|
texture_coordinate_pointer[5] = 0.0f;
|
||||||
|
texture_coordinate_pointer[6] = 0.0f;
|
||||||
|
texture_coordinate_pointer[7] = 0.0f;
|
||||||
|
GX2RUnlockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
|
||||||
|
|
||||||
|
|
||||||
|
WHBGfxBeginRender();
|
||||||
|
|
||||||
|
// Draw to the TV
|
||||||
|
WHBGfxBeginRenderTV();
|
||||||
|
WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// This might be needed? Not sure.
|
||||||
|
// GX2RInvalidateSurface(&framebuffer_surface->texture.surface, 0, (GX2RResourceFlags)0);
|
||||||
|
|
||||||
|
GX2SetFetchShader(&texture_shader.fetchShader);
|
||||||
|
GX2SetVertexShader(texture_shader.vertexShader);
|
||||||
|
GX2SetPixelShader(texture_shader.pixelShader);
|
||||||
|
|
||||||
|
GX2SetPixelSampler(&sampler, texture_shader.pixelShader->samplerVars[0].location);
|
||||||
|
GX2SetPixelTexture(&framebuffer_surface->texture, texture_shader.pixelShader->samplerVars[0].location);
|
||||||
|
GX2RSetAttributeBuffer(&vertex_position_buffer, 0, vertex_position_buffer.elemSize, 0);
|
||||||
|
GX2RSetAttributeBuffer(&texture_coordinate_buffer, 1, texture_coordinate_buffer.elemSize, 0);
|
||||||
|
|
||||||
|
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
||||||
|
|
||||||
|
WHBGfxFinishRenderTV();
|
||||||
|
|
||||||
|
// Draw to the gamepad
|
||||||
|
WHBGfxBeginRenderDRC();
|
||||||
|
WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// This might be needed? Not sure.
|
||||||
|
// GX2RInvalidateSurface(&framebuffer_surface->texture.surface, 0, (GX2RResourceFlags)0);
|
||||||
|
|
||||||
|
GX2SetFetchShader(&texture_shader.fetchShader);
|
||||||
|
GX2SetVertexShader(texture_shader.vertexShader);
|
||||||
|
GX2SetPixelShader(texture_shader.pixelShader);
|
||||||
|
|
||||||
|
GX2SetPixelSampler(&sampler, texture_shader.pixelShader->samplerVars[0].location);
|
||||||
|
GX2SetPixelTexture(&framebuffer_surface->texture, texture_shader.pixelShader->samplerVars[0].location);
|
||||||
|
GX2RSetAttributeBuffer(&vertex_position_buffer, 0, vertex_position_buffer.elemSize, 0);
|
||||||
|
GX2RSetAttributeBuffer(&texture_coordinate_buffer, 1, texture_coordinate_buffer.elemSize, 0);
|
||||||
|
|
||||||
|
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
||||||
|
|
||||||
|
WHBGfxFinishRenderDRC();
|
||||||
|
|
||||||
|
WHBGfxFinishRender();
|
||||||
|
|
||||||
|
// Do this or else the screen will never update. I wish I understood why.
|
||||||
|
GX2SetContextState(gx2_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned int height)
|
RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned int height)
|
||||||
|
@ -191,7 +257,6 @@ RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned
|
||||||
|
|
||||||
if (surface != NULL)
|
if (surface != NULL)
|
||||||
{
|
{
|
||||||
surface->is_screen = false;
|
|
||||||
surface->width = width;
|
surface->width = width;
|
||||||
surface->height = height;
|
surface->height = height;
|
||||||
|
|
||||||
|
@ -210,11 +275,21 @@ RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned
|
||||||
GX2CalcSurfaceSizeAndAlignment(&surface->texture.surface);
|
GX2CalcSurfaceSizeAndAlignment(&surface->texture.surface);
|
||||||
GX2InitTextureRegs(&surface->texture);
|
GX2InitTextureRegs(&surface->texture);
|
||||||
|
|
||||||
|
// Initialise colour buffer (needed so the texture can be drawn to)
|
||||||
|
memset(&surface->colour_buffer, 0, sizeof(surface->colour_buffer));
|
||||||
|
surface->colour_buffer.surface = surface->texture.surface;
|
||||||
|
surface->colour_buffer.viewNumSlices = 1;
|
||||||
|
GX2InitColorBufferRegs(&surface->colour_buffer);
|
||||||
|
|
||||||
if (GX2RCreateSurface(&surface->texture.surface, (GX2RResourceFlags)(GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_BIND_COLOR_BUFFER |
|
if (GX2RCreateSurface(&surface->texture.surface, (GX2RResourceFlags)(GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_BIND_COLOR_BUFFER |
|
||||||
GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_CPU_READ |
|
GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_CPU_READ |
|
||||||
GX2R_RESOURCE_USAGE_GPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ)))
|
GX2R_RESOURCE_USAGE_GPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ)))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (GX2RCreateSurfaceUserMemory(&surface->colour_buffer.surface, (uint8_t*)surface->texture.surface.image, (uint8_t*)surface->texture.surface.mipmaps, surface->texture.surface.resourceFlags))
|
||||||
return surface;
|
return surface;
|
||||||
|
|
||||||
|
GX2RDestroySurfaceEx(&surface->texture.surface, (GX2RResourceFlags)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(surface);
|
free(surface);
|
||||||
|
@ -227,6 +302,7 @@ void RenderBackend_FreeSurface(RenderBackend_Surface *surface)
|
||||||
{
|
{
|
||||||
if (surface != NULL)
|
if (surface != NULL)
|
||||||
{
|
{
|
||||||
|
GX2RDestroySurfaceEx(&surface->colour_buffer.surface, (GX2RResourceFlags)0);
|
||||||
GX2RDestroySurfaceEx(&surface->texture.surface, (GX2RResourceFlags)0);
|
GX2RDestroySurfaceEx(&surface->texture.surface, (GX2RResourceFlags)0);
|
||||||
free(surface);
|
free(surface);
|
||||||
}
|
}
|
||||||
|
@ -293,11 +369,10 @@ void RenderBackend_Blit(RenderBackend_Surface *source_surface, const RenderBacke
|
||||||
if (source_surface == NULL || destination_surface == NULL)
|
if (source_surface == NULL || destination_surface == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (source_surface->is_screen || !destination_surface->is_screen)
|
// Make sure the buffers aren't currently being used before we modify them
|
||||||
return;
|
|
||||||
|
|
||||||
GX2DrawDone();
|
GX2DrawDone();
|
||||||
|
|
||||||
|
// Set vertex position buffer
|
||||||
const float destination_left = x;
|
const float destination_left = x;
|
||||||
const float destination_top = y;
|
const float destination_top = y;
|
||||||
const float destination_right = x + (rect->right - rect->left);
|
const float destination_right = x + (rect->right - rect->left);
|
||||||
|
@ -312,18 +387,21 @@ void RenderBackend_Blit(RenderBackend_Surface *source_surface, const RenderBacke
|
||||||
position_pointer[5] = destination_bottom;
|
position_pointer[5] = destination_bottom;
|
||||||
position_pointer[6] = destination_left;
|
position_pointer[6] = destination_left;
|
||||||
position_pointer[7] = destination_bottom;
|
position_pointer[7] = destination_bottom;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 8; i += 2)
|
for (unsigned int i = 0; i < 8; i += 2)
|
||||||
{
|
{
|
||||||
position_pointer[i + 0] /= framebuffer_width;
|
position_pointer[i + 0] /= destination_surface->width;
|
||||||
position_pointer[i + 0] *= 2.0f;
|
position_pointer[i + 0] *= 2.0f;
|
||||||
position_pointer[i + 0] -= 1.0f;
|
position_pointer[i + 0] -= 1.0f;
|
||||||
|
|
||||||
position_pointer[i + 1] /= framebuffer_height;
|
position_pointer[i + 1] /= destination_surface->height;
|
||||||
position_pointer[i + 1] *= -2.0f;
|
position_pointer[i + 1] *= -2.0f;
|
||||||
position_pointer[i + 1] += 1.0f;
|
position_pointer[i + 1] += 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
GX2RUnlockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
|
GX2RUnlockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
|
||||||
|
|
||||||
|
// Set texture coordinate buffer
|
||||||
float *texture_coordinate_pointer = (float*)GX2RLockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
|
float *texture_coordinate_pointer = (float*)GX2RLockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
|
||||||
texture_coordinate_pointer[0] = rect->left / (float)source_surface->width;
|
texture_coordinate_pointer[0] = rect->left / (float)source_surface->width;
|
||||||
texture_coordinate_pointer[1] = rect->top / (float)source_surface->height;
|
texture_coordinate_pointer[1] = rect->top / (float)source_surface->height;
|
||||||
|
@ -335,15 +413,26 @@ void RenderBackend_Blit(RenderBackend_Surface *source_surface, const RenderBacke
|
||||||
texture_coordinate_pointer[7] = rect->bottom / (float)source_surface->height;
|
texture_coordinate_pointer[7] = rect->bottom / (float)source_surface->height;
|
||||||
GX2RUnlockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
|
GX2RUnlockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
|
||||||
|
|
||||||
GX2SetFetchShader(&texture_colour_key_shader.fetchShader);
|
// Draw to the selected texture, instead of the screen
|
||||||
GX2SetVertexShader(texture_colour_key_shader.vertexShader);
|
GX2SetColorBuffer(&destination_surface->colour_buffer, GX2_RENDER_TARGET_0);
|
||||||
GX2SetPixelShader(texture_colour_key_shader.pixelShader);
|
GX2SetViewport(0.0f, 0.0f, (float)destination_surface->colour_buffer.surface.width, (float)destination_surface->colour_buffer.surface.height, 0.0f, 1.0f);
|
||||||
|
GX2SetScissor(0, 0, destination_surface->colour_buffer.surface.width, destination_surface->colour_buffer.surface.height);
|
||||||
|
|
||||||
GX2SetPixelSampler(&sampler, texture_colour_key_shader.pixelShader->samplerVars[0].location);
|
// Select shader
|
||||||
GX2SetPixelTexture(&source_surface->texture, texture_colour_key_shader.pixelShader->samplerVars[0].location);
|
WHBGfxShaderGroup *shader = colour_key ? &texture_colour_key_shader : &texture_shader;
|
||||||
|
|
||||||
|
// Bind it
|
||||||
|
GX2SetFetchShader(&shader->fetchShader);
|
||||||
|
GX2SetVertexShader(shader->vertexShader);
|
||||||
|
GX2SetPixelShader(shader->pixelShader);
|
||||||
|
|
||||||
|
// Bind misc. data
|
||||||
|
GX2SetPixelSampler(&sampler, shader->pixelShader->samplerVars[0].location);
|
||||||
|
GX2SetPixelTexture(&source_surface->texture, shader->pixelShader->samplerVars[0].location);
|
||||||
GX2RSetAttributeBuffer(&vertex_position_buffer, 0, vertex_position_buffer.elemSize, 0);
|
GX2RSetAttributeBuffer(&vertex_position_buffer, 0, vertex_position_buffer.elemSize, 0);
|
||||||
GX2RSetAttributeBuffer(&texture_coordinate_buffer, 1, texture_coordinate_buffer.elemSize, 0);
|
GX2RSetAttributeBuffer(&texture_coordinate_buffer, 1, texture_coordinate_buffer.elemSize, 0);
|
||||||
|
|
||||||
|
// Draw
|
||||||
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,9 +441,7 @@ void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBacken
|
||||||
if (surface == NULL)
|
if (surface == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!surface->is_screen)
|
// Make sure the buffers aren't currently being used before we modify them
|
||||||
return;
|
|
||||||
|
|
||||||
GX2DrawDone();
|
GX2DrawDone();
|
||||||
|
|
||||||
float *position_pointer = (float*)GX2RLockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
|
float *position_pointer = (float*)GX2RLockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
|
||||||
|
@ -368,16 +455,20 @@ void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBacken
|
||||||
position_pointer[7] = rect->bottom;
|
position_pointer[7] = rect->bottom;
|
||||||
for (unsigned int i = 0; i < 8; i += 2)
|
for (unsigned int i = 0; i < 8; i += 2)
|
||||||
{
|
{
|
||||||
position_pointer[i + 0] /= framebuffer_width;
|
position_pointer[i + 0] /= surface->width;
|
||||||
position_pointer[i + 0] *= 2.0f;
|
position_pointer[i + 0] *= 2.0f;
|
||||||
position_pointer[i + 0] -= 1.0f;
|
position_pointer[i + 0] -= 1.0f;
|
||||||
|
|
||||||
position_pointer[i + 1] /= framebuffer_height;
|
position_pointer[i + 1] /= surface->height;
|
||||||
position_pointer[i + 1] *= -2.0f;
|
position_pointer[i + 1] *= -2.0f;
|
||||||
position_pointer[i + 1] += 1.0f;
|
position_pointer[i + 1] += 1.0f;
|
||||||
}
|
}
|
||||||
GX2RUnlockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
|
GX2RUnlockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
|
||||||
|
|
||||||
|
GX2SetColorBuffer(&surface->colour_buffer, GX2_RENDER_TARGET_0);
|
||||||
|
GX2SetViewport(0, 0, (float)surface->colour_buffer.surface.width, (float)surface->colour_buffer.surface.height, 0.0f, 1.0f);
|
||||||
|
GX2SetScissor(0, 0, (float)surface->colour_buffer.surface.width, (float)surface->colour_buffer.surface.height);
|
||||||
|
|
||||||
float uniform_colours[4] = {red / 255.0f, green / 255.0f, blue / 255.0f, 1.0f};
|
float uniform_colours[4] = {red / 255.0f, green / 255.0f, blue / 255.0f, 1.0f};
|
||||||
|
|
||||||
GX2SetPixelUniformReg(colour_fill_shader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&uniform_colours);
|
GX2SetPixelUniformReg(colour_fill_shader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&uniform_colours);
|
||||||
|
|
Loading…
Add table
Reference in a new issue