[VITA] Update Vita2D

This commit is contained in:
Francisco José García García 2019-07-18 21:12:19 +02:00
parent 6da7a0c19a
commit 98ecdd9510
3 changed files with 494 additions and 155 deletions

View File

@ -35,6 +35,10 @@ typedef struct vita2d_texture {
SceGxmTexture gxm_tex; SceGxmTexture gxm_tex;
SceUID data_UID; SceUID data_UID;
SceUID palette_UID; SceUID palette_UID;
SceGxmRenderTarget *gxm_rtgt;
SceGxmColorSurface gxm_sfc;
SceGxmDepthStencilSurface gxm_sfd;
SceUID depth_UID;
} vita2d_texture; } vita2d_texture;
typedef struct vita2d_font vita2d_font; typedef struct vita2d_font vita2d_font;
@ -42,6 +46,7 @@ typedef struct vita2d_pgf vita2d_pgf;
int vita2d_init(); int vita2d_init();
int vita2d_init_advanced(unsigned int temp_pool_size); int vita2d_init_advanced(unsigned int temp_pool_size);
int vita2d_init_advanced_with_msaa(unsigned int temp_pool_size, SceGxmMultisampleMode msaa);
void vita2d_wait_rendering_done(); void vita2d_wait_rendering_done();
int vita2d_fini(); int vita2d_fini();
@ -49,6 +54,7 @@ void vita2d_clear_screen();
void vita2d_swap_buffers(); void vita2d_swap_buffers();
void vita2d_start_drawing(); void vita2d_start_drawing();
void vita2d_start_drawing_advanced(vita2d_texture *target, unsigned int flags);
void vita2d_end_drawing(); void vita2d_end_drawing();
int vita2d_common_dialog_update(); int vita2d_common_dialog_update();
@ -56,10 +62,21 @@ int vita2d_common_dialog_update();
void vita2d_set_clear_color(unsigned int color); void vita2d_set_clear_color(unsigned int color);
unsigned int vita2d_get_clear_color(); unsigned int vita2d_get_clear_color();
void vita2d_set_clear_color(unsigned int color);
unsigned int vita2d_get_clear_color();
void vita2d_set_vblank_wait(int enable); void vita2d_set_vblank_wait(int enable);
void *vita2d_get_current_fb(); void *vita2d_get_current_fb();
SceGxmContext *vita2d_get_context();
SceGxmShaderPatcher *vita2d_get_shader_patcher();
const uint16_t *vita2d_get_linear_indices();
void vita2d_set_region_clip(SceGxmRegionClipMode mode, unsigned int x_min, unsigned int y_min, unsigned int x_max, unsigned int y_max); void vita2d_set_region_clip(SceGxmRegionClipMode mode, unsigned int x_min, unsigned int y_min, unsigned int x_max, unsigned int y_max);
void vita2d_enable_clipping();
void vita2d_disable_clipping();
int vita2d_get_clipping_enabled();
void vita2d_set_clip_rectangle(int x_min, int y_min, int x_max, int y_max);
void vita2d_get_clip_rectangle(int *x_min, int *y_min, int *x_max, int *y_max);
void vita2d_set_blend_mode_add(int enable);
void *vita2d_pool_malloc(unsigned int size); void *vita2d_pool_malloc(unsigned int size);
void *vita2d_pool_memalign(unsigned int size, unsigned int alignment); void *vita2d_pool_memalign(unsigned int size, unsigned int alignment);
@ -70,9 +87,14 @@ void vita2d_draw_pixel(float x, float y, unsigned int color);
void vita2d_draw_line(float x0, float y0, float x1, float y1, unsigned int color); void vita2d_draw_line(float x0, float y0, float x1, float y1, unsigned int color);
void vita2d_draw_rectangle(float x, float y, float w, float h, unsigned int color); void vita2d_draw_rectangle(float x, float y, float w, float h, unsigned int color);
void vita2d_draw_fill_circle(float x, float y, float radius, unsigned int color); void vita2d_draw_fill_circle(float x, float y, float radius, unsigned int color);
void vita2d_draw_array(SceGxmPrimitiveType mode, const vita2d_color_vertex *vertices, size_t count);
void vita2d_texture_set_alloc_memblock_type(SceKernelMemBlockType type);
SceKernelMemBlockType vita2d_texture_get_alloc_memblock_type();
vita2d_texture *vita2d_create_empty_texture(unsigned int w, unsigned int h); vita2d_texture *vita2d_create_empty_texture(unsigned int w, unsigned int h);
vita2d_texture *vita2d_create_empty_texture_format(unsigned int w, unsigned int h, SceGxmTextureFormat format); vita2d_texture *vita2d_create_empty_texture_format(unsigned int w, unsigned int h, SceGxmTextureFormat format);
vita2d_texture *vita2d_create_empty_texture_rendertarget(unsigned int w, unsigned int h, SceGxmTextureFormat format);
void vita2d_free_texture(vita2d_texture *texture); void vita2d_free_texture(vita2d_texture *texture);
unsigned int vita2d_texture_get_width(const vita2d_texture *texture); unsigned int vita2d_texture_get_width(const vita2d_texture *texture);
@ -93,6 +115,7 @@ void vita2d_draw_texture_part(const vita2d_texture *texture, float x, float y, f
void vita2d_draw_texture_part_scale(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale); void vita2d_draw_texture_part_scale(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale);
void vita2d_draw_texture_scale_rotate_hotspot(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, float center_x, float center_y); void vita2d_draw_texture_scale_rotate_hotspot(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, float center_x, float center_y);
void vita2d_draw_texture_scale_rotate(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad); void vita2d_draw_texture_scale_rotate(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad);
void vita2d_draw_texture_part_scale_rotate(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, float rad);
void vita2d_draw_texture_tint(const vita2d_texture *texture, float x, float y, unsigned int color); void vita2d_draw_texture_tint(const vita2d_texture *texture, float x, float y, unsigned int color);
void vita2d_draw_texture_tint_rotate(const vita2d_texture *texture, float x, float y, float rad, unsigned int color); void vita2d_draw_texture_tint_rotate(const vita2d_texture *texture, float x, float y, float rad, unsigned int color);
@ -102,6 +125,8 @@ void vita2d_draw_texture_tint_part(const vita2d_texture *texture, float x, float
void vita2d_draw_texture_tint_part_scale(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, unsigned int color); void vita2d_draw_texture_tint_part_scale(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, unsigned int color);
void vita2d_draw_texture_tint_scale_rotate_hotspot(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, float center_x, float center_y, unsigned int color); void vita2d_draw_texture_tint_scale_rotate_hotspot(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, float center_x, float center_y, unsigned int color);
void vita2d_draw_texture_tint_scale_rotate(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, unsigned int color); void vita2d_draw_texture_tint_scale_rotate(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, unsigned int color);
void vita2d_draw_texture_part_tint_scale_rotate(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, float rad, unsigned int color);
void vita2d_draw_array_textured(const vita2d_texture *texture, SceGxmPrimitiveType mode, const vita2d_texture_vertex *vertices, size_t count, unsigned int color);
/** ADVANCED **/ /** ADVANCED **/
void vita2d_texture_set_wvp(float x, float y, float width, float height); void vita2d_texture_set_wvp(float x, float y, float width, float height);

View File

@ -25,7 +25,6 @@
#define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8 #define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8
#define DISPLAY_BUFFER_COUNT 3 #define DISPLAY_BUFFER_COUNT 3
#define DISPLAY_MAX_PENDING_SWAPS 2 #define DISPLAY_MAX_PENDING_SWAPS 2
#define MSAA_MODE SCE_GXM_MULTISAMPLE_NONE
#define DEFAULT_TEMP_POOL_SIZE (1 * 1024 * 1024) #define DEFAULT_TEMP_POOL_SIZE (1 * 1024 * 1024)
typedef struct vita2d_display_data { typedef struct vita2d_display_data {
@ -56,8 +55,14 @@ static const SceGxmProgram *const textureTintFragmentProgramGxp = &texture_tint_
static int vita2d_initialized = 0; static int vita2d_initialized = 0;
static float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; static float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
static unsigned int clear_color_u = 0xff000000; static unsigned int clear_color_u = 0xFF000000;
static int clip_rect_x_min = 0;
static int clip_rect_y_min = 0;
static int clip_rect_x_max = DISPLAY_WIDTH;
static int clip_rect_y_max = DISPLAY_HEIGHT;
static int vblank_wait = 1; static int vblank_wait = 1;
static int drawing = 0;
static int clipping_enabled = 0;
static SceUID vdmRingBufferUid; static SceUID vdmRingBufferUid;
static SceUID vertexRingBufferUid; static SceUID vertexRingBufferUid;
@ -72,8 +77,10 @@ static SceUID displayBufferUid[DISPLAY_BUFFER_COUNT];
static SceGxmColorSurface displaySurface[DISPLAY_BUFFER_COUNT]; static SceGxmColorSurface displaySurface[DISPLAY_BUFFER_COUNT];
static SceGxmSyncObject *displayBufferSync[DISPLAY_BUFFER_COUNT]; static SceGxmSyncObject *displayBufferSync[DISPLAY_BUFFER_COUNT];
static SceUID depthBufferUid; static SceUID depthBufferUid;
static SceUID stencilBufferUid;
static SceGxmDepthStencilSurface depthSurface; static SceGxmDepthStencilSurface depthSurface;
static void *depthBufferData = NULL; static void *depthBufferData = NULL;
static void *stencilBufferData = NULL;
static unsigned int backBufferIndex = 0; static unsigned int backBufferIndex = 0;
static unsigned int frontBufferIndex = 0; static unsigned int frontBufferIndex = 0;
@ -95,9 +102,9 @@ static SceUID patcherVertexUsseUid;
static SceUID patcherFragmentUsseUid; static SceUID patcherFragmentUsseUid;
static SceUID clearVerticesUid; static SceUID clearVerticesUid;
static SceUID clearIndicesUid; static SceUID linearIndicesUid;
static vita2d_clear_vertex *clearVertices = NULL; static vita2d_clear_vertex *clearVertices = NULL;
static uint16_t *clearIndices = NULL; static uint16_t *linearIndices = NULL;
/* Shared with other .c */ /* Shared with other .c */
float _vita2d_ortho_matrix[4*4]; float _vita2d_ortho_matrix[4*4];
@ -112,6 +119,17 @@ const SceGxmProgramParameter *_vita2d_colorWvpParam = NULL;
const SceGxmProgramParameter *_vita2d_textureWvpParam = NULL; const SceGxmProgramParameter *_vita2d_textureWvpParam = NULL;
const SceGxmProgramParameter *_vita2d_textureTintColorParam = NULL; const SceGxmProgramParameter *_vita2d_textureTintColorParam = NULL;
typedef struct vita2d_fragment_programs {
SceGxmFragmentProgram *color;
SceGxmFragmentProgram *texture;
SceGxmFragmentProgram *textureTint;
} vita2d_fragment_programs;
struct {
vita2d_fragment_programs blend_mode_normal;
vita2d_fragment_programs blend_mode_add;
} _vita2d_fragmentPrograms;
// Temporary memory pool // Temporary memory pool
static void *pool_addr = NULL; static void *pool_addr = NULL;
static SceUID poolUid; static SceUID poolUid;
@ -149,12 +167,54 @@ static void display_callback(const void *callback_data)
} }
} }
int vita2d_init() static void _vita2d_free_fragment_programs(vita2d_fragment_programs *out)
{ {
return vita2d_init_advanced(DEFAULT_TEMP_POOL_SIZE); sceGxmShaderPatcherReleaseFragmentProgram(shaderPatcher, out->color);
sceGxmShaderPatcherReleaseFragmentProgram(shaderPatcher, out->texture);
sceGxmShaderPatcherReleaseFragmentProgram(shaderPatcher, out->textureTint);
} }
int vita2d_init_advanced(unsigned int temp_pool_size) static void _vita2d_make_fragment_programs(vita2d_fragment_programs *out,
const SceGxmBlendInfo *blend_info, SceGxmMultisampleMode msaa)
{
int err;
(void)err;
err = sceGxmShaderPatcherCreateFragmentProgram(
shaderPatcher,
colorFragmentProgramId,
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
msaa,
blend_info,
colorVertexProgramGxp,
&out->color);
VITA2D_DEBUG("color sceGxmShaderPatcherCreateFragmentProgram(): 0x%08X\n", err);
err = sceGxmShaderPatcherCreateFragmentProgram(
shaderPatcher,
textureFragmentProgramId,
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
msaa,
blend_info,
textureVertexProgramGxp,
&out->texture);
VITA2D_DEBUG("texture sceGxmShaderPatcherCreateFragmentProgram(): 0x%08X\n", err);
err = sceGxmShaderPatcherCreateFragmentProgram(
shaderPatcher,
textureTintFragmentProgramId,
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
msaa,
blend_info,
textureVertexProgramGxp,
&out->textureTint);
VITA2D_DEBUG("texture_tint sceGxmShaderPatcherCreateFragmentProgram(): 0x%08X\n", err);
}
static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMode msaa)
{ {
int err; int err;
unsigned int i, x, y; unsigned int i, x, y;
@ -227,7 +287,7 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
renderTargetParams.width = DISPLAY_WIDTH; renderTargetParams.width = DISPLAY_WIDTH;
renderTargetParams.height = DISPLAY_HEIGHT; renderTargetParams.height = DISPLAY_HEIGHT;
renderTargetParams.scenesPerFrame = 1; renderTargetParams.scenesPerFrame = 1;
renderTargetParams.multisampleMode = MSAA_MODE; renderTargetParams.multisampleMode = msaa;
renderTargetParams.multisampleLocations = 0; renderTargetParams.multisampleLocations = 0;
renderTargetParams.driverMemBlock = -1; // Invalid UID renderTargetParams.driverMemBlock = -1; // Invalid UID
@ -258,7 +318,7 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
&displaySurface[i], &displaySurface[i],
DISPLAY_COLOR_FORMAT, DISPLAY_COLOR_FORMAT,
SCE_GXM_COLOR_SURFACE_LINEAR, SCE_GXM_COLOR_SURFACE_LINEAR,
(MSAA_MODE == SCE_GXM_MULTISAMPLE_NONE) ? SCE_GXM_COLOR_SURFACE_SCALE_NONE : SCE_GXM_COLOR_SURFACE_SCALE_MSAA_DOWNSCALE, (msaa == SCE_GXM_MULTISAMPLE_NONE) ? SCE_GXM_COLOR_SURFACE_SCALE_NONE : SCE_GXM_COLOR_SURFACE_SCALE_MSAA_DOWNSCALE,
SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT, SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
DISPLAY_WIDTH, DISPLAY_WIDTH,
DISPLAY_HEIGHT, DISPLAY_HEIGHT,
@ -274,11 +334,11 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
const unsigned int alignedHeight = ALIGN(DISPLAY_HEIGHT, SCE_GXM_TILE_SIZEY); const unsigned int alignedHeight = ALIGN(DISPLAY_HEIGHT, SCE_GXM_TILE_SIZEY);
unsigned int sampleCount = alignedWidth*alignedHeight; unsigned int sampleCount = alignedWidth*alignedHeight;
unsigned int depthStrideInSamples = alignedWidth; unsigned int depthStrideInSamples = alignedWidth;
if (MSAA_MODE == SCE_GXM_MULTISAMPLE_4X) { if (msaa == SCE_GXM_MULTISAMPLE_4X) {
// samples increase in X and Y // samples increase in X and Y
sampleCount *= 4; sampleCount *= 4;
depthStrideInSamples *= 2; depthStrideInSamples *= 2;
} else if (MSAA_MODE == SCE_GXM_MULTISAMPLE_2X) { } else if (msaa == SCE_GXM_MULTISAMPLE_2X) {
// samples increase in Y only // samples increase in Y only
sampleCount *= 2; sampleCount *= 2;
} }
@ -291,6 +351,14 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
&depthBufferUid); &depthBufferUid);
// allocate the stencil buffer
stencilBufferData = gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
4*sampleCount,
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
&stencilBufferUid);
// create the SceGxmDepthStencilSurface structure // create the SceGxmDepthStencilSurface structure
err = sceGxmDepthStencilSurfaceInit( err = sceGxmDepthStencilSurfaceInit(
&depthSurface, &depthSurface,
@ -298,7 +366,19 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
SCE_GXM_DEPTH_STENCIL_SURFACE_TILED, SCE_GXM_DEPTH_STENCIL_SURFACE_TILED,
depthStrideInSamples, depthStrideInSamples,
depthBufferData, depthBufferData,
NULL); stencilBufferData);
// set the stencil test reference (this is currently assumed to always remain 1 after here for region clipping)
sceGxmSetFrontStencilRef(_vita2d_context, 1);
// set the stencil function (this wouldn't actually be needed, as the set clip rectangle function has to call this at the begginning of every scene)
sceGxmSetFrontStencilFunc(
_vita2d_context,
SCE_GXM_STENCIL_FUNC_ALWAYS,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
0xFF,
0xFF);
// set buffer sizes for this sample // set buffer sizes for this sample
const unsigned int patcherBufferSize = 64*1024; const unsigned int patcherBufferSize = 64*1024;
@ -393,8 +473,18 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
.alphaFunc = SCE_GXM_BLEND_FUNC_ADD, .alphaFunc = SCE_GXM_BLEND_FUNC_ADD,
.colorSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA, .colorSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA,
.colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, .colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.alphaSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA,
.alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.colorMask = SCE_GXM_COLOR_MASK_ALL
};
static const SceGxmBlendInfo blend_info_add = {
.colorFunc = SCE_GXM_BLEND_FUNC_ADD,
.alphaFunc = SCE_GXM_BLEND_FUNC_ADD,
.colorSrc = SCE_GXM_BLEND_FACTOR_ONE,
.colorDst = SCE_GXM_BLEND_FACTOR_ONE,
.alphaSrc = SCE_GXM_BLEND_FACTOR_ONE, .alphaSrc = SCE_GXM_BLEND_FACTOR_ONE,
.alphaDst = SCE_GXM_BLEND_FACTOR_ZERO, .alphaDst = SCE_GXM_BLEND_FACTOR_ONE,
.colorMask = SCE_GXM_COLOR_MASK_ALL .colorMask = SCE_GXM_COLOR_MASK_ALL
}; };
@ -428,7 +518,7 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
shaderPatcher, shaderPatcher,
clearFragmentProgramId, clearFragmentProgramId,
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
MSAA_MODE, msaa,
NULL, NULL,
clearVertexProgramGxp, clearVertexProgramGxp,
&clearFragmentProgram); &clearFragmentProgram);
@ -443,12 +533,20 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
SCE_GXM_MEMORY_ATTRIB_READ, SCE_GXM_MEMORY_ATTRIB_READ,
&clearVerticesUid); &clearVerticesUid);
clearIndices = (uint16_t *)gpu_alloc( // Allocate a 64k * 2 bytes = 128 KiB buffer and store all possible
// 16-bit indices in linear ascending order, so we can use this for
// all drawing operations where we don't want to use indexing.
linearIndices = (uint16_t *)gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
3*sizeof(uint16_t), UINT16_MAX*sizeof(uint16_t),
2, sizeof(uint16_t),
SCE_GXM_MEMORY_ATTRIB_READ, SCE_GXM_MEMORY_ATTRIB_READ,
&clearIndicesUid); &linearIndicesUid);
// Range of i must be greater than uint16_t, this doesn't endless-loop
for (uint32_t i=0; i<=UINT16_MAX; ++i) {
linearIndices[i] = i;
}
clearVertices[0].x = -1.0f; clearVertices[0].x = -1.0f;
clearVertices[0].y = -1.0f; clearVertices[0].y = -1.0f;
@ -457,10 +555,6 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
clearVertices[2].x = -1.0f; clearVertices[2].x = -1.0f;
clearVertices[2].y = 3.0f; clearVertices[2].y = 3.0f;
clearIndices[0] = 0;
clearIndices[1] = 1;
clearIndices[2] = 2;
const SceGxmProgramParameter *paramColorPositionAttribute = sceGxmProgramFindParameterByName(colorVertexProgramGxp, "aPosition"); const SceGxmProgramParameter *paramColorPositionAttribute = sceGxmProgramFindParameterByName(colorVertexProgramGxp, "aPosition");
VITA2D_DEBUG("aPosition sceGxmProgramFindParameterByName(): %p\n", paramColorPositionAttribute); VITA2D_DEBUG("aPosition sceGxmProgramFindParameterByName(): %p\n", paramColorPositionAttribute);
@ -498,17 +592,6 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
VITA2D_DEBUG("color sceGxmShaderPatcherCreateVertexProgram(): 0x%08X\n", err); VITA2D_DEBUG("color sceGxmShaderPatcherCreateVertexProgram(): 0x%08X\n", err);
err = sceGxmShaderPatcherCreateFragmentProgram(
shaderPatcher,
colorFragmentProgramId,
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
MSAA_MODE,
&blend_info,
colorVertexProgramGxp,
&_vita2d_colorFragmentProgram);
VITA2D_DEBUG("color sceGxmShaderPatcherCreateFragmentProgram(): 0x%08X\n", err);
const SceGxmProgramParameter *paramTexturePositionAttribute = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "aPosition"); const SceGxmProgramParameter *paramTexturePositionAttribute = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "aPosition");
VITA2D_DEBUG("aPosition sceGxmProgramFindParameterByName(): %p\n", paramTexturePositionAttribute); VITA2D_DEBUG("aPosition sceGxmProgramFindParameterByName(): %p\n", paramTexturePositionAttribute);
@ -547,27 +630,12 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
VITA2D_DEBUG("texture sceGxmShaderPatcherCreateVertexProgram(): 0x%08X\n", err); VITA2D_DEBUG("texture sceGxmShaderPatcherCreateVertexProgram(): 0x%08X\n", err);
err = sceGxmShaderPatcherCreateFragmentProgram( // Create variations of the fragment program based on blending mode
shaderPatcher, _vita2d_make_fragment_programs(&_vita2d_fragmentPrograms.blend_mode_normal, &blend_info, msaa);
textureFragmentProgramId, _vita2d_make_fragment_programs(&_vita2d_fragmentPrograms.blend_mode_add, &blend_info_add, msaa);
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
MSAA_MODE,
&blend_info,
textureVertexProgramGxp,
&_vita2d_textureFragmentProgram);
VITA2D_DEBUG("texture sceGxmShaderPatcherCreateFragmentProgram(): 0x%08X\n", err); // Default to "normal" blending mode (non-additive)
vita2d_set_blend_mode_add(0);
err = sceGxmShaderPatcherCreateFragmentProgram(
shaderPatcher,
textureTintFragmentProgramId,
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
MSAA_MODE,
&blend_info,
textureVertexProgramGxp,
&_vita2d_textureTintFragmentProgram);
VITA2D_DEBUG("texture_tint sceGxmShaderPatcherCreateFragmentProgram(): 0x%08X\n", err);
// find vertex uniforms by name and cache parameter information // find vertex uniforms by name and cache parameter information
_vita2d_clearClearColorParam = sceGxmProgramFindParameterByName(clearFragmentProgramGxp, "uClearColor"); _vita2d_clearClearColorParam = sceGxmProgramFindParameterByName(clearFragmentProgramGxp, "uClearColor");
@ -590,6 +658,7 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
sizeof(void *), sizeof(void *),
SCE_GXM_MEMORY_ATTRIB_READ, SCE_GXM_MEMORY_ATTRIB_READ,
&poolUid); &poolUid);
matrix_init_orthographic(_vita2d_ortho_matrix, 0.0f, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0.0f, 0.0f, 1.0f); matrix_init_orthographic(_vita2d_ortho_matrix, 0.0f, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0.0f, 0.0f, 1.0f);
@ -605,6 +674,21 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
return 1; return 1;
} }
int vita2d_init()
{
return vita2d_init_internal(DEFAULT_TEMP_POOL_SIZE, SCE_GXM_MULTISAMPLE_NONE);
}
int vita2d_init_advanced(unsigned int temp_pool_size)
{
return vita2d_init_internal(temp_pool_size, SCE_GXM_MULTISAMPLE_NONE);
}
int vita2d_init_advanced_with_msaa(unsigned int temp_pool_size, SceGxmMultisampleMode msaa)
{
return vita2d_init_internal(temp_pool_size, msaa);
}
void vita2d_wait_rendering_done() void vita2d_wait_rendering_done()
{ {
sceGxmFinish(_vita2d_context); sceGxmFinish(_vita2d_context);
@ -625,12 +709,13 @@ int vita2d_fini()
// clean up allocations // clean up allocations
sceGxmShaderPatcherReleaseFragmentProgram(shaderPatcher, clearFragmentProgram); sceGxmShaderPatcherReleaseFragmentProgram(shaderPatcher, clearFragmentProgram);
sceGxmShaderPatcherReleaseVertexProgram(shaderPatcher, clearVertexProgram); sceGxmShaderPatcherReleaseVertexProgram(shaderPatcher, clearVertexProgram);
sceGxmShaderPatcherReleaseFragmentProgram(shaderPatcher, _vita2d_colorFragmentProgram);
sceGxmShaderPatcherReleaseVertexProgram(shaderPatcher, _vita2d_colorVertexProgram); sceGxmShaderPatcherReleaseVertexProgram(shaderPatcher, _vita2d_colorVertexProgram);
sceGxmShaderPatcherReleaseFragmentProgram(shaderPatcher, _vita2d_textureFragmentProgram);
sceGxmShaderPatcherReleaseFragmentProgram(shaderPatcher, _vita2d_textureTintFragmentProgram);
sceGxmShaderPatcherReleaseVertexProgram(shaderPatcher, _vita2d_textureVertexProgram); sceGxmShaderPatcherReleaseVertexProgram(shaderPatcher, _vita2d_textureVertexProgram);
gpu_free(clearIndicesUid);
_vita2d_free_fragment_programs(&_vita2d_fragmentPrograms.blend_mode_normal);
_vita2d_free_fragment_programs(&_vita2d_fragmentPrograms.blend_mode_add);
gpu_free(linearIndicesUid);
gpu_free(clearVerticesUid); gpu_free(clearVerticesUid);
// wait until display queue is finished before deallocating display buffers // wait until display queue is finished before deallocating display buffers
@ -647,8 +732,9 @@ int vita2d_fini()
sceGxmSyncObjectDestroy(displayBufferSync[i]); sceGxmSyncObjectDestroy(displayBufferSync[i]);
} }
// free the depth buffer // free the depth and stencil buffer
gpu_free(depthBufferUid); gpu_free(depthBufferUid);
gpu_free(stencilBufferUid);
// unregister programs and destroy shader patcher // unregister programs and destroy shader patcher
sceGxmShaderPatcherUnregisterProgram(shaderPatcher, clearFragmentProgramId); sceGxmShaderPatcherUnregisterProgram(shaderPatcher, clearFragmentProgramId);
@ -701,7 +787,7 @@ void vita2d_clear_screen()
// draw the clear triangle // draw the clear triangle
sceGxmSetVertexStream(_vita2d_context, 0, clearVertices); sceGxmSetVertexStream(_vita2d_context, 0, clearVertices);
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, clearIndices, 3); sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, linearIndices, 3);
} }
void vita2d_swap_buffers() void vita2d_swap_buffers()
@ -723,23 +809,129 @@ void vita2d_swap_buffers()
void vita2d_start_drawing() void vita2d_start_drawing()
{ {
/* Reset the temporary memory pool */
vita2d_pool_reset(); vita2d_pool_reset();
vita2d_start_drawing_advanced(NULL, 0);
}
sceGxmBeginScene( void vita2d_start_drawing_advanced(vita2d_texture *target, unsigned int flags)
{
if (target == NULL) {
sceGxmBeginScene(
_vita2d_context, _vita2d_context,
0, flags,
renderTarget, renderTarget,
NULL, NULL,
NULL, NULL,
displayBufferSync[backBufferIndex], displayBufferSync[backBufferIndex],
&displaySurface[backBufferIndex], &displaySurface[backBufferIndex],
&depthSurface); &depthSurface);
} else {
sceGxmBeginScene(
_vita2d_context,
flags,
target->gxm_rtgt,
NULL,
NULL,
NULL,
&target->gxm_sfc,
&target->gxm_sfd);
}
drawing = 1;
// in the current way, the library keeps the region clip across scenes
if (clipping_enabled) {
vita2d_set_clip_rectangle(clip_rect_x_min, clip_rect_y_min, clip_rect_x_max, clip_rect_y_max);
}
} }
void vita2d_end_drawing() void vita2d_end_drawing()
{ {
sceGxmEndScene(_vita2d_context, NULL, NULL); sceGxmEndScene(_vita2d_context, NULL, NULL);
drawing = 0;
}
void vita2d_enable_clipping()
{
clipping_enabled = 1;
vita2d_set_clip_rectangle(clip_rect_x_min, clip_rect_y_min, clip_rect_x_max, clip_rect_y_max);
}
void vita2d_disable_clipping()
{
clipping_enabled = 0;
sceGxmSetFrontStencilFunc(
_vita2d_context,
SCE_GXM_STENCIL_FUNC_ALWAYS,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
0xFF,
0xFF);
}
int vita2d_get_clipping_enabled()
{
return clipping_enabled;
}
void vita2d_set_clip_rectangle(int x_min, int y_min, int x_max, int y_max)
{
clip_rect_x_min = x_min;
clip_rect_y_min = y_min;
clip_rect_x_max = x_max;
clip_rect_y_max = y_max;
// we can only draw during a scene, but we can cache the values since they're not going to have any visible effect till the scene starts anyways
if(drawing) {
// clear the stencil buffer to 0
sceGxmSetFrontStencilFunc(
_vita2d_context,
SCE_GXM_STENCIL_FUNC_NEVER,
SCE_GXM_STENCIL_OP_ZERO,
SCE_GXM_STENCIL_OP_ZERO,
SCE_GXM_STENCIL_OP_ZERO,
0xFF,
0xFF);
vita2d_draw_rectangle(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0);
// set the stencil to 1 in the desired region
sceGxmSetFrontStencilFunc(
_vita2d_context,
SCE_GXM_STENCIL_FUNC_NEVER,
SCE_GXM_STENCIL_OP_REPLACE,
SCE_GXM_STENCIL_OP_REPLACE,
SCE_GXM_STENCIL_OP_REPLACE,
0xFF,
0xFF);
vita2d_draw_rectangle(x_min, y_min, x_max - x_min, y_max - y_min, 0);
if(clipping_enabled) {
// set the stencil function to only accept pixels where the stencil is 1
sceGxmSetFrontStencilFunc(
_vita2d_context,
SCE_GXM_STENCIL_FUNC_EQUAL,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
0xFF,
0xFF);
} else {
sceGxmSetFrontStencilFunc(
_vita2d_context,
SCE_GXM_STENCIL_FUNC_ALWAYS,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
SCE_GXM_STENCIL_OP_KEEP,
0xFF,
0xFF);
}
}
}
void vita2d_get_clip_rectangle(int *x_min, int *y_min, int *x_max, int *y_max)
{
*x_min = clip_rect_x_min;
*y_min = clip_rect_y_min;
*x_max = clip_rect_x_max;
*y_max = clip_rect_y_max;
} }
int vita2d_common_dialog_update() int vita2d_common_dialog_update()
@ -769,7 +961,8 @@ void vita2d_set_clear_color(unsigned int color)
clear_color_u = color; clear_color_u = color;
} }
unsigned int vita2d_get_clear_color(){ unsigned int vita2d_get_clear_color()
{
return clear_color_u; return clear_color_u;
} }
@ -783,6 +976,21 @@ void *vita2d_get_current_fb()
return displayBufferData[frontBufferIndex]; return displayBufferData[frontBufferIndex];
} }
SceGxmContext *vita2d_get_context()
{
return _vita2d_context;
}
SceGxmShaderPatcher *vita2d_get_shader_patcher()
{
return shaderPatcher;
}
const uint16_t *vita2d_get_linear_indices()
{
return linearIndices;
}
void vita2d_set_region_clip(SceGxmRegionClipMode mode, unsigned int x_min, unsigned int y_min, unsigned int x_max, unsigned int y_max) void vita2d_set_region_clip(SceGxmRegionClipMode mode, unsigned int x_min, unsigned int y_min, unsigned int x_max, unsigned int y_max)
{ {
sceGxmSetRegionClip(_vita2d_context, mode, x_min, y_min, x_max, y_max); sceGxmSetRegionClip(_vita2d_context, mode, x_min, y_min, x_max, y_max);
@ -818,3 +1026,13 @@ void vita2d_pool_reset()
{ {
pool_index = 0; pool_index = 0;
} }
void vita2d_set_blend_mode_add(int enable)
{
vita2d_fragment_programs *in = enable ? &_vita2d_fragmentPrograms.blend_mode_add
: &_vita2d_fragmentPrograms.blend_mode_normal;
_vita2d_colorFragmentProgram = in->color;
_vita2d_textureFragmentProgram = in->texture;
_vita2d_textureTintFragmentProgram = in->textureTint;
}

View File

@ -7,6 +7,7 @@
#include "shared.h" #include "shared.h"
#define GXM_TEX_MAX_SIZE 4096 #define GXM_TEX_MAX_SIZE 4096
static SceKernelMemBlockType MemBlockType = SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW;
static int tex_format_to_bytespp(SceGxmTextureFormat format) static int tex_format_to_bytespp(SceGxmTextureFormat format)
{ {
@ -36,12 +37,22 @@ static int tex_format_to_bytespp(SceGxmTextureFormat format)
} }
} }
void vita2d_texture_set_alloc_memblock_type(SceKernelMemBlockType type)
{
MemBlockType = (type == 0) ? SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW : type;
}
SceKernelMemBlockType vita2d_texture_get_alloc_memblock_type()
{
return MemBlockType;
}
vita2d_texture *vita2d_create_empty_texture(unsigned int w, unsigned int h) vita2d_texture *vita2d_create_empty_texture(unsigned int w, unsigned int h)
{ {
return vita2d_create_empty_texture_format(w, h, SCE_GXM_TEXTURE_FORMAT_A8B8G8R8); return vita2d_create_empty_texture_format(w, h, SCE_GXM_TEXTURE_FORMAT_A8B8G8R8);
} }
vita2d_texture *vita2d_create_empty_texture_format(unsigned int w, unsigned int h, SceGxmTextureFormat format) static vita2d_texture *_vita2d_create_empty_texture_format_advanced(unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget)
{ {
if (w > GXM_TEX_MAX_SIZE || h > GXM_TEX_MAX_SIZE) if (w > GXM_TEX_MAX_SIZE || h > GXM_TEX_MAX_SIZE)
return NULL; return NULL;
@ -54,10 +65,10 @@ vita2d_texture *vita2d_create_empty_texture_format(unsigned int w, unsigned int
/* Allocate a GPU buffer for the texture */ /* Allocate a GPU buffer for the texture */
void *texture_data = gpu_alloc( void *texture_data = gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, MemBlockType,
tex_size, tex_size,
SCE_GXM_TEXTURE_ALIGNMENT, SCE_GXM_TEXTURE_ALIGNMENT,
SCE_GXM_MEMORY_ATTRIB_READ, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
&texture->data_UID); &texture->data_UID);
if (!texture_data) { if (!texture_data) {
@ -66,7 +77,7 @@ vita2d_texture *vita2d_create_empty_texture_format(unsigned int w, unsigned int
} }
/* Clear the texture */ /* Clear the texture */
//memset(texture_data, 0, tex_size); memset(texture_data, 0, tex_size);
/* Create the gxm texture */ /* Create the gxm texture */
sceGxmTextureInitLinear( sceGxmTextureInitLinear(
@ -82,7 +93,7 @@ vita2d_texture *vita2d_create_empty_texture_format(unsigned int w, unsigned int
const int pal_size = 256 * sizeof(uint32_t); const int pal_size = 256 * sizeof(uint32_t);
void *texture_palette = gpu_alloc( void *texture_palette = gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, MemBlockType,
pal_size, pal_size,
SCE_GXM_PALETTE_ALIGNMENT, SCE_GXM_PALETTE_ALIGNMENT,
SCE_GXM_MEMORY_ATTRIB_READ, SCE_GXM_MEMORY_ATTRIB_READ,
@ -94,19 +105,107 @@ vita2d_texture *vita2d_create_empty_texture_format(unsigned int w, unsigned int
return NULL; return NULL;
} }
//memset(texture_palette, 0, pal_size); memset(texture_palette, 0, pal_size);
sceGxmTextureSetPalette(&texture->gxm_tex, texture_palette); sceGxmTextureSetPalette(&texture->gxm_tex, texture_palette);
} else { } else {
texture->palette_UID = 0; texture->palette_UID = 0;
} }
if (isRenderTarget) {
int err = sceGxmColorSurfaceInit(
&texture->gxm_sfc,
SCE_GXM_COLOR_FORMAT_A8B8G8R8,
SCE_GXM_COLOR_SURFACE_LINEAR,
SCE_GXM_COLOR_SURFACE_SCALE_NONE,
SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
w,
h,
w,
texture_data
);
if (err < 0) {
vita2d_free_texture(texture);
return NULL;
}
// create the depth/stencil surface
const uint32_t alignedWidth = ALIGN(w, SCE_GXM_TILE_SIZEX);
const uint32_t alignedHeight = ALIGN(h, SCE_GXM_TILE_SIZEY);
uint32_t sampleCount = alignedWidth*alignedHeight;
uint32_t depthStrideInSamples = alignedWidth;
// allocate it
void *depthBufferData = gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
4*sampleCount,
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
&texture->depth_UID);
// create the SceGxmDepthStencilSurface structure
err = sceGxmDepthStencilSurfaceInit(
&texture->gxm_sfd,
SCE_GXM_DEPTH_STENCIL_FORMAT_S8D24,
SCE_GXM_DEPTH_STENCIL_SURFACE_TILED,
depthStrideInSamples,
depthBufferData,
NULL);
if (err < 0) {
vita2d_free_texture(texture);
return NULL;
}
SceGxmRenderTarget *tgt = NULL;
// set up parameters
SceGxmRenderTargetParams renderTargetParams;
memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams));
renderTargetParams.flags = 0;
renderTargetParams.width = w;
renderTargetParams.height = h;
renderTargetParams.scenesPerFrame = 1;
renderTargetParams.multisampleMode = SCE_GXM_MULTISAMPLE_NONE;
renderTargetParams.multisampleLocations = 0;
renderTargetParams.driverMemBlock = -1;
// create the render target
err = sceGxmCreateRenderTarget(&renderTargetParams, &tgt);
texture->gxm_rtgt = tgt;
if (err < 0) {
vita2d_free_texture(texture);
return NULL;
}
}
return texture; return texture;
} }
vita2d_texture * vita2d_create_empty_texture_format(unsigned int w, unsigned int h, SceGxmTextureFormat format)
{
return _vita2d_create_empty_texture_format_advanced(w, h, format, 0);
}
vita2d_texture * vita2d_create_empty_texture_rendertarget(unsigned int w, unsigned int h, SceGxmTextureFormat format)
{
return _vita2d_create_empty_texture_format_advanced(w, h, format, 1);
}
void vita2d_free_texture(vita2d_texture *texture) void vita2d_free_texture(vita2d_texture *texture)
{ {
if (texture) { if (texture) {
if (texture->gxm_rtgt) {
sceGxmDestroyRenderTarget(texture->gxm_rtgt);
}
if (texture->depth_UID) {
gpu_free(texture->depth_UID);
}
if (texture->palette_UID) { if (texture->palette_UID) {
gpu_free(texture->palette_UID); gpu_free(texture->palette_UID);
} }
@ -178,7 +277,6 @@ static inline void set_texture_wvp_uniform()
{ {
void *vertex_wvp_buffer; void *vertex_wvp_buffer;
sceGxmReserveVertexDefaultUniformBuffer(_vita2d_context, &vertex_wvp_buffer); sceGxmReserveVertexDefaultUniformBuffer(_vita2d_context, &vertex_wvp_buffer);
//matrix_init_orthographic(_vita2d_ortho_matrix, 0.0f, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0.0f, 0.0f, 1.0f);
sceGxmSetUniformDataF(vertex_wvp_buffer, _vita2d_textureWvpParam, 0, 16, _vita2d_ortho_matrix); sceGxmSetUniformDataF(vertex_wvp_buffer, _vita2d_textureWvpParam, 0, 16, _vita2d_ortho_matrix);
} }
@ -205,10 +303,6 @@ static inline void draw_texture_generic(const vita2d_texture *texture, float x,
4 * sizeof(vita2d_texture_vertex), // 4 vertices 4 * sizeof(vita2d_texture_vertex), // 4 vertices
sizeof(vita2d_texture_vertex)); sizeof(vita2d_texture_vertex));
uint16_t *indices = (uint16_t *)vita2d_pool_memalign(
4 * sizeof(uint16_t), // 4 indices
sizeof(uint16_t));
const float w = vita2d_texture_get_width(texture); const float w = vita2d_texture_get_width(texture);
const float h = vita2d_texture_get_height(texture); const float h = vita2d_texture_get_height(texture);
@ -236,16 +330,11 @@ static inline void draw_texture_generic(const vita2d_texture *texture, float x,
vertices[3].u = 1.0f; vertices[3].u = 1.0f;
vertices[3].v = 1.0f; vertices[3].v = 1.0f;
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 3;
// Set the texture to the TEXUNIT0 // Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex); sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices); sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, indices, 4); sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), 4);
} }
void vita2d_draw_texture(const vita2d_texture *texture, float x, float y) void vita2d_draw_texture(const vita2d_texture *texture, float x, float y)
@ -284,10 +373,6 @@ static inline void draw_texture_rotate_hotspot_generic(const vita2d_texture *tex
4 * sizeof(vita2d_texture_vertex), // 4 vertices 4 * sizeof(vita2d_texture_vertex), // 4 vertices
sizeof(vita2d_texture_vertex)); sizeof(vita2d_texture_vertex));
uint16_t *indices = (uint16_t *)vita2d_pool_memalign(
4 * sizeof(uint16_t), // 4 indices
sizeof(uint16_t));
const float w = vita2d_texture_get_width(texture); const float w = vita2d_texture_get_width(texture);
const float h = vita2d_texture_get_height(texture); const float h = vita2d_texture_get_height(texture);
@ -325,16 +410,11 @@ static inline void draw_texture_rotate_hotspot_generic(const vita2d_texture *tex
vertices[i].y = _x*s + _y*c + y; vertices[i].y = _x*s + _y*c + y;
} }
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 3;
// Set the texture to the TEXUNIT0 // Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex); sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices); sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, indices, 4); sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), 4);
} }
void vita2d_draw_texture_rotate_hotspot(const vita2d_texture *texture, float x, float y, float rad, float center_x, float center_y) void vita2d_draw_texture_rotate_hotspot(const vita2d_texture *texture, float x, float y, float rad, float center_x, float center_y)
@ -358,10 +438,6 @@ static inline void draw_texture_scale_generic(const vita2d_texture *texture, flo
4 * sizeof(vita2d_texture_vertex), // 4 vertices 4 * sizeof(vita2d_texture_vertex), // 4 vertices
sizeof(vita2d_texture_vertex)); sizeof(vita2d_texture_vertex));
uint16_t *indices = (uint16_t *)vita2d_pool_memalign(
4 * sizeof(uint16_t), // 4 indices
sizeof(uint16_t));
const float w = x_scale * vita2d_texture_get_width(texture); const float w = x_scale * vita2d_texture_get_width(texture);
const float h = y_scale * vita2d_texture_get_height(texture); const float h = y_scale * vita2d_texture_get_height(texture);
@ -389,16 +465,11 @@ static inline void draw_texture_scale_generic(const vita2d_texture *texture, flo
vertices[3].u = 1.0f; vertices[3].u = 1.0f;
vertices[3].v = 1.0f; vertices[3].v = 1.0f;
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 3;
// Set the texture to the TEXUNIT0 // Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex); sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices); sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, indices, 4); sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), 4);
} }
void vita2d_draw_texture_scale(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale) void vita2d_draw_texture_scale(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale)
@ -423,10 +494,6 @@ static inline void draw_texture_part_generic(const vita2d_texture *texture, floa
4 * sizeof(vita2d_texture_vertex), // 4 vertices 4 * sizeof(vita2d_texture_vertex), // 4 vertices
sizeof(vita2d_texture_vertex)); sizeof(vita2d_texture_vertex));
uint16_t *indices = (uint16_t *)vita2d_pool_memalign(
4 * sizeof(uint16_t), // 4 indices
sizeof(uint16_t));
const float w = vita2d_texture_get_width(texture); const float w = vita2d_texture_get_width(texture);
const float h = vita2d_texture_get_height(texture); const float h = vita2d_texture_get_height(texture);
@ -459,16 +526,11 @@ static inline void draw_texture_part_generic(const vita2d_texture *texture, floa
vertices[3].u = u1; vertices[3].u = u1;
vertices[3].v = v1; vertices[3].v = v1;
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 3;
// Set the texture to the TEXUNIT0 // Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex); sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices); sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, indices, 4); sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), 4);
} }
void vita2d_draw_texture_part(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h) void vita2d_draw_texture_part(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h)
@ -492,10 +554,6 @@ static inline void draw_texture_part_scale_generic(const vita2d_texture *texture
4 * sizeof(vita2d_texture_vertex), // 4 vertices 4 * sizeof(vita2d_texture_vertex), // 4 vertices
sizeof(vita2d_texture_vertex)); sizeof(vita2d_texture_vertex));
uint16_t *indices = (uint16_t *)vita2d_pool_memalign(
4 * sizeof(uint16_t), // 4 indices
sizeof(uint16_t));
const float w = vita2d_texture_get_width(texture); const float w = vita2d_texture_get_width(texture);
const float h = vita2d_texture_get_height(texture); const float h = vita2d_texture_get_height(texture);
@ -531,16 +589,11 @@ static inline void draw_texture_part_scale_generic(const vita2d_texture *texture
vertices[3].u = u1; vertices[3].u = u1;
vertices[3].v = v1; vertices[3].v = v1;
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 3;
// Set the texture to the TEXUNIT0 // Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex); sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices); sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, indices, 4); sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), 4);
} }
void vita2d_draw_texture_part_scale(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale) void vita2d_draw_texture_part_scale(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale)
@ -564,10 +617,6 @@ static inline void draw_texture_scale_rotate_hotspot_generic(const vita2d_textur
4 * sizeof(vita2d_texture_vertex), // 4 vertices 4 * sizeof(vita2d_texture_vertex), // 4 vertices
sizeof(vita2d_texture_vertex)); sizeof(vita2d_texture_vertex));
uint16_t *indices = (uint16_t *)vita2d_pool_memalign(
4 * sizeof(uint16_t), // 4 indices
sizeof(uint16_t));
const float w = x_scale * vita2d_texture_get_width(texture); const float w = x_scale * vita2d_texture_get_width(texture);
const float h = y_scale * vita2d_texture_get_height(texture); const float h = y_scale * vita2d_texture_get_height(texture);
const float center_x_scaled = x_scale * center_x; const float center_x_scaled = x_scale * center_x;
@ -607,16 +656,11 @@ static inline void draw_texture_scale_rotate_hotspot_generic(const vita2d_textur
vertices[i].y = _x*s + _y*c + y + center_y_scaled; vertices[i].y = _x*s + _y*c + y + center_y_scaled;
} }
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 3;
// Set the texture to the TEXUNIT0 // Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex); sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices); sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, indices, 4); sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), 4);
} }
void vita2d_draw_texture_scale_rotate_hotspot(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, float center_x, float center_y) void vita2d_draw_texture_scale_rotate_hotspot(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, float center_x, float center_y)
@ -650,43 +694,95 @@ void vita2d_draw_texture_tint_scale_rotate(const vita2d_texture *texture, float
vita2d_texture_get_height(texture)/2.0f, color); vita2d_texture_get_height(texture)/2.0f, color);
} }
void vita2d_texture_set_wvp(float x, float y, float width, float height) static inline void draw_texture_part_scale_rotate_generic(const vita2d_texture *texture, float x, float y,
float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, float rad)
{ {
void *vertex_wvp_buffer; vita2d_texture_vertex *vertices = (vita2d_texture_vertex *)vita2d_pool_memalign(
matrix_init_orthographic(_vita2d_ortho_matrix, x, width, height, y, 0.0f, 1.0f); 4 * sizeof(vita2d_texture_vertex), // 4 vertices
sceGxmReserveVertexDefaultUniformBuffer(_vita2d_context, &vertex_wvp_buffer); sizeof(vita2d_texture_vertex));
sceGxmSetUniformDataF(vertex_wvp_buffer, _vita2d_textureWvpParam, 0, 16, _vita2d_ortho_matrix);
}
void vita2d_texture_set_program(){ const float w_full = vita2d_texture_get_width(texture);
set_texture_program(); const float h_full = vita2d_texture_get_height(texture);
}
void vita2d_texture_set_tint_program(){ const float w_half = (tex_w * x_scale) / 2.0f;
set_texture_tint_program(); const float h_half = (tex_h * y_scale) / 2.0f;
}
void vita2d_texture_set_tint_color_uniform(unsigned int color){ const float u0 = tex_x / w_full;
set_texture_tint_color_uniform(color); const float v0 = tex_y / h_full;
} const float u1 = (tex_x + tex_w) / w_full;
const float v1 = (tex_y + tex_h) / h_full;
vertices[0].x = -w_half;
vertices[0].y = -h_half;
vertices[0].z = +0.5f;
vertices[0].u = u0;
vertices[0].v = v0;
void vita2d_draw_texture_part_generic(const vita2d_texture *texture, SceGxmPrimitiveType type, vita2d_texture_vertex *vertices, unsigned int num_vertices) vertices[1].x = w_half;
{ vertices[1].y = -h_half;
vertices[1].z = +0.5f;
vertices[1].u = u1;
vertices[1].v = v0;
uint16_t *indices = (uint16_t *)vita2d_pool_memalign( vertices[2].x = -w_half;
num_vertices * sizeof(uint16_t), // 4 indices vertices[2].y = h_half;
sizeof(uint16_t)); vertices[2].z = +0.5f;
vertices[2].u = u0;
vertices[2].v = v1;
for(int n = 0; n < num_vertices; n++){ vertices[3].x = w_half;
indices[n] = n; vertices[3].y = h_half;
vertices[3].z = +0.5f;
vertices[3].u = u1;
vertices[3].v = v1;
const float c = cosf(rad);
const float s = sinf(rad);
int i;
for (i = 0; i < 4; ++i) { // Rotate and translate
float _x = vertices[i].x;
float _y = vertices[i].y;
vertices[i].x = _x*c - _y*s + x;
vertices[i].y = _x*s + _y*c + y;
} }
// Set the texture to the TEXUNIT0 // Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex); sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices); sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, type, SCE_GXM_INDEX_FORMAT_U16, indices, 4); sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), 4);
} }
void vita2d_draw_texture_part_scale_rotate(const vita2d_texture *texture, float x, float y,
float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, float rad)
{
set_texture_program();
set_texture_wvp_uniform();
draw_texture_part_scale_rotate_generic(texture, x, y,
tex_x, tex_y, tex_w, tex_h, x_scale, y_scale, rad);
}
void vita2d_draw_texture_part_tint_scale_rotate(const vita2d_texture *texture, float x, float y,
float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, float rad, unsigned int color)
{
set_texture_tint_program();
set_texture_wvp_uniform();
set_texture_tint_color_uniform(color);
draw_texture_part_scale_rotate_generic(texture, x, y,
tex_x, tex_y, tex_w, tex_h, x_scale, y_scale, rad);
}
void vita2d_draw_array_textured(const vita2d_texture *texture, SceGxmPrimitiveType mode, const vita2d_texture_vertex *vertices, size_t count, unsigned int color)
{
set_texture_tint_program();
set_texture_wvp_uniform();
set_texture_tint_color_uniform(color);
sceGxmSetBackPolygonMode(_vita2d_context, SCE_GXM_POLYGON_MODE_TRIANGLE_FILL);
// Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, mode, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), count);
}