Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Pp2d 3DS: Difference between revisions

From GameBrew
No edit summary
No edit summary
Line 2: Line 2:
|title=pp2d
|title=pp2d
|image=pp2d.png
|image=pp2d.png
|description=Graphic rendering helper to use with libctru and citro3D.�https://discord.gg/bGKEyfY
|description=Graphic rendering helper to use with libctru and citro3D.
|author=wrathsoffire76
|author=wrathsoffire76
|lastupdated=2018/02/26
|lastupdated=2018/02/26
|type=PC Utilities
|type=PC Utilities
|version=2018
|version=2018
|license=GPLv3
|license=GPL-3.0
|download=https://dlhb.gamebrew.org/3dshomebrew/pp2d-master.zip
|download=https://dlhb.gamebrew.org/3dshomebrews/pp2d3ds.7z Source Only
|website=https://github.com/wrathsoffire76/pp2d
|website=https://github.com/wrathsoffire76/pp2d
|source=https://github.com/wrathsoffire76/pp2d
|source=https://github.com/wrathsoffire76/pp2d
}}
}}
<youtube>Bh-2YzZU-eU</youtube>
{{Obsolete}}


== pp2d ==
pp2d, also known as Plug & Play 2D, is an unofficial graphics rendering helper to use with libctru and citro3D.
Plug &amp; Play 2D is an unofficial graphics rendering helper to use with libctru and citro3D.


== Notice ==
'''Note:''' Use citro2d instead. This code is not supported by the devkitPro team and may not work if there are breaking changes in the libraries on which pp2d depends.
This repository was made private due to pp2d not working as good as it should work and not using the hardware resources with parsimony. I recently made some intense optimization work, and pp2d uses hardware resources nowadays more appropriately than in the past.


For this reason, I felt this repository is ready to be public again. Anyways, this code is not supported by the devkitPro team and may stop working if there are breaking changes in the libraries on which pp2d depends. Use citro2d when (and if) it becomes a thing.
==User guide==
== Using pp2d ==
===Using pp2d===
In order to initialize pp2d's working variables, you'll need to call <code>void pp2d_init(void);</code>. Note that this already calls <code>gfxInitDefault();</code> and <code>C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);</code> by default. <code>void pp2d_exit(void);</code> frees all the pp2d variables instead. Here are functions you're required to actually render things to the screens.
In order to initialize pp2d's working variables, you'll need to call <code>void pp2d_init(void);</code>. Note that this already calls <code>gfxInitDefault();</code> and <code>C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);</code> by default. <code>void pp2d_exit(void);</code> frees all the pp2d variables instead. Here are functions you're required to actually render things to the screens.
* <code>void pp2d_frame_begin(gfxScreen_t target, gfx3dSide_t side);</code> begins a frame.
* <code>void pp2d_frame_begin(gfxScreen_t target, gfx3dSide_t side);</code> begins a frame.
* <code>void pp2d_frame_draw_on(gfxScreen_t target, gfx3dSide_t side);</code> changes the screen target.
* <code>void pp2d_frame_draw_on(gfxScreen_t target, gfx3dSide_t side);</code> changes the screen target.
Line 31: Line 30:
* <code>void pp2d_texture_position(int x, int y);</code>
* <code>void pp2d_texture_position(int x, int y);</code>
* <code>void pp2d_texture_rotate(float angle);</code>
* <code>void pp2d_texture_rotate(float angle);</code>
* <code>void pp2d_texture_scale(float scaleX, float scaleY);</code> You can use none of them or each of them, depeding what you need to do. After that, using <code>void pp2d_texture_queue(void);</code> will add the vertices into the linear buffer the GPU will use to render them. If you're an advanced user and know what you're doing, you can use <code>void pp2d_draw_arrays(void);</code> once you filled the linear memory with the vertices you need to draw from a single spritesheet. You can also avoid calling this though, it will be handled automatically from pp2d, in particular when calling <code>void pp2d_frame_draw_on(gfxScreen_t target, gfx3dSide_t side);</code> and <code>void pp2d_frame_end(void);</code>. Check the [https://github.com/BernardoGiordano/pp2d/blob/master/example/source/main.c example] for more details.  
* <code>void pp2d_texture_scale(float scaleX, float scaleY);</code> You can use none of them or each of them, depending what you need to do. After that, using <code>void pp2d_texture_queue(void);</code> will add the vertices into the linear buffer the GPU will use to render them. If you're an advanced user and know what you're doing, you can use <code>void pp2d_draw_arrays(void);</code> once you filled the linear memory with the vertices you need to draw from a single spritesheet. You can also avoid calling this though, it will be handled automatically from pp2d, in particular when calling <code>void pp2d_frame_draw_on(gfxScreen_t target, gfx3dSide_t side);</code> and <code>void pp2d_frame_end(void);</code>. Check the [https://github.com/BernardoGiordano/pp2d/blob/master/example/source/main.c example] for more details.
 
===Past issues===
pp2d used to misuse the command buffer, the CPU and the GPU. Here are some details:
 
'''Texture binding:'''
 
Texture binding was performed each time pp2d_texture_draw() was called. This has been solved by storing the last used spritesheet's infos inside pp2d, in order to bind a new texture only when it's necessary. This doesn't solve texture binding issues alone. A behaviour that was encouraged in the old pp2d was to have multiple single texture loaded in memory, rather than a single spritesheet containing them all.
 
Relying on a single spritesheet to contain all the textures (or at least all the static ones) will increase performance and reduce CPU usage, because you're not going to bind different textures every time you want to draw a different sprite on screen. To use the new pp2d in the best way, you'll be required to write your own spritesheet handler. You can find a really simple and barebone example of spritesheet handler in the example. More advanced examples will come in the future. In order to discourage having multiple textures rather than just one spritesheet, PP2D_MAX_TEXTURES's default value is 1. You can change this by sending a different value through the Makefile if you need more, though.


== Which issues had pp2d in the past? ==
'''Texture blending:'''
pp2d used to really misuse the command buffer, the CPU and the GPU. Let's see in details:


=== Texture binding ===
Same as texture binding, texture blending was performed each time you used pp2d_texture_draw(), making you waste lots of power. Now, pp2d only changes blend parameters when you use a different blend color than the past one. This also applies to the text color. It was changed each time a function from the pp2d_draw_text family was called, instead it's now called only the first time you start rendering text after you rendered something different, like a sprite or a rectangle.
Texture binding was performed ''each time'' <code>pp2d_texture_draw()</code> was called. This has been solved by storing the last used spritesheet's infos inside pp2d, in order to bind a new texture ''only when it's necessary''. '''This doesn't solve texture binding issues alone'''. A behaviour that was encouraged in the old pp2d was to have multiple single texture loaded in memory, rather than a single spritesheet containing them all.


Relying on a single spritesheet to contain all the textures (or at least all the static ones) will increase performance and reduce CPU usage, because you're not going to bind different textures every time you want to draw a different sprite on screen. To use the new pp2d in the best way, you'll be required to write your own spritesheet handler. You can find a really simple and barebone example of spritesheet handler in the example. More advanced examples will come in the future. In order to discourage having multiple textures rather than just one spritesheet, <code>PP2D_MAX_TEXTURES</code>'s default value is <code>1</code>. You can change this by sending a different value through the Makefile if you need more, though.
// blending
=== Texture blending ===
Same as texture binding, texture blending was performed each time you used <code>pp2d_texture_draw()</code>, making you waste lots of power. Now, pp2d only changes blend parameters when you use a different blend color than the past one. This also applies to the text color. It was changed each time a function from the <code>pp2d_draw_text</code> family was called, instead it's now called only the first time you start rendering text after you rendered something different, like a sprite or a rectangle.
<pre>// blending
if (changeColor)
if (changeColor)
{
{
Line 48: Line 51:
...
...
}
}
</pre>
 
=== Texture rendering ===
'''Texture rendering:'''
In the old pp2d, <code>C3D_DrawArrays</code> was used in each <code>pp2d_texture_draw()</code> call because the last used spritesheet wasn't stored somewhere into pp2d, causing the command buffer to be misused. Now, when pp2d recognizes you just need to render from the same spritesheet, it will render everything at once before binding a new texture.
 
=== Texture tiling ===
In the old pp2d, C3D_DrawArrays was used in each pp2d_texture_draw() call because the last used spritesheet wasn't stored somewhere into pp2d, causing the command buffer to be misused. Now, when pp2d recognizes you just need to render from the same spritesheet, it will render everything at once before binding a new texture.
 
'''Texture tiling:'''
 
In order to convert textures to the proper tiled format, the old pp2d used some weird operations relying on the CPU. It now uses the proper citro3D functions to do that.
In order to convert textures to the proper tiled format, the old pp2d used some weird operations relying on the CPU. It now uses the proper citro3D functions to do that.
== Known issues ==
 
The new pp2d has some minor problems that will hopefully be fixed soon. In case you want to help, Pull Requests are highly appreciated.
==Media==
* The white color <code>RGBA8(0xFF, 0xFF, 0xFF, 0xFF)</code> causes blending issues. This could be fixed by changing the blending portions to modulate the colors better. There are simple workarounds though, like using <code>RGBA8(0xFE, 0xFE, 0xFE, 0xFF)</code> as white color.
'''PP2D Screen Transition Test''' ([https://www.youtube.com/watch?v=Bh-2YzZU-eU blujay]) <br>
* Texture rotation is actually done CPU-side. This could waste some CPU usage in case you really need to rotate multiple sprites per frame.
<youtube>Bh-2YzZU-eU</youtube>
* Report other issues in case you find more. You can receive real-time support by joining PKSM's Discord server. [https://discord.gg/bGKEyfY [[File:https://discordapp.com/api/guilds/278222834633801728/widget.png?style=banner3&time-|Discord]]]
 
== License ==
==Known issues==
pp2d is licensed under the [https://github.com/BernardoGiordano/pp2d/blob/master/LICENSE GPLv3 License].
The white color <code>RGBA8(0xFF, 0xFF, 0xFF, 0xFF)</code> causes blending issues. This could be fixed by changing the blending portions to modulate the colors better. There are simple workarounds though, like using <code>RGBA8(0xFE, 0xFE, 0xFE, 0xFF)</code> as white color.
== Credits ==
 
* all the contributors for [https://github.com/fincs/citro3d citro3d]
Texture rotation is actually done CPU-side. This could waste some CPU usage in case you really need to rotate multiple sprites per frame.
* all the contributors for [https://github.com/smealum/ctrulib libctru] You can [https://www.patreon.com/bernardogiordano support me] if you like my work.
 
==Credits==
* All the contributors for [https://github.com/fincs/citro3d citro3d]
* All the contributors for [https://github.com/smealum/ctrulib libctru].
 
[[Category:3DS homebrew applications]]
[[Category:PC utilities for 3DS homebrew]]

Revision as of 01:33, 10 March 2022

pp2d
File:Pp2d.png
General
Authorwrathsoffire76
TypePC Utilities
Version2018
LicenseGPL-3.0
Last Updated2018/02/26
Links
Source Only Download
Website
Source

pp2d, also known as Plug & Play 2D, is an unofficial graphics rendering helper to use with libctru and citro3D.

Note: Use citro2d instead. This code is not supported by the devkitPro team and may not work if there are breaking changes in the libraries on which pp2d depends.

User guide

Using pp2d

In order to initialize pp2d's working variables, you'll need to call void pp2d_init(void);. Note that this already calls gfxInitDefault(); and C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); by default. void pp2d_exit(void); frees all the pp2d variables instead. Here are functions you're required to actually render things to the screens.

  • void pp2d_frame_begin(gfxScreen_t target, gfx3dSide_t side); begins a frame.
  • void pp2d_frame_draw_on(gfxScreen_t target, gfx3dSide_t side); changes the screen target.
  • void pp2d_frame_end(void); ends a frame. In order to start rendering a texture, you'll need to use void pp2d_texture_select_part(size_t id, int x, int y, int xbegin, int ybegin, int width, int height);. Note that this discourages using separate textures. After you used the said function, you can use the following functions in any order:
  • void pp2d_texture_blend(u32 color);
  • void pp2d_texture_depth(float depth);
  • void pp2d_texture_flip(flipType_t fliptype);
  • void pp2d_texture_position(int x, int y);
  • void pp2d_texture_rotate(float angle);
  • void pp2d_texture_scale(float scaleX, float scaleY); You can use none of them or each of them, depending what you need to do. After that, using void pp2d_texture_queue(void); will add the vertices into the linear buffer the GPU will use to render them. If you're an advanced user and know what you're doing, you can use void pp2d_draw_arrays(void); once you filled the linear memory with the vertices you need to draw from a single spritesheet. You can also avoid calling this though, it will be handled automatically from pp2d, in particular when calling void pp2d_frame_draw_on(gfxScreen_t target, gfx3dSide_t side); and void pp2d_frame_end(void);. Check the example for more details.

Past issues

pp2d used to misuse the command buffer, the CPU and the GPU. Here are some details:

Texture binding:

Texture binding was performed each time pp2d_texture_draw() was called. This has been solved by storing the last used spritesheet's infos inside pp2d, in order to bind a new texture only when it's necessary. This doesn't solve texture binding issues alone. A behaviour that was encouraged in the old pp2d was to have multiple single texture loaded in memory, rather than a single spritesheet containing them all.

Relying on a single spritesheet to contain all the textures (or at least all the static ones) will increase performance and reduce CPU usage, because you're not going to bind different textures every time you want to draw a different sprite on screen. To use the new pp2d in the best way, you'll be required to write your own spritesheet handler. You can find a really simple and barebone example of spritesheet handler in the example. More advanced examples will come in the future. In order to discourage having multiple textures rather than just one spritesheet, PP2D_MAX_TEXTURES's default value is 1. You can change this by sending a different value through the Makefile if you need more, though.

Texture blending:

Same as texture binding, texture blending was performed each time you used pp2d_texture_draw(), making you waste lots of power. Now, pp2d only changes blend parameters when you use a different blend color than the past one. This also applies to the text color. It was changed each time a function from the pp2d_draw_text family was called, instead it's now called only the first time you start rendering text after you rendered something different, like a sprite or a rectangle.

// blending if (changeColor) { prevColor = pp2dBuffer.color; ... }

Texture rendering:

In the old pp2d, C3D_DrawArrays was used in each pp2d_texture_draw() call because the last used spritesheet wasn't stored somewhere into pp2d, causing the command buffer to be misused. Now, when pp2d recognizes you just need to render from the same spritesheet, it will render everything at once before binding a new texture.

Texture tiling:

In order to convert textures to the proper tiled format, the old pp2d used some weird operations relying on the CPU. It now uses the proper citro3D functions to do that.

Media

PP2D Screen Transition Test (blujay)

Known issues

The white color RGBA8(0xFF, 0xFF, 0xFF, 0xFF) causes blending issues. This could be fixed by changing the blending portions to modulate the colors better. There are simple workarounds though, like using RGBA8(0xFE, 0xFE, 0xFE, 0xFF) as white color.

Texture rotation is actually done CPU-side. This could waste some CPU usage in case you really need to rotate multiple sprites per frame.

Credits

Advertising: