Homebrew [Release] {beta} sf2dlib - Simple and Fast 2D library (using the GPU)

xerpi

Well-Known Member
OP
Member
Joined
Dec 25, 2011
Messages
215
Trophies
1
Age
29
Location
Tokyo
XP
1,544
Country
Spain
Hi there, lately I've been coding a GPU accelerated 2D library for the Nintendo 3DS, on top of ctrulib. I've got to the point where it starts to be usable, so I think it's time to release it.
This will benefit you if you want to code a 2D game/app/emulator, as you obviously will need to draw textures/images. Maybe software rendering is enough, but if you have a GPU out there, why don't you use it ? ;)

DOCUMENTATION: http://xerpi.github.io/sf2dlib/html/sf2d_8h.html#func-members

DOWNLOAD: https://github.com/xerpi/sf2dlib

Precompiled portlibs: https://github.com/xerpi/3ds_portlibs/releases/tag/1

If you need to load images, take a look at this lib: https://github.com/xerpi/sfillib

Here there are the functions SF2D provides:
Code:
int sf2d_init();
int sf2d_init_advanced(int gpucmd_size, int temppool_size);
int sf2d_fini();

void sf2d_set_3D(int enable);

void sf2d_start_frame(gfxScreen_t screen, gfx3dSide_t side);
void sf2d_end_frame();

void sf2d_swapbuffers();
void sf2d_set_vblank_wait(int enable);

float sf2d_get_fps();

void *sf2d_pool_malloc(u32 size);
void *sf2d_pool_memalign(u32 size, u32 alignment);
unsigned int sf2d_pool_space_free();
void sf2d_pool_reset();

void sf2d_set_clear_color(u32 color);

void sf2d_draw_line(int x0, int y0, int x1, int y1, u32 color);
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);

sf2d_texture *sf2d_create_texture(int width, int height, GPU_TEXCOLOR pixel_format, sf2d_place place);
void sf2d_free_texture(sf2d_texture *texture);

void sf2d_fill_texture_from_RGBA8(sf2d_texture *dst, const void *rgba8, int source_w, int source_h);
sf2d_texture *sf2d_create_texture_mem_RGBA8(const void *src_buffer, int src_w, int src_h, GPU_TEXCOLOR pixel_format, sf2d_place place);

void sf2d_bind_texture(const sf2d_texture *texture, GPU_TEXUNIT unit);
void sf2d_bind_texture_color(const sf2d_texture *texture, GPU_TEXUNIT unit, u32 color);

void sf2d_draw_texture(const sf2d_texture *texture, int x, int y);
void sf2d_draw_texture_rotate(const sf2d_texture *texture, int x, int y, float rad);
void sf2d_draw_texture_part(const sf2d_texture *texture, int x, int y, int tex_x, int tex_y, int tex_w, int tex_h);
void sf2d_draw_texture_scale(const sf2d_texture *texture, int x, int y, float x_scale, float y_scale);
void sf2d_draw_texture_rotate_cut_scale(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale);
void sf2d_draw_texture_blend(const sf2d_texture *texture, int x, int y, u32 color);
void sf2d_draw_texture_part_blend(const sf2d_texture *texture, int x, int y, int tex_x, int tex_y, int tex_w, int tex_h, u32 color);
void sf2d_draw_texture_depth(const sf2d_texture *texture, int x, int y, signed short z);
void sf2d_texture_tile32(sf2d_texture *texture);

void sf2d_set_scissor_test(GPU_SCISSORMODE mode, u32 x, u32 y, u32 w, u32 h);

gfxScreen_t sf2d_get_current_screen();
gfx3dSide_t sf2d_get_current_side();

The 2D coordinate system goes like this:
Code:
Top screen:
      X
  ---------->
  | (0,0)
  |  ______________________
Y | |                      |
  | |                      |
  v |                      |
    |                      |
    |                      |
    |______________________|
                      (400, 240)
Bottom screen:
        X
    ---------->
    | (0,0)
    |  ________________
  Y | |                |
    | |                |
    v |                |
      |                |
      |                |
      |________________|
                  (320, 240)
And the skeleton of a program using this lib:
Code:
int main()
{
    sf2d_init();
    sf2d_set_clear_color(RGBA8(0x00, 0x00, 0x00, 0x00));

    while (aptMainLoop()) {

        hidScanInput();
        if (hidKeysDown() & KEY_START) break;

        sf2d_start_frame(GFX_TOP, GFX_LEFT);
            //Draws a 100x100 yellow rectangle (255, 255, 00, 255) at (150, 70)
            sf2d_draw_rectangle(150, 70, 100, 100, RGBA8(0xFF, 0xFF, 0x00, 0xFF));
        sf2d_end_frame();

        sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
            //Draws a 70x100 blue rectangle (0, 0, 00, 255) at (120, 30)
            sf2d_draw_rectangle(120, 30, 70, 100, RGBA8(0x00, 0x00, 0xFF, 0xFF));
        sf2d_end_frame();

        sf2d_swapbuffers();
    }

    sf2d_fini();
    return 0;
}

