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

  • Thread starter Thread starter xerpi
  • Start date Start date
  • Views Views 97,215
  • Replies Replies 501
  • Likes Likes 32
Texture palettes are not supported. It think it is an OpenGL ES thing - not in the spec. Very annoying. Seems like an odd choice for memory constrained environments.
 
  • Like
Reactions: ashinnblunts
I haven't really looked into this lib yet but...

Would this lib be faster than doing the following?
Code:
    // get screen buffer
    u8* bufAdr=gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);

    int slider = 22- ((CONFIG_3D_SLIDERSTATE)*22); // scroll screen using 3d slider!
 
    for(int y=slider; y<240+slider; y++){
        for(int x=0; x<384; x++){
            int r = palette_red[bufmem[x+512*y]];
            int g = palette_green[bufmem[x+512*y]];
            int b = palette_blue[bufmem[x+512*y]];
            drawPixel(x+8,y-slider,r,g,b,bufAdr);
        }
    }

(the slider part isn't really important at all)

Is there for example an 8bit paletted texture format or something?
May I ask why you're using 3 different buffers for red, green, and blue CLUTs? You're potentially performing 6 memory accesses per iteration, 3 of which seem like they're located arbitrarily in memory. Since the texture indices returned from bufmem most likely doesn't increase linearly, you'll access the palettes randomly and get a lot of cache misses. Why not pack the red, green, and blue into a single integer then unpack them using shifts and bit masks? This way you'll only have to take a cache miss once per iteration instead of 3 or more. Furthermore, if you're rarely updating the source image/indices, then it would be worth storing the indexed texture data into a buffer then just linearly accessing the color buffer so you won't have to perform the index lookup every time. You could then just feed this color buffer into sf2dlib and render it as a textured quad.
 
So I was just trying to install libsf2d and I ran into this error:
Code:
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:5:18: fatal error: sf2d.h: No such file or directory
 #include <sf2d.h>
  ^
compilation terminated.
make[1]: *** [main.o] Error 1
make: *** [build] Error 2
Whale:Keys AgentMoose$

I ran "make" on the libsf2d directory to get the sf2d.h file and the libsf2d.a file and put them into the ctrulib/lib/ and ctrulib/include directories, so why isn't it reading the libsf2d files when I run "make" on my own homebrew?
 
Well, now I am getting even more errors, but at least it's reading the #include <sf2d.h> part.
Code:
linking Keys.elf
main.o: In function `main':
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:8: undefined reference to `sf2d_init'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:21: undefined reference to `sf2d_start_frame'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:24: undefined reference to `sf2d_end_frame'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:26: undefined reference to `sf2d_start_frame'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:27: undefined reference to `sf2d_draw_rectangle'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:28: undefined reference to `sf2d_end_frame'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:30: undefined reference to `sf2d_swapbuffers'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:33: undefined reference to `sf2d_fini'
collect2: error: ld returned 1 exit status
make[1]: *** [/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/Keys.elf] Error 1
make: *** [build] Error 2
Whale:Keys AgentMoose$
 
Well, now I am getting even more errors, but at least it's reading the #include <sf2d.h> part.
Code:
linking Keys.elf
main.o: In function `main':
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:8: undefined reference to `sf2d_init'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:21: undefined reference to `sf2d_start_frame'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:24: undefined reference to `sf2d_end_frame'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:26: undefined reference to `sf2d_start_frame'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:27: undefined reference to `sf2d_draw_rectangle'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:28: undefined reference to `sf2d_end_frame'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:30: undefined reference to `sf2d_swapbuffers'
/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/source/main.c:33: undefined reference to `sf2d_fini'
collect2: error: ld returned 1 exit status
make[1]: *** [/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/Keys.elf] Error 1
make: *** [build] Error 2
Whale:Keys AgentMoose$

Did you add "-lsf2d" (without the quotes) to the LIBS part of your makefile?
 
Just did, now I am getting a whole bunch of errors for a different reason. :P
Code:
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d.o): In function `reset_gpu_apt_resume':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:291: undefined reference to `GPU_Reset'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:292: undefined reference to `shaderProgramUse'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:300: undefined reference to `GPUCMD_Finalize'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:301: undefined reference to `GPUCMD_FlushAndRun'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d.o): In function `sf2d_init_advanced':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:52: undefined reference to `vramMemAlign'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:53: undefined reference to `vramMemAlign'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:54: undefined reference to `linearAlloc'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:55: undefined reference to `linearAlloc'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:59: undefined reference to `gfxInitDefault'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:60: undefined reference to `GPU_Init'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:61: undefined reference to `gfxSet3D'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:62: undefined reference to `GPU_Reset'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:65: undefined reference to `DVLB_ParseFile'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:66: undefined reference to `shaderProgramInit'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:67: undefined reference to `shaderProgramSetVsh'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:70: undefined reference to `shaderInstanceGetUniformLocation'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:72: undefined reference to `shaderProgramUse'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:89: undefined reference to `GPUCMD_Finalize'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:90: undefined reference to `GPUCMD_FlushAndRun'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d.o): In function `sf2d_fini':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:106: undefined reference to `gfxExit'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:107: undefined reference to `shaderProgramFree'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:108: undefined reference to `DVLB_Free'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:110: undefined reference to `linearFree'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:111: undefined reference to `linearFree'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:112: undefined reference to `vramFree'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:113: undefined reference to `vramFree'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d.o): In function `sf2d_set_3D':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:122: undefined reference to `gfxSet3D'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d.o): In function `sf2d_start_frame':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:128: undefined reference to `GPUCMD_SetBufferOffset'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:147: undefined reference to `GPU_SetViewport'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:151: undefined reference to `GPU_DepthMap'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:152: undefined reference to `GPU_SetFaceCulling'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:153: undefined reference to `GPU_SetStencilTest'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:154: undefined reference to `GPU_SetStencilOp'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:155: undefined reference to `GPU_SetBlendingColor'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:156: undefined reference to `GPU_SetDepthTestAndWriteMask'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:157: undefined reference to `GPUCMD_Add'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:158: undefined reference to `GPUCMD_Add'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:160: undefined reference to `GPU_SetAlphaBlending'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:167: undefined reference to `GPU_SetAlphaTest'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d.o): In function `sf2d_end_frame':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:178: undefined reference to `GPU_FinishDrawing'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:179: undefined reference to `GPUCMD_Finalize'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:180: undefined reference to `GPUCMD_FlushAndRun'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:190: undefined reference to `gfxGetFramebuffer'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:189: undefined reference to `GX_SetDisplayTransfer'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:196: undefined reference to `GX_SetMemoryFill'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:186: undefined reference to `gfxGetFramebuffer'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:185: undefined reference to `GX_SetDisplayTransfer'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d.o): In function `sf2d_swapbuffers':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:203: undefined reference to `gfxSwapBuffersGpu'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d.o): In function `sf2d_set_scissor_test':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d.c:268: undefined reference to `GPU_SetScissorTest'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d_draw.o): In function `sf2d_draw_line':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:25: undefined reference to `GPU_SetTexEnv'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:35: undefined reference to `GPU_SetAttributeBuffers'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:47: undefined reference to `GPU_DrawArray'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d_draw.o): In function `sf2d_draw_rectangle':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:70: undefined reference to `GPU_SetTexEnv'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:80: undefined reference to `GPU_SetAttributeBuffers'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:92: undefined reference to `GPU_DrawArray'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d_draw.o): In function `sf2d_draw_rectangle_rotate':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:128: undefined reference to `GPU_SetTexEnv'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:138: undefined reference to `GPU_SetAttributeBuffers'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:150: undefined reference to `GPU_DrawArray'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d_draw.o): In function `sf2d_draw_fill_circle':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:189: undefined reference to `GPU_SetTexEnv'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:199: undefined reference to `GPU_SetAttributeBuffers'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_draw.c:211: undefined reference to `GPU_DrawArray'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d_private.o): In function `GPU_SetDummyTexEnv':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_private.c:8: undefined reference to `GPU_SetTexEnv'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d_private.o): In function `matrix_gpu_set_uniform':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_private.c:36: undefined reference to `GPU_SetFloatUniform'
/Users/AgentMoose/3DS/devkitPro/libctru/lib/libsf2d.a(sf2d_private.o): In function `matrix_set_z_rotation':
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_private.c:68: undefined reference to `cosf'
/Users/AgentMoose/3DS/devkitPro/ctrulib/libsf2d/source/sf2d_private.c:69: undefined reference to `sinf'
collect2: error: ld returned 1 exit status
make[1]: *** [/Users/AgentMoose/3DS/Ninjhax/MyHomebrew/Ninjhax-2/Keys/Keys.elf] Error 1
make: *** [build] Error 2
Whale:Keys AgentMoose$
 
Change the order to
Code:
LIBS  := -lsf2d -lctru -lm
The order matters because libsf2d depends on libctru so libsf2d must precede libctru in the library list.
Awesome! Got it working! Thanks :D

EDIT:

So I am trying to recreate my piano application (it doesn't work with ninjhax 2):
https://gbatemp.net/threads/3ds-piano-homebrew.377088/

Well, when I do it all that I see is rendering is the first white rectangle. How am I supposed to have it overlap other rectangles to make it look like my original homebrew?
Code:
#include <string.h>
#include <sf2d.h>
#include <stdlib.h>
#include <stdio.h>
#include <3ds.h>

int main() {
  sf2d_init();
   
  // Main loop
  while (aptMainLoop())
  {
  hidScanInput();
  gspWaitForVBlank();
   
  u32 kDown = hidKeysDown();
  u32 kUp = hidKeysUp();
   
  if (kDown & KEY_START) break;
   
  sf2d_start_frame(GFX_TOP, GFX_LEFT);
  printf("Piano v1");
  printf("Created by Agent Moose/Metroynome");
  sf2d_end_frame();
   
  sf2d_start_frame(GFX_BOTTOM, GFX_LEFT);
   
  sf2d_draw_rectangle(0, 0, 320, 240, RGBA8(0xFF, 0xFF, 0xFF, 0xFF));
   
  sf2d_draw_rectangle(25, 0, 30, 100, RGBA8(0x00, 0x00, 0x00, 0x00));
  sf2d_draw_rectangle(65, 0, 30, 100, RGBA8(0x00, 0x00, 0x00, 0x00));
  sf2d_draw_rectangle(145, 0, 30, 100, RGBA8(0x00, 0x00, 0x00, 0x00));
  sf2d_draw_rectangle(185, 0, 30, 100, RGBA8(0x00, 0x00, 0x00, 0x00));
  sf2d_draw_rectangle(225, 0, 30, 100, RGBA8(0x00, 0x00, 0x00, 0x00));
   
  sf2d_draw_line(39, 0, 40, 240, RGBA8(0x00, 0x00, 0x00, 0x00));
  sf2d_draw_line(79, 0, 80, 240, RGBA8(0x00, 0x00, 0x00, 0x00));
  sf2d_draw_line(119, 0, 120, 240, RGBA8(0x00, 0x00, 0x00, 0x00));
  sf2d_draw_line(159, 0, 160, 240, RGBA8(0x00, 0x00, 0x00, 0x00));
  sf2d_draw_line(199, 0, 200, 240, RGBA8(0x00, 0x00, 0x00, 0x00));
  sf2d_draw_line(239, 0, 240, 240, RGBA8(0x00, 0x00, 0x00, 0x00));
  sf2d_draw_line(279, 0, 280, 240, RGBA8(0x00, 0x00, 0x00, 0x00));
   
   
//  sf2d_draw_rectangle(40, 0, 39, 240, RGBA8(0xFF, 0xFF, 0xFF, 0xFF));
//  sf2d_draw_rectangle(80, 0, 39, 240, RGBA8(0xFF, 0xFF, 0xFF, 0xFF));
//  sf2d_draw_rectangle(120, 0, 39, 240, RGBA8(0xFF, 0xFF, 0xFF, 0xFF));
//  sf2d_draw_rectangle(160, 0, 39, 240, RGBA8(0xFF, 0xFF, 0xFF, 0xFF));
//  sf2d_draw_rectangle(200, 0, 39, 240, RGBA8(0xFF, 0xFF, 0xFF, 0xFF));
//  sf2d_draw_rectangle(240, 0, 39, 240, RGBA8(0xFF, 0xFF, 0xFF, 0xFF));
//  sf2d_draw_rectangle(280, 0, 39, 240, RGBA8(0xFF, 0xFF, 0xFF, 0xFF));
  sf2d_end_frame();
  sf2d_swapbuffers();
   
  }
  sf2d_fini();
  return 0;
}
 
Last edited by Agent Moose,
This might be a bit late, but I finally got it to install, after I tried it to install it the first time around 3 months ago xD
However, if anyone has the problem that nihstro-assemble is missing, like me, download the binarys from 4dsdev and play them in the devkitARM/bin folder :D

Also, thanks of this, I now created this :D :
wip1.png

(Still WIP, in this picture you can see randomly generated terrain, with my REALLY crappy generator)
 
Last edited by josamilu,
Fair enough. Then it shouldn't really be a huge problem - you just need to have cmake and boost installed. In particular, running "cmake . && make" should give you a binary, assuming cmake didn't output any errors (which would likely stem from missing dependencies).
 

Site & Scene News

Popular threads in this forum