Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render to texture #89

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ add_object_library_macros(GS_CORE_OBJS ee/gs/src/gsCore.c
gsKit_vram_clear
gsKit_sync_flip
gsKit_setactive
gsKit_renderToScreen
gsKit_finish
gsKit_lock_buffer
gsKit_unlock_buffer
Expand Down Expand Up @@ -216,6 +217,7 @@ add_object_library_macros(GS_TEXTURE_OBJS ee/gs/src/gsTexture.c
gsKit_texture_send
gsKit_texture_send_inline
gsKit_texture_upload
gsKit_renderToTexture
gsKit_prim_sprite_texture_3d
gsKit_prim_sprite_striped_texture_3d
gsKit_prim_triangle_texture_3d
Expand Down Expand Up @@ -361,6 +363,7 @@ if(NOT SKIP_BUILD_EXAMPLES)
modetest
modetesthires
pixelperfect
rendertexture
texstream
textures
vsync
Expand Down
3 changes: 3 additions & 0 deletions ee/gs/include/gsCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ void gsKit_switch_context(GSGLOBAL *gsGlobal);
/// Sets Your Active Framebuffer
void gsKit_setactive(GSGLOBAL *gsGlobal);

/// Set the render target to the current screen buffer
void gsKit_renderToScreen(GSGLOBAL *gsGlobal);

/// Blocks until FINISH is triggered
void gsKit_finish(void);

Expand Down
1 change: 1 addition & 0 deletions ee/gs/include/gsTexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ void gsKit_texture_to_psm16(GSTEXTURE *Texture);
void gsKit_texture_send(u32 *mem, int width, int height, u32 tbp, u32 psm, u32 tbw, u8 clut);
void gsKit_texture_send_inline(GSGLOBAL *gsGlobal, u32 *mem, int width, int height, u32 tbp, u32 psm, u32 tbw, u8 clut);
void gsKit_texture_upload(GSGLOBAL *gsGlobal, GSTEXTURE *Texture);
void gsKit_renderToTexture(GSGLOBAL *gsGlobal, GSTEXTURE *texture);

void gsKit_prim_sprite_texture_3d(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture, float x1, float y1, int iz1, float u1, float v1,
float x2, float y2, int iz2, float u2, float v2,
Expand Down
21 changes: 21 additions & 0 deletions ee/gs/src/gsCore.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,27 @@ void gsKit_setactive(GSGLOBAL *gsGlobal)
}
#endif

#if F_gsKit_renderToScreen
void gsKit_renderToScreen(GSGLOBAL *gsGlobal)
{
u64 *p_data;
u64 *p_store;
int qsize = 1;

p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD);

if(p_store == gsGlobal->CurQueue->last_tag)
{
*p_data++ = GIF_TAG_AD(qsize);
*p_data++ = GIF_AD;
}

*p_data++ = GS_SETREG_FRAME_1( gsGlobal->ScreenBuffer[gsGlobal->ActiveBuffer & 1] / 8192,
gsGlobal->Width / 64, gsGlobal->PSM, 0 );
*p_data++ = GS_FRAME_1;
}
#endif

#if F_gsKit_finish
void gsKit_finish(void)
{
Expand Down
21 changes: 21 additions & 0 deletions ee/gs/src/gsTexture.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,27 @@ void gsKit_prim_sprite_texture_3d(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture,
}
#endif

#if F_gsKit_renderToTexture
void gsKit_renderToTexture(GSGLOBAL *gsGlobal, GSTEXTURE *texture)
{
u64 *p_data;
u64 *p_store;
int qsize = 1;

p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD);

if(p_store == gsGlobal->CurQueue->last_tag)
{
*p_data++ = GIF_TAG_AD(qsize);
*p_data++ = GIF_AD;
}

*p_data++ = GS_SETREG_FRAME_1(texture->Vram / 8192,
texture->Width / 64, texture->PSM, 0 );
*p_data++ = GS_FRAME_1;
}
#endif

#if F_gsKit_prim_sprite_striped_texture_3d
void gsKit_prim_sprite_striped_texture_3d(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture,
float x1, float y1, int iz1, float u1, float v1,
Expand Down
97 changes: 97 additions & 0 deletions examples/rendertexture/rendertexture.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// ____ ___ | / _____ _____
// | __ | |___/ | |
// |___| ___| | \ __|__ | gsKit Open Source Project.
// ----------------------------------------------------------------------
// Copyright 2004 - Chris "Neovanglist" Gilbert <Neovanglist@LainOS.org>
// Licenced under Academic Free License version 2.0
// Review gsKit README & LICENSE files for further details.
//
// renderTexture.c - Example demonstrating render to texture operation.
// First we are rendering a triangle to a texture,
// then we are rendering the texture to the screen.
//

#include <stdio.h>
#include <malloc.h>

#include <gsKit.h>
#include <dmaKit.h>
#include <gsToolkit.h>
#include <gsInline.h>
#include <gsTexture.h>

#define TEXTURE_WIDTH 256
#define TEXTURE_HEIGHT 256

int main(int argc, char *argv[])
{
GSGLOBAL *gsGlobal;
GSTEXTURE renderTexture;
uint32_t i, j, offset;
uint32_t totalVertices = 3;
uint32_t textureTotalVertices = 2;
uint64_t White = GS_SETREG_RGBAQ(0xFF, 0xFF, 0xFF, 0x00, 0x00);
gs_rgbaq color = color_to_RGBAQ(0x80, 0x80, 0x80, 0x80, 0);
u32 render_target_ptr;

gsGlobal = gsKit_init_global();

gsGlobal->PSM = GS_PSM_CT24;
gsGlobal->PSMZ = GS_PSMZ_16S;

dmaKit_init(D_CTRL_RELE_OFF, D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC,
D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF);

// Initialize the DMAC
dmaKit_chan_init(DMA_CHANNEL_GIF);

gsKit_init_screen(gsGlobal);
gsKit_mode_switch(gsGlobal, GS_ONESHOT);

renderTexture.Width = TEXTURE_WIDTH;
renderTexture.Height = TEXTURE_HEIGHT;
renderTexture.PSM = GS_PSM_CT16;
renderTexture.Mem = 0; // NOT NEEDED
renderTexture.Vram = gsKit_vram_alloc(gsGlobal, gsKit_texture_size(renderTexture.Width, renderTexture.Height, renderTexture.PSM), GSKIT_ALLOC_USERBUFFER);

gsKit_set_clamp(gsGlobal, GS_CMODE_CLAMP);

GSPRIMPOINT *verts = (GSPRIMPOINT *)malloc(sizeof(GSPRIMPOINT) * totalVertices);
verts[0].xyz2 = vertex_to_XYZ2(gsGlobal, 0, 0, 0);
verts[0].rgbaq = color_to_RGBAQ(0xFF, 0x00, 0x00, 0xFF, 0);

verts[1].xyz2 = vertex_to_XYZ2(gsGlobal, renderTexture.Width, 0, 0);
verts[1].rgbaq = color_to_RGBAQ(0x00, 0xFF, 0x00, 0xFF, 0);

verts[2].xyz2 = vertex_to_XYZ2(gsGlobal, renderTexture.Width / 2, renderTexture.Height, 0);
verts[2].rgbaq = color_to_RGBAQ(0x00, 0x00, 0xFF, 0xFF, 0);

GSPRIMUVPOINTFLAT *textureVertex = (GSPRIMUVPOINTFLAT *)malloc(sizeof(GSPRIMUVPOINTFLAT) * textureTotalVertices);
textureVertex[0].xyz2 = vertex_to_XYZ2(gsGlobal, 0, 0, 0);
textureVertex[0].uv = vertex_to_UV(&renderTexture, 0, 0);

textureVertex[1].xyz2 = vertex_to_XYZ2(gsGlobal, gsGlobal->Width, gsGlobal->Height, 0);
textureVertex[1].uv = vertex_to_UV(&renderTexture, renderTexture.Width, renderTexture.Height);

while (1)
{
gsKit_clear(gsGlobal, White);

// set render target to the texture
gsKit_renderToTexture(gsGlobal, &renderTexture);

gsKit_prim_list_triangle_gouraud_3d(gsGlobal, totalVertices, verts);

// set render target back to the screen
gsKit_renderToScreen(gsGlobal);

gskit_prim_list_sprite_texture_uv_flat_color(gsGlobal, &renderTexture, color, textureTotalVertices, textureVertex);

gsKit_queue_exec(gsGlobal);
gsKit_sync_flip(gsGlobal);
}

free(verts);

return 0;
}
Loading