A more complex sample: https://github.com/xerpi/sf2dlib/blob/master/sample/source/main.c

Screenshot of Citra emulator running a sample using my lib:
v93z1eU.png
 
Last edited by xerpi,

xerpi

Well-Known Member
OP
Member
Joined
Dec 25, 2011
Messages
215
Trophies
1
Age
29
Location
Tokyo
XP
1,544
Country
Spain
I was just starting converting lpp-3ds luaGraphics to ctrGL for GPU usage but this sounds much more better, very thanks for sharing this :D

No problem :D Btw this will be a 2D-only lib, so if you want to do some 3D on lpp-3ds maybe it's not the best option.
I'll add texture rotation/zoom support very soon!
 

Rinnegatamante

Well-Known Member
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
30
Location
Bologna
Website
rinnegatamante.it
XP
4,869
Country
Italy
No problem :D Btw this will be a 2D-only lib, so if you want to do some 3D on lpp-3ds maybe it's not the best option.
I'll add texture rotation/zoom support very soon!

luaGraphics module is only for 2D Graphics (probably for 3D i'll use another module name like lua3D).
 
  • Like
Reactions: Margen67

xerpi

Well-Known Member
OP
Member
Joined
Dec 25, 2011
Messages
215
Trophies
1
Age
29
Location
Tokyo
XP
1,544
Country
Spain
luaGraphics module is only for 2D Graphics (probably for 3D i'll use another module name like lua3D).

Cool! Btw switching from 2D to 3DS isn't hard, you mainly have to change the projection matrix (an uniform passed to the GPU) and maybe the shader.
 

Rinnegatamante

Well-Known Member
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
30
Location
Bologna
Website
rinnegatamante.it
XP
4,869
Country
Italy
Got an error during compilation, i'm using GPU folder from latest libctru revision:
Code:
c:/Users/Alessio/Desktop/lpp-3ds/source/include/sf2d/sf2d.c:48:58: error: request for member 'vertexShader' in something not a structure or union
  modelview_desc = shaderInstanceGetUniformLocation(shader.vertexShader, "modelview");
 

xerpi

Well-Known Member
OP
Member
Joined
Dec 25, 2011
Messages
215
Trophies
1
Age
29
Location
Tokyo
XP
1,544
Country
Spain
Got an error during compilation, i'm using GPU folder from latest libctru revision:
Code:
c:/Users/Alessio/Desktop/lpp-3ds/source/include/sf2d/sf2d.c:48:58: error: request for member 'vertexShader' in something not a structure or union
  modelview_desc = shaderInstanceGetUniformLocation(shader.vertexShader, "modelview");

Weird, are you sure you are using the latest ctrulib version?
I've shader defined as:
Code:
static shaderProgram_s shader;
And if you look at the source of ctrulib: https://github.com/smealum/ctrulib/blob/master/libctru/include/3ds/gpu/shaderProgram.h#L28
It has the vertexShader member.
 

Rinnegatamante

Well-Known Member
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
30
Location
Bologna
Website
rinnegatamante.it
XP
4,869
Country
Italy
  • Like
Reactions: xerpi

Rinnegatamante

Well-Known Member
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
30
Location
Bologna
Website
rinnegatamante.it
XP
4,869
Country
Italy
Yes, this also happens with the ctrulib's GPU sample.
Are you using my sf2d sample?

I just tried to blend two simple rectangles:

Code:
Graphics.init()
while true do
    Graphics.initBlend(TOP_SCREEN)
    Graphics.fillRect(50,100,50,100,Color.new(255,255,0,255))
    Graphics.termBlend()
    Graphics.initBlend(BOTTOM_SCREEN)
    Graphics.fillRect(70,120,100,120,Color.new(255,255,0,255))
    Graphics.termBlend()
end

where:
Code:
static int lua_init(lua_State *L) {
    int argc = lua_gettop(L);
    if (argc != 0) return luaL_error(L, "wrong number of arguments"); 
    sf2d_init();
    sf2d_set_clear_color(RGBA8(0x00, 0x00, 0x00, 0xFF));
    return 0;
}
 
static int lua_initblend(lua_State *L) {
    int argc = lua_gettop(L);
    if ((argc != 1) && (argc != 2))  return luaL_error(L, "wrong number of arguments");
    int screen = luaL_checkinteger(L,1);
    int side=0;
    if (argc == 2) side = luaL_checkinteger(L,2);
    gfxScreen_t my_screen;
    gfx3dSide_t eye;
    if (screen == 0) my_screen = GFX_TOP;
    else my_screen = GFX_BOTTOM;
    if (side == 0) eye = GFX_LEFT;
    else eye = GFX_RIGHT;
    sf2d_start_frame(my_screen,eye);
    return 0;
}
 
static int lua_rect(lua_State *L) {
    int argc = lua_gettop(L);
    if (argc != 5) return luaL_error(L, "wrong number of arguments");
    int x1 = luaL_checkinteger(L,1);
    int x2 = luaL_checkinteger(L,2);
    int y1 = luaL_checkinteger(L,3);
    int y2 = luaL_checkinteger(L,4);
    if (x2 < x1){
        int tmp = x2;
        x2 = x1;
        x1 = tmp;
    }
    if (y2 < y1){
        int tmp = y2;
        y2 = y1;
        y1 = tmp;
    }
    u32 color = luaL_checkinteger(L,5);
    sf2d_draw_rectangle(x1, y1, x2-x1, y2-y1, RGBA8((color >> 16) & 0xFF, (color >> 8) & 0xFF, (color) & 0xFF, (color >> 24) & 0xFF));
    return 0;
}
 
static int lua_termblend(lua_State *L) {
    int argc = lua_gettop(L);
    if (argc != 0) return luaL_error(L, "wrong number of arguments");
    sf2d_end_frame();
    return 0;
}
 

xerpi

Well-Known Member
OP
Member
Joined
Dec 25, 2011
Messages
215
Trophies
1
Age
29
Location
Tokyo
XP
1,544
Country
Spain
I just tried to blend two simple rectangles:


I see what's wrong, you have to call sf2d_swapbuffers(); once after rendering, something like this:
Code:
sf2d_start_frame(GFX_TOP, GFX_LEFT);
    //Draw top
sf2d_end_frame();
sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
    //Draw bottom
sf2d_end_frame();
sf2d_swapbuffers();
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
  • Sicklyboy @ Sicklyboy:
    I do but the optometrist I got my glasses at last year was expensive as fuck even WITH my insurance, so I'm gonna order on Zenni and see if my insurance will reimburse it. And if they won't, then, oh well, still will be cheaper anyway
  • Sicklyboy @ Sicklyboy:
    $90 for the safety glasses on Zenni, vs my daily wear glasses were >$200 after insurance
  • K3Nv3 @ K3Nv3:
    Haven't been to the eye doc in like 3 years but was pretty surprised they cut the glass in office had the in like an hour ready
  • Sicklyboy @ Sicklyboy:
    That's pretty sweet, I had to wait like a week or so for mine to be ready
  • Sicklyboy @ Sicklyboy:
    Lookin at buying another pair of regular glasses too. And maybe prescription sunglasses
  • K3Nv3 @ K3Nv3:
    Yeah most just ship off to a lab could always call around to see if new ones have in office glass cutters
  • Sicklyboy @ Sicklyboy:
    too much effort + im shy and social anxiety :( lmao
  • K3Nv3 @ K3Nv3:
    I just wear them when I drive cause I'd like to actually read signs
  • K3Nv3 @ K3Nv3:
    Think they said I'm far sighted or some bs
  • Sicklyboy @ Sicklyboy:
    My eyes aren't that bad, I need mine for driving but ever since I got my latest pair I wear them all the time when I'm home now, I never used to before
  • Sicklyboy @ Sicklyboy:
    I'm near sighted though
  • K3Nv3 @ K3Nv3:
    I feel like docs just say you're this and that for the insurance claims half the time
    +1
  • Sicklyboy @ Sicklyboy:
    But even my computer monitors, that are like 3ft away when I'm leaning back in my chair, so much easier to see now with my glasses than without
  • Sicklyboy @ Sicklyboy:
    Doc was cool though, he measured my old glasses and I wanted to try different contacts than I had had previously and he's like "hmmm I bet you're this strength and that strength" and damn dude was dead on the money
  • Sicklyboy @ Sicklyboy:
    lmao that clip
  • K3Nv3 @ K3Nv3:
    Know a guy who did laser surgery for like 2g but argued you'd never need glasses again
  • Sicklyboy @ Sicklyboy:
    laser eye surgery scares me
  • Sicklyboy @ Sicklyboy:
    The thought of any kind of surgery shit being done on my eyes gives me unbelievable amounts of dread and anxiety, and with the potential risks or side effects that laser eye surgery has, I don't think my eyes are bad enough to warrant it. I can see without my glasses - not great, but not bad either.
  • K3Nv3 @ K3Nv3:
    Yeah I feel that if it gets to the point where all I see is blurry then I might consider if
  • Skelletonike @ Skelletonike:
    Just do it like in Minority Report. Won't feel a thing.
  • Skelletonike @ Skelletonike:
    Is it the full van? If so t's suspiciously cheap.
  • Skelletonike @ Skelletonike:
    Ah, the 2000€ is only the deposit
    Skelletonike @ Skelletonike: Ah, the 2000€ is only the deposit