Help with drawing text (sprites)

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
sturatt
Posts: 46
Joined: Thu Jul 13, 2006 4:21 pm

Help with drawing text (sprites)

Post by sturatt »

This all started when i wanted to use a custom font. at first i tried to make a text drawer using graphic.h's blit alpha image to screen, but it was too slow. So i embarked on my journey to try and learn enough GU to be able to draw text on the screen.

the way im trying to do it is with a 256x256 png with all the ascii chars. I can load and find my way through that with no problem, but when it comes to the gu stuff im a bit lost. Here's what i have so far, but it doesnt seem to actually draw any text..

FontEngine.c

Code: Select all

void InitFont()
{

    FontTexture *FTex;
    FTex = readFontPNGTexture("font2.png");
    readwidths();

    
    sceGuInit();
	sceGuStart(GU_DIRECT, list);
	sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH);
	sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)0x88000,BUF_WIDTH);
	sceGuDepthBuffer((void*)0x110000,BUF_WIDTH);
	sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2));
	sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT);
	sceGuDepthRange(0xc350,0x2710);
	sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT);
	sceGuEnable(GU_SCISSOR_TEST);
	sceGuDisable(GU_DEPTH_TEST);
	sceGuShadeModel(GU_SMOOTH);
	sceGuEnable(GU_BLEND);
	sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
	sceGuEnable(GU_TEXTURE_2D);
	sceGuTexMode(GU_PSM_8888, 0, 0, 0);
	sceGuTexImage(0, 256, 256, 256, FTex->data);
	sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
	sceGuTexEnvColor(0x0);
	sceGuTexOffset(0.0f, 0.0f);
	sceGuTexScale(1.0f / 256.0f, 1.0f / 128.0f);
	sceGuTexWrap(GU_REPEAT, GU_REPEAT);
	sceGuTexFilter(GU_NEAREST, GU_NEAREST);
	sceGuFinish();
	sceGuSync(0,0);
	sceGuDisplay(GU_TRUE);
    
}

Code: Select all

void pTextScreen(int x, int y, char * text, unsigned int color)
{
    int length = strlen(text);
    Vertex *vertices = sceGuGetMemory(sizeof(Vertex) * 2 * length);

    sceGuStart(GU_DIRECT, list);

    for &#40;i = 0; i < strlen&#40;text&#41;; i += 2&#41;
    &#123;
        ascii_num = &#40;int&#41;text&#91;i&#93;;
        Y_Pos_Tex = &#40;&#40;int&#41;&#40;ascii_num / 16&#41;&#41; * 16;
        X_Pos_Tex = &#40;ascii_num % 16&#41; * 16;

        vertices&#91;i&#93;.u = &#40;float&#41;X_Pos_Tex;
        vertices&#91;i&#93;.v = &#40;float&#41;Y_Pos_Tex;
        vertices&#91;i&#93;.c = color;
        vertices&#91;i&#93;.x = &#40;float&#41;x;
        vertices&#91;i&#93;.y = &#40;float&#41;y;
        vertices&#91;i&#93;.z = 0.0f;

        vertices&#91;i + 1&#93;.u = &#40;float&#41;&#40;&#40;X_Pos_Tex + 16&#41; - &#40;16 - fontwidths&#91;ascii_num&#93;&#41;&#41;;
        vertices&#91;i + 1&#93;.v = &#40;float&#41;&#40;Y_Pos_Tex + 16&#41;;
        vertices&#91;i + 1&#93;.c = color;
        vertices&#91;i + 1&#93;.x = &#40;float&#41;&#40;&#40;x + 16&#41; - &#40;16 - fontwidths&#91;ascii_num&#93;&#41;&#41;;
        vertices&#91;i + 1&#93;.y = &#40;float&#41;&#40;y + 16&#41;;
        vertices&#91;i + 1&#93;.z = 0.0f;
        x += fontwidths&#91;ascii_num&#93;;
    &#125;

    sceGuDrawArray&#40;GU_SPRITES,
		GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_2D,
		length * 2, 0, vertices
	&#41;;

    sceGuFinish&#40;&#41;;
    sceGuSync&#40;0, 0&#41;;
&#125;

Code: Select all

FontTexture* readFontPNGTexture&#40;char *pngfile&#41;
&#123;
    FontTexture* fonttexture;
    png_uint_32 width, height;
    int bit_depth, color_type, interlace_type, x, y;
    u32 *line;

    fonttexture = &#40;FontTexture*&#41; malloc&#40;sizeof&#40;FontTexture&#41;&#41;;

    FILE *fp = fopen&#40;pngfile,"rb"&#41;;
    if &#40;!fp&#41;
    &#123;
        return NULL;
    &#125;
    //fread &#40;signature, 1, 8, fp&#41;;
    //if &#40;png_sig_cmp&#40;signature, 0, 8&#41; != 0&#41;
    //&#123;
    //    fclose&#40;fp&#41;;
    //    return NULL;
    //&#125;

    png_structp png_ptr = png_create_read_struct&#40;PNG_LIBPNG_VER_STRING, NULL, NULL, NULL&#41;;
    if &#40;!png_ptr&#41;
    &#123;
        fclose&#40;fp&#41;;
        return NULL;
    &#125;

    png_infop info_ptr = png_create_info_struct&#40;png_ptr&#41;;
    if &#40;!info_ptr&#41;
    &#123;
        png_destroy_read_struct&#40;&png_ptr, &#40;png_infopp&#41;NULL, &#40;png_infopp&#41;NULL&#41;;
        fclose&#40;fp&#41;;
        return NULL;
    &#125;

    png_infop end_info = png_create_info_struct&#40;png_ptr&#41;;
    if &#40;!end_info&#41;
    &#123;
        png_destroy_read_struct&#40;&png_ptr, &info_ptr,&#40;png_infopp&#41;NULL&#41;;
        fclose&#40;fp&#41;;
        return NULL;
    &#125;

    png_init_io&#40;png_ptr, fp&#41;;
    png_set_sig_bytes&#40;png_ptr, 0&#41;;

    png_read_info&#40;png_ptr, info_ptr&#41;;

    png_get_IHDR&#40;png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL&#41;;

    if &#40;color_type == PNG_COLOR_TYPE_PALETTE&#41;
        png_set_palette_to_rgb&#40;png_ptr&#41;;

    if &#40;color_type == PNG_COLOR_TYPE_GRAY &&
        bit_depth < 8&#41; png_set_gray_1_2_4_to_8&#40;png_ptr&#41;;

    if &#40;png_get_valid&#40;png_ptr, info_ptr,
        PNG_INFO_tRNS&#41;&#41; png_set_tRNS_to_alpha&#40;png_ptr&#41;;

    png_set_strip_16&#40;png_ptr&#41;;
    png_set_packing&#40;png_ptr&#41;;
    png_set_filler&#40;png_ptr, 0xFF, PNG_FILLER_AFTER&#41;;

    if &#40;color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA&#41;
          png_set_gray_to_rgb&#40;png_ptr&#41;;

    fonttexture->imageWidth = width;
	fonttexture->imageHeight = height;
	fonttexture->textureWidth = 512;
	fonttexture->textureHeight = 512;
	fonttexture->data = &#40;u32*&#41; memalign&#40;16, fonttexture->textureWidth * fonttexture->textureHeight * sizeof&#40;u32&#41;&#41;;
	if &#40;!fonttexture->data&#41; return NULL;

    line = &#40;u32*&#41; malloc&#40;width * 4&#41;;

	for &#40;y = 0; y < height; y++&#41; &#123;
		png_read_row&#40;png_ptr, &#40;u8*&#41; line, png_bytep_NULL&#41;;
		for &#40;x = 0; x < width; x++&#41; &#123;
			u32 color = line&#91;x&#93;;
			fonttexture->data&#91;x + y * fonttexture->textureWidth&#93; =  color;
		&#125;
	&#125;

	free&#40;line&#41;;
	png_read_end&#40;png_ptr, info_ptr&#41;;
	png_destroy_read_struct&#40;&png_ptr, &info_ptr, png_infopp_NULL&#41;;
	fclose&#40;fp&#41;;
	return fonttexture;
&#125;
and yes i realize that ^^ is almost exactly like the graphics.h loadImage but i wanted to go through with the libpng documentation and find out what it was actually doing.


FontEngine.h

Code: Select all

#include "graphics.h"


void readwidths&#40;&#41;;
void pTextScreen&#40;int x, int y, char * text, unsigned int color&#41;;
void blitAlphaImageScreen&#40;int sx, int sy, int width, int height, Image* source, int dx, int dy&#41;;
void InitFont&#40;&#41;;
void writewidths&#40;&#41;;

typedef struct
&#123;
	int textureWidth;
	int textureHeight;
	int imageWidth;
	int imageHeight;
	u32* data;
&#125; FontTexture;

typedef struct &#123;
		float u, v;
		unsigned int c;
		float x, y, z;
	&#125; Vertex;

FontTexture* readFontPNGTexture&#40;char *pngfile&#41;;
fontwidths[] is a 256 int array that has a width for each char.
and i know the readFontPNGTexture() function works because ive used it to load a png and call a function in graphics.h and it worked fine.



i realize this is a lot of nonsense to sort through to try and find someone else's error, but i really would appreciate any help. I'm really trying hard to learn this =\
sturatt
Posts: 46
Joined: Thu Jul 13, 2006 4:21 pm

Post by sturatt »

maybe it has something to do with my sceGuTexMode(GU_PSM_8888, 0, 0, 0); and with my sceGuDrawArray call. i dont actually know if my texture is 32bits, would that stop it from drawing?

also, if i changed GU_VERTEX_32BITF in the sceGuDrawArray function to GU_VERTEX_16BIT could i just use my ints instead of typecasting them as floats?
subbie
Posts: 122
Joined: Thu May 05, 2005 4:14 am

Post by subbie »

You try doing a cache flush on your verticie list before sending it off to the GU?
Post Reply