Skip to content

Commit

Permalink
Added rectangle gradients, triangles, updated sf2dlib
Browse files Browse the repository at this point in the history
Gradients are done with additional parameters to gfx.rectangle, so old code that gave the function too many parameters and expected them to be ignored may break.
  • Loading branch information
Reuh committed Jun 27, 2016
1 parent 4a2c1a7 commit b47971b
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 112 deletions.
1 change: 1 addition & 0 deletions libs/sf2dlib/libsf2d/.gitignore
@@ -0,0 +1 @@
/Default/
45 changes: 45 additions & 0 deletions libs/sf2dlib/libsf2d/include/sf2d.h
Expand Up @@ -67,6 +67,14 @@ typedef enum {
TEXFMT_ETC1A4 = 13
} sf2d_texfmt;

/**
* @brief Represents a direction for drawing a gradient
*/

typedef enum {
SF2D_TOP_TO_BOTTOM,
SF2D_LEFT_TO_RIGHT
} sf2d_gradient_dir;

/**
* @brief Data allocated on the RAM or VRAM
Expand Down Expand Up @@ -264,6 +272,18 @@ void sf2d_set_clear_color(u32 color);
*/
void sf2d_draw_rectangle(int x, int y, int w, int h, u32 color);

/**
* @brief Draws a triangle
* @param x1 x coordinate of a vertex of the triangle
* @param y1 y coordinate of a vertex of the triangle
* @param x2 x coordinate of a vertex of the triangle
* @param y2 y coordinate of a vertex of the triangle
* @param x3 x coordinate of a vertex of the triangle
* @param y3 y coordinate of a vertex of the triangle
* @param color the color to draw the triangle
*/
void sf2d_draw_triangle(float x1, float y1, float x2, float y2, float x3, float y3, u32 color);

/**
* @brief Draws a rotated rectangle
* @param x x coordinate of the top left corner of the rectangle
Expand All @@ -275,6 +295,31 @@ void sf2d_draw_rectangle(int x, int y, int w, int h, u32 color);
*/
void sf2d_draw_rectangle_rotate(int x, int y, int w, int h, u32 color, float rad);

/**
* @brief Draws a rectangle
* @param x x coordinate of the top left corner of the rectangle
* @param y y coordinate of the top left corner of the rectangle
* @param w rectangle width
* @param h rectangle height
* @param color1 the color at the start of the gradient
* @param color2 the color at the end of the gradient
* @param left_to_right determines which direction the gradient is in
*/
void sf2d_draw_rectangle_gradient(int x, int y, int w, int h, u32 color1, u32 color2, sf2d_gradient_dir direction);

/**
* @brief Draws a rotated rectangle
* @param x x coordinate of the top left corner of the rectangle
* @param y y coordinate of the top left corner of the rectangle
* @param w rectangle width
* @param h rectangle height
* @param color1 the color at the start of the gradient
* @param color2 the color at the end of the gradient
* @param left_to_right determines which direction the gradient is in
* @param rad rotation (in radians) to draw the rectangle
*/
void sf2d_draw_rectangle_gradient_rotate(int x, int y, int w, int h, u32 color1, u32 color2, sf2d_gradient_dir direction, float rad);

/**
* @brief Draws a filled circle
* @param x x coordinate of the center of the circle
Expand Down
2 changes: 2 additions & 0 deletions libs/sf2dlib/libsf2d/include/sf2d_private.h
Expand Up @@ -7,6 +7,8 @@

void GPU_SetDummyTexEnv(u8 num);

void sf2d_draw_rectangle_internal(const sf2d_vertex_pos_col *vertices);

// Vector operations

void vector_mult_matrix4x4(const float *msrc, const sf2d_vector_3f *vsrc, sf2d_vector_3f *vdst);
Expand Down
185 changes: 102 additions & 83 deletions libs/sf2dlib/libsf2d/source/sf2d_draw.c
Expand Up @@ -6,6 +6,30 @@
#define M_PI (3.14159265358979323846)
#endif

void sf2d_setup_env_internal(const sf2d_vertex_pos_col* vertices) {
GPU_SetTexEnv(
0,
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVOPERANDS(0, 0, 0),
GPU_TEVOPERANDS(0, 0, 0),
GPU_REPLACE, GPU_REPLACE,
0xFFFFFFFF
);

GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE),
0xFFFC, //0b1100
0x10,
1, //number of buffers
(u32[]){0x0}, // buffer offsets (placeholders)
(u64[]){0x10}, // attribute permutations for each buffer
(u8[]){2} // number of attributes for each buffer
);
}

void sf2d_draw_line(float x0, float y0, float x1, float y1, float width, u32 color)
{
sf2d_vertex_pos_col *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_col), 8);
Expand Down Expand Up @@ -38,31 +62,25 @@ void sf2d_draw_line(float x0, float y0, float x1, float y1, float width, u32 col
vertices[2].color = vertices[0].color;
vertices[3].color = vertices[0].color;

GPU_SetTexEnv(
0,
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVOPERANDS(0, 0, 0),
GPU_TEVOPERANDS(0, 0, 0),
GPU_REPLACE, GPU_REPLACE,
0xFFFFFFFF
);
sf2d_setup_env_internal(vertices);

GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE),
0xFFFC, //0b1100
0x10,
1, //number of buffers
(u32[]){0x0}, // buffer offsets (placeholders)
(u64[]){0x10}, // attribute permutations for each buffer
(u8[]){2} // number of attributes for each buffer
);
GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
}

void sf2d_draw_rectangle_internal(const sf2d_vertex_pos_col *vertices)
{
sf2d_setup_env_internal(vertices);

GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
}

void sf2d_draw_triangle_internal(const sf2d_vertex_pos_col *vertices)
{
sf2d_setup_env_internal(vertices);

GPU_DrawArray(GPU_TRIANGLES, 0, 3);
}

void sf2d_draw_rectangle(int x, int y, int w, int h, u32 color)
{
sf2d_vertex_pos_col *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_col), 8);
Expand All @@ -78,29 +96,23 @@ void sf2d_draw_rectangle(int x, int y, int w, int h, u32 color)
vertices[2].color = vertices[0].color;
vertices[3].color = vertices[0].color;

GPU_SetTexEnv(
0,
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVOPERANDS(0, 0, 0),
GPU_TEVOPERANDS(0, 0, 0),
GPU_REPLACE, GPU_REPLACE,
0xFFFFFFFF
);
sf2d_draw_rectangle_internal(vertices);
}

GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE),
0xFFFC, //0b1100
0x10,
1, //number of buffers
(u32[]){0x0}, // buffer offsets (placeholders)
(u64[]){0x10}, // attribute permutations for each buffer
(u8[]){2} // number of attributes for each buffer
);
void sf2d_draw_triangle(float x1, float y1, float x2, float y2, float x3, float y3, u32 color)
{
sf2d_vertex_pos_col *vertices = sf2d_pool_memalign(3 * sizeof(sf2d_vertex_pos_col), 8);
if (!vertices) return;

GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
vertices[0].position = (sf2d_vector_3f){(float)x1, (float)y1, SF2D_DEFAULT_DEPTH};
vertices[1].position = (sf2d_vector_3f){(float)x2, (float)y2, SF2D_DEFAULT_DEPTH};
vertices[2].position = (sf2d_vector_3f){(float)x3, (float)y3, SF2D_DEFAULT_DEPTH};

vertices[0].color = color;
vertices[1].color = vertices[0].color;
vertices[2].color = vertices[0].color;

sf2d_draw_triangle_internal(vertices);
}

void sf2d_draw_rectangle_rotate(int x, int y, int w, int h, u32 color, float rad)
Expand Down Expand Up @@ -131,29 +143,56 @@ void sf2d_draw_rectangle_rotate(int x, int y, int w, int h, u32 color, float rad
vertices[i].position = (sf2d_vector_3f){rot[i].x + x + w2, rot[i].y + y + h2, rot[i].z};
}

GPU_SetTexEnv(
0,
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVOPERANDS(0, 0, 0),
GPU_TEVOPERANDS(0, 0, 0),
GPU_REPLACE, GPU_REPLACE,
0xFFFFFFFF
);
sf2d_draw_rectangle_internal(vertices);
}

GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE),
0xFFFC, //0b1100
0x10,
1, //number of buffers
(u32[]){0x0}, // buffer offsets (placeholders)
(u64[]){0x10}, // attribute permutations for each buffer
(u8[]){2} // number of attributes for each buffer
);
void sf2d_draw_rectangle_gradient(int x, int y, int w, int h, u32 color1, u32 color2, sf2d_gradient_dir direction)
{
sf2d_vertex_pos_col *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_col), 8);
if (!vertices) return;

GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4);
vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, SF2D_DEFAULT_DEPTH};
vertices[1].position = (sf2d_vector_3f){(float)x+w, (float)y, SF2D_DEFAULT_DEPTH};
vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+h, SF2D_DEFAULT_DEPTH};
vertices[3].position = (sf2d_vector_3f){(float)x+w, (float)y+h, SF2D_DEFAULT_DEPTH};

vertices[0].color = color1;
vertices[1].color = (direction == SF2D_LEFT_TO_RIGHT) ? color2 : color1;
vertices[2].color = (direction == SF2D_LEFT_TO_RIGHT) ? color1 : color2;
vertices[3].color = color2;

sf2d_draw_rectangle_internal(vertices);
}

void sf2d_draw_rectangle_gradient_rotate(int x, int y, int w, int h, u32 color1, u32 color2, sf2d_gradient_dir direction, float rad)
{
sf2d_vertex_pos_col *vertices = sf2d_pool_memalign(4 * sizeof(sf2d_vertex_pos_col), 8);
if (!vertices) return;

int w2 = w/2.0f;
int h2 = h/2.0f;

vertices[0].position = (sf2d_vector_3f){(float)-w2, (float)-h2, SF2D_DEFAULT_DEPTH};
vertices[1].position = (sf2d_vector_3f){(float) w2, (float)-h2, SF2D_DEFAULT_DEPTH};
vertices[2].position = (sf2d_vector_3f){(float)-w2, (float) h2, SF2D_DEFAULT_DEPTH};
vertices[3].position = (sf2d_vector_3f){(float) w2, (float) h2, SF2D_DEFAULT_DEPTH};

vertices[0].color = color1;
vertices[1].color = (direction == SF2D_LEFT_TO_RIGHT) ? color2 : color1;
vertices[2].color = (direction == SF2D_LEFT_TO_RIGHT) ? color1 : color2;
vertices[3].color = color2;

float m[4*4];
matrix_set_z_rotation(m, rad);
sf2d_vector_3f rot[4];

int i;
for (i = 0; i < 4; i++) {
vector_mult_matrix4x4(m, &vertices[i].position, &rot[i]);
vertices[i].position = (sf2d_vector_3f){rot[i].x + x + w2, rot[i].y + y + h2, rot[i].z};
}

sf2d_draw_rectangle_internal(vertices);
}

void sf2d_draw_fill_circle(int x, int y, int radius, u32 color)
Expand Down Expand Up @@ -186,27 +225,7 @@ void sf2d_draw_fill_circle(int x, int y, int radius, u32 color)
vertices[num_segments + 1].position = vertices[1].position;
vertices[num_segments + 1].color = vertices[1].color;

GPU_SetTexEnv(
0,
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR),
GPU_TEVOPERANDS(0, 0, 0),
GPU_TEVOPERANDS(0, 0, 0),
GPU_REPLACE, GPU_REPLACE,
0xFFFFFFFF
);

GPU_SetAttributeBuffers(
2, // number of attributes
(u32*)osConvertVirtToPhys(vertices),
GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE),
0xFFFC, //0b1100
0x10,
1, //number of buffers
(u32[]){0x0}, // buffer offsets (placeholders)
(u64[]){0x10}, // attribute permutations for each buffer
(u8[]){2} // number of attributes for each buffer
);
sf2d_setup_env_internal(vertices);

GPU_DrawArray(GPU_TRIANGLE_FAN, 0, num_segments + 2);
}
29 changes: 24 additions & 5 deletions libs/sf2dlib/libsf2d/source/sf2d_texture.c
Expand Up @@ -8,7 +8,7 @@
#define M_PI (3.14159265358979323846)
#endif

#define TEX_MIN_SIZE 8
#define TEX_MIN_SIZE 32

static unsigned int nibbles_per_pixel(sf2d_texfmt format)
{
Expand Down Expand Up @@ -146,21 +146,40 @@ void sf2d_clear_target(sf2d_rendertarget *target, u32 color) {
sf2d_texture_tile32(&(target->texture));
}

void sf2d_texture_tile32_hardware(sf2d_texture *texture, const void *data, int w, int h)
{
if (texture->tiled) return;
const u32 flags = (GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) |
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGBA8) |
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO));

GSPGPU_FlushDataCache(data, (w*h)<<2);
GX_DisplayTransfer(
(u32*)data,
GX_BUFFER_DIM(w, h),
(u32*)texture->data,
GX_BUFFER_DIM(texture->pow2_w, texture->pow2_h),
flags
);
gspWaitForPPF();
GSPGPU_InvalidateDataCache(texture->data, texture->data_size);
texture->tiled = 1;
}

void sf2d_fill_texture_from_RGBA8(sf2d_texture *dst, const void *rgba8, int source_w, int source_h)
{
// TODO: add support for non-RGBA8 textures

u8 *tmp = linearAlloc(dst->pow2_w * dst->pow2_h * 4);
u8 *tmp = linearAlloc((dst->pow2_w * dst->pow2_h)<<2);
int i, j;
for (i = 0; i < source_h; i++) {
for (j = 0; j < source_w; j++) {
((u32 *)tmp)[i*dst->pow2_w + j] = ((u32 *)rgba8)[i*source_w + j];
((u32 *)tmp)[i*dst->pow2_w + j] = __builtin_bswap32(((u32 *)rgba8)[i*source_w + j]);
}
}
memcpy(dst->data, tmp, dst->pow2_w*dst->pow2_h*4);
sf2d_texture_tile32_hardware(dst, tmp, dst->pow2_w, dst->pow2_h);
linearFree(tmp);

sf2d_texture_tile32(dst);
}

sf2d_texture *sf2d_create_texture_mem_RGBA8(const void *src_buffer, int src_w, int src_h, sf2d_texfmt pixel_format, sf2d_place place)
Expand Down

0 comments on commit b47971b

Please sign in to comment.