void TextEngine::renderText(float x, float y, float scaleX, float scaleY, bool baseline, const char* text) { ssize_t units; uint32_t code; // Configure buffers C3D_BufInfo* bufInfo = C3D_GetBufInfo(); BufInfo_Init(bufInfo); BufInfo_Add(bufInfo, textVtxArray, sizeof(textVertex_s), 2, 0x10); const uint8_t* p = (const uint8_t*)text; float firstX = x; u32 flags = GLYPH_POS_CALC_VTXCOORD | (baseline ? GLYPH_POS_AT_BASELINE : 0); int lastSheet = -1; do { if (!*p) break; units = decode_utf8(&code, p); if (units == -1) break; p += units; if (code == '\n') { x = firstX; y += scaleY*fontGetInfo()->lineFeed; } else if (code > 0) { int glyphIdx = fontGlyphIndexFromCodePoint(code); fontGlyphPos_s data; fontCalcGlyphPos(&data, glyphIdx, flags, scaleX, scaleY); // Bind the correct texture sheet if (data.sheetIndex != lastSheet) { lastSheet = data.sheetIndex; C3D_TexBind(0, &glyphSheets[lastSheet]); } int arrayIndex = textVtxArrayPos; if ((arrayIndex+4) >= TEXT_VTX_ARRAY_COUNT) break; // We can't render more characters // Add the vertices to the array addTextVertex(x+data.vtxcoord.left, y+data.vtxcoord.bottom, data.texcoord.left, data.texcoord.bottom); addTextVertex(x+data.vtxcoord.right, y+data.vtxcoord.bottom, data.texcoord.right, data.texcoord.bottom); addTextVertex(x+data.vtxcoord.left, y+data.vtxcoord.top, data.texcoord.left, data.texcoord.top); addTextVertex(x+data.vtxcoord.right, y+data.vtxcoord.top, data.texcoord.right, data.texcoord.top); // Draw the glyph C3D_DrawArrays(GPU_TRIANGLE_STRIP, arrayIndex, 4); x += data.xAdvance; } } while (code > 0); }
static void sceneRender(void) { // Update the uniforms C3D_FVUnifMtx4x4(GPU_GEOMETRY_SHADER, uLoc_projection, &projection); // Draw the VBO - GPU_GEOMETRY_PRIM allows the geoshader to control primitive emission C3D_DrawArrays(GPU_GEOMETRY_PRIM, 0, vertex_list_count); }
static void sceneRender(void) { // Update the uniforms C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projection); // Draw the VBO C3D_DrawArrays(GPU_TRIANGLES, 0, vertex_list_count); }
void draw(void) { // WARNING: DO **NOT** USE ANY C3D STUFF, ESPECIALLY NOTHING EFFECT RELATED! // FIXME: Enable alpha blend for 50% mixing with BG GPUCMD_AddWrite(GPUREG_BLEND_COLOR, color_blend ? 0x7F7F7F7F : 0x00000000); GPUCMD_AddWrite(GPUREG_BLEND_FUNC, (GPU_BLEND_ADD << 0) | (GPU_BLEND_ADD << 8) | (GPU_ONE_MINUS_CONSTANT_COLOR << 16) | (GPU_CONSTANT_COLOR << 20) | (GPU_ONE_MINUS_CONSTANT_ALPHA << 24) | (GPU_CONSTANT_ALPHA << 28)); GPUCMD_AddWrite(GPUREG_COLOR_OPERATION, (0x0E4 << 24) | (1 << 8)); uint32_t compare_mode = test_high ? GPU_GREATER : GPU_LESS; // Set color and depth mask + depth test { uint32_t mask_reg = (depth_mask ? 1 << 12 : 0) | ((color_mask & 0xF) << 8); GPUCMD_AddWrite(GPUREG_DEPTH_COLOR_MASK, mask_reg | ((compare_mode & 7) << 4) | (!!depth_test)); } // Set stencil mask + stencil test { uint32_t buffer_mask = stencil_mask ? 0x2A : 0x00; // Mask used for buffer write uint32_t mask = 0xFF; // Mask for comparison uint32_t ref = 0x80; GPUCMD_AddWrite(GPUREG_STENCIL_TEST, ((mask & 0xFF) << 24) | ((ref & 0xFF) << 16) | ((buffer_mask & 0xFF) << 8) | ((compare_mode & 7) << 4) | (!!stencil_test)); //0-2 unsigned, Fail operation //4-6 unsigned, Z-fail operation //8-10 unsigned, Z-pass operation GPUCMD_AddWrite(GPUREG_STENCIL_OP, (GPU_STENCIL_INVERT << 8) | (GPU_STENCIL_INVERT << 4) | (GPU_STENCIL_KEEP << 0)); } // Allow functions.. GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_READ, (depth_read_allow ? 2 : 0) | (stencil_read_allow ? 1 : 0)); GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_WRITE, (depth_write_allow ? 2 : 0) | (stencil_write_allow ? 1 : 0)); GPUCMD_AddWrite(GPUREG_COLORBUFFER_READ, color_read_allow); GPUCMD_AddWrite(GPUREG_COLORBUFFER_WRITE, color_write_allow); // Configure depth values (= will always return 0.5) bool w_buffer = true; float depth_scale = -1.0f; float depth_offset = 0.0f; #if 1 GPUCMD_AddWrite(GPUREG_DEPTHMAP_ENABLE, w_buffer ? 0x00000000 : 0x00000001); GPUCMD_AddWrite(GPUREG_DEPTHMAP_SCALE, f32tof24(depth_scale)); GPUCMD_AddWrite(GPUREG_DEPTHMAP_OFFSET, f32tof24(depth_offset)); #endif // Draw the VBO C3D_DrawArrays(GPU_TRIANGLES, 0, 3); }
void Sprite::render() { if (dirtyPixels) { dirtyPixels = false; GSPGPU_FlushDataCache(pixels, w * h * format.bytesPerPixel); C3D_SafeDisplayTransfer((u32*)pixels, GX_BUFFER_DIM(w, h), (u32*)texture.data, GX_BUFFER_DIM(w, h), TEXTURE_TRANSFER_FLAGS); gspWaitForPPF(); } C3D_TexBind(0, &texture); C3D_BufInfo *bufInfo = C3D_GetBufInfo(); BufInfo_Init(bufInfo); BufInfo_Add(bufInfo, vertices, sizeof(vertex), 2, 0x10); C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4); }
void ctrFlushBatch(void) { if (ctrNumVerts == 0) { return; } C3D_BufInfo* bufInfo = C3D_GetBufInfo(); BufInfo_Init(bufInfo); BufInfo_Add(bufInfo, &ctrVertexBuffer[ctrVertStart], sizeof(struct ctrUIVertex), 4, 0x3210); GSPGPU_FlushDataCache(&ctrVertexBuffer[ctrVertStart], sizeof(struct ctrUIVertex) * ctrNumVerts); C3D_DrawArrays(GPU_GEOMETRY_PRIM, 0, ctrNumVerts); ctrVertStart += ctrNumVerts; ctrNumVerts = 0; }