Solved! See below for details
I'm trying to write a simple GPU-based text renderer that will load a png file on the SD card into a C3D_Tex and display it on the screen.
I've tried using libpng from the precompiled portlibs, and a png loader PicoPNG but both of them produce a texture like this:
Both the Tex and the png have the same dimensions (128x128). I've used the png to bin converter tool and loaded the bin as the texture and that still shows up this garbled mess. Strangely the kitten.bin from the examples does load properly so I have no clue what it would be, probably something simple .
I've had a look at sfillib and it seems to do what I want but according to the github page it is deprecated.
Any help is appreciated
Cheers
I'm trying to write a simple GPU-based text renderer that will load a png file on the SD card into a C3D_Tex and display it on the screen.
I've tried using libpng from the precompiled portlibs, and a png loader PicoPNG but both of them produce a texture like this:
Mostly copy paste from the textured cube example
Code:
std::streamsize size, size_2;
std::vector<unsigned char> buffer, image, bin_image;
std::ifstream file("sdmc:test_game/test.png");
if (file.seekg(0, std::ios::end).good()) size = file.tellg();
if (file.seekg(0, std::ios::beg).good()) size -= file.tellg();
std::ifstream file_2("sdmc:test_game/test.bin");
if (file_2.seekg(0, std::ios::end).good()) size_2 = file_2.tellg();
if (file_2.seekg(0, std::ios::beg).good()) size_2 -= file_2.tellg();
//read contents of the file into the vector
if (size > 0)
{
buffer.resize((size_t)size);
file.read((char*)(&buffer[0]), size);
}
else buffer.clear();
if (size_2 > 0)
{
bin_image.resize((size_t)size_2);
file_2.read((char*)(&bin_image[0]), size_2);
}
else buffer.clear();
unsigned long w, h;
int error = decodePNG(image, w, h, buffer.empty() ? 0 : &buffer[0], (unsigned long)buffer.size());
if (error != 0) {
char info[30];
sprintf(info, "error:%i", error);
util::debug_print(info);
}
/* Upload to shader */
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
// Initialize the render target
C3D_RenderTarget* target = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
C3D_RenderTargetSetClear(target, C3D_CLEAR_ALL, CLEAR_COLOR, 0);
C3D_RenderTargetSetOutput(target, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
static const util::vertex vertex_list[] =
{
// First face (PZ)
// First triangle
{ { -0.5f, -0.5f, +0.5f },{ 0.0f, 0.0f },{ 0.0f, 0.0f, +1.0f } },
{ { +0.5f, -0.5f, +0.5f },{ 1.0f, 0.0f },{ 0.0f, 0.0f, +1.0f } },
{ { +0.5f, +0.5f, +0.5f },{ 1.0f, 1.0f },{ 0.0f, 0.0f, +1.0f } },
// Second triangle
{ { +0.5f, +0.5f, +0.5f },{ 1.0f, 1.0f },{ 0.0f, 0.0f, +1.0f } },
{ { -0.5f, +0.5f, +0.5f },{ 0.0f, 1.0f },{ 0.0f, 0.0f, +1.0f } },
{ { -0.5f, -0.5f, +0.5f },{ 0.0f, 0.0f },{ 0.0f, 0.0f, +1.0f } }
};
DVLB_s* vshader_dvlb;
shaderProgram_s program;
int uLoc_projection, uLoc_modelView;
int uLoc_lightVec, uLoc_lightHalfVec, uLoc_lightClr, uLoc_material;
C3D_Mtx projection;
C3D_Mtx material =
{
{
{ { 0.0f, 0.2f, 0.2f, 0.2f } }, // Ambient
{ { 0.0f, 0.4f, 0.4f, 0.4f } }, // Diffuse
{ { 0.0f, 0.8f, 0.8f, 0.8f } }, // Specular
{ { 1.0f, 0.0f, 0.0f, 0.0f } }, // Emission
}
};
// Load the vertex shader, create a shader program and bind it
vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size);
shaderProgramInit(&program);
shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]);
C3D_BindProgram(&program);
uLoc_projection = shaderInstanceGetUniformLocation(program.vertexShader, "projection");
uLoc_modelView = shaderInstanceGetUniformLocation(program.vertexShader, "modelView");
uLoc_lightVec = shaderInstanceGetUniformLocation(program.vertexShader, "lightVec");
uLoc_lightHalfVec = shaderInstanceGetUniformLocation(program.vertexShader, "lightHalfVec");
uLoc_lightClr = shaderInstanceGetUniformLocation(program.vertexShader, "lightClr");
uLoc_material = shaderInstanceGetUniformLocation(program.vertexShader, "material");
// Configure attributes for use with the vertex shader
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
AttrInfo_Init(attrInfo);
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // v0=position
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2); // v1=texcoord
AttrInfo_AddLoader(attrInfo, 2, GPU_FLOAT, 3); // v2=normal
// Compute the projection matrix
Mtx_PerspTilt(&projection, C3D_AngleFromDegrees(80.0f), C3D_AspectRatioTop, 0.01f, 1000.0f, false);
// Create the VBO (vertex buffer object)
void* vbo_data = linearAlloc(sizeof(vertex_list));
memcpy(vbo_data, vertex_list, sizeof(vertex_list));
// Configure buffers
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, vbo_data, sizeof(util::vertex), 3, 0x210);
C3D_Tex png_texture;
// Load the texture and bind it to the first texture unit
C3D_TexInit(&png_texture, 128, 128, GPU_TEXCOLOR::GPU_RGBA8);
C3D_TexUpload(&png_texture, &image[0]);
C3D_TexSetFilter(&png_texture, GPU_LINEAR, GPU_NEAREST);
C3D_TexBind(0, &png_texture);
// Configure the first fragment shading substage to blend the texture color with
// the vertex color (calculated by the vertex shader using a lighting algorithm)
// See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0);
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
while (true) {
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C3D_FrameDrawOn(target);
C3D_Mtx modelView;
Mtx_Identity(&modelView);
Mtx_Translate(&modelView, 0.0, 0.0, -2.0, true);
// Update the uniforms
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projection);
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_modelView, &modelView);
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_material, &material);
C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightVec, 0.0f, 0.0f, -1.0f, 0.0f);
C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightHalfVec, 0.0f, 0.0f, -1.0f, 0.0f);
C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightClr, 1.0f, 1.0f, 1.0f, 1.0f);
// Draw the VBO
C3D_DrawArrays(GPU_TRIANGLES, 0, sizeof(vertex_list) / sizeof(util::vertex));
C3D_FrameEnd(0);
}
Both the Tex and the png have the same dimensions (128x128). I've used the png to bin converter tool and loaded the bin as the texture and that still shows up this garbled mess. Strangely the kitten.bin from the examples does load properly so I have no clue what it would be, probably something simple .
I've had a look at sfillib and it seems to do what I want but according to the github page it is deprecated.
Any help is appreciated
Cheers
Last edited by PrintHello,