コード例 #1
0
ファイル: text.c プロジェクト: te-bachi/cgr
void SDL_GL_RenderText(char *text, TTF_Font *font, SDL_Color color, SDL_Rect *location) {
    SDL_Surface *initial;
    SDL_Surface *intermediary;
    int w,h;
    GLuint texture;
    
    /* Use SDL_TTF to render our text */
    initial = TTF_RenderText_Blended(font, text, color);
    
    /* Convert the rendered text to a known format */
    w = nextpoweroftwo(initial->w);
    h = nextpoweroftwo(initial->h);
    
    intermediary = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);

    SDL_BlitSurface(initial, 0, intermediary, 0);
    
    /* Tell GL about our new texture */
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_BGRA, 
            GL_UNSIGNED_BYTE, intermediary->pixels );
    
    /* GL_NEAREST looks horrible, if scaled... */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   

    /* prepare to render our texture */
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glColor3f(1.0f, 1.0f, 1.0f);
    
    /* Draw a quad at location */
    glBegin(GL_QUADS);
        /* Recall that the origin is in the lower-left corner
           That is why the TexCoords specify different corners
           than the Vertex coors seem to. */
        glTexCoord2f(0.0f, 1.0f); 
            glVertex2f(location->x    , location->y);
        glTexCoord2f(1.0f, 1.0f); 
            glVertex2f(location->x + w, location->y);
        glTexCoord2f(1.0f, 0.0f); 
            glVertex2f(location->x + w, location->y + h);
        glTexCoord2f(0.0f, 0.0f); 
            glVertex2f(location->x    , location->y + h);
    glEnd();
    
    /* Bad things happen if we delete the texture before it finishes */
    glFinish();
    
    /* return the deltas in the unused w,h part of the rect */
    location->w = initial->w;
    location->h = initial->h;
    
    /* Clean up */
    SDL_FreeSurface(initial);
    SDL_FreeSurface(intermediary);
    glDeleteTextures(1, &texture);
}
コード例 #2
0
ファイル: sdl_gl.cpp プロジェクト: czajkovsky/superarkanoid
GLuint SDL_GL_MakeTextTexture(const char *text, TTF_Font *font, SDL_Color color, SDL_Rect &offset) {
	GLuint texture;
	glGenTextures(1, &texture);
	glLoadIdentity();
	SDL_Surface *initial;
	SDL_Surface *intermediary;
	
	initial = TTF_RenderText_Blended(font, text, color);
	SDL_SetAlpha(initial, 0, 0);
	
	offset.w = nextpoweroftwo(initial->w);
	offset.h = nextpoweroftwo(initial->h);
	
	intermediary = SDL_CreateRGBSurface(SDL_SWSURFACE, offset.w, offset.h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);

	SDL_BlitSurface(initial, 0, intermediary, 0);
	
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, offset.w, offset.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, intermediary->pixels );
	
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	
	
	SDL_FreeSurface(initial);
	SDL_FreeSurface(intermediary);
	return texture;
}
コード例 #3
0
ファイル: sdl_gl.cpp プロジェクト: czajkovsky/superarkanoid
void SDL_GL_RenderText(const char *text, TTF_Font *font, SDL_Color color, SDL_Rect *location) {
	glLoadIdentity();
	SDL_Surface *initial;
	SDL_Surface *intermediary;
	GLuint font_texture;
	
	initial = TTF_RenderText_Blended(font, text, color);
	SDL_SetAlpha(initial, 0, 0);
	
	location->w = nextpoweroftwo(initial->w);
	location->h = nextpoweroftwo(initial->h);
	
	intermediary = SDL_CreateRGBSurface(SDL_SWSURFACE, location->w, location->h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);

	SDL_BlitSurface(initial, 0, intermediary, 0);
	
	glGenTextures(1, &font_texture);
	glBindTexture(GL_TEXTURE_2D, font_texture);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, location->w, location->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, intermediary->pixels );
	
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, font_texture);
	glColor3f(1,1,1);
	
	glBegin(GL_QUADS);
		// Top-left vertex (corner)
		glTexCoord2d(0, 0);
		glVertex3f(location->x, location->y, 0);
		// Bottom-left vertex (corner)
		glTexCoord2d(1, 0);
		glVertex3f(location->x + intermediary->w, location->y, 0);
		// Bottom-right vertex (corner)
		glTexCoord2d(1, 1);
		glVertex3f(location->x + intermediary->w, location->y + intermediary->h, 0);
		// Top-right vertex (corner)
		glTexCoord2d(0, 1);
		glVertex3f(location->x, location->y + intermediary->h, 0); 
	glEnd();

	glFinish();
	
	SDL_FreeSurface(initial);
	SDL_FreeSurface(intermediary);
	glDeleteTextures(1, &font_texture);
}
コード例 #4
0
ファイル: ttf.c プロジェクト: goblinhack/Tullianum
//
// Create a texture from a surface. Set the alpha according to the color key.
// Pixels that match the color key get an alpha of zero while all other pixels
// get an alpha of one. We use black for the color key.
//
GLuint ttf_set_color_key (SDL_Surface *glyph_surface,
                          GLfloat *texcoord,
                          uint8 ckr, 
                          uint8 ckg, 
                          uint8 ckb)
{
    SDL_Surface *tmp;
    uint32 colorkey;
    GLuint texture;
    SDL_Rect area;

    //
    // Use the surface width and height expanded to powers of 2
    //
    int width = nextpoweroftwo(glyph_surface->w);
    int height = nextpoweroftwo(glyph_surface->h);

    texcoord[0] = 0; // Min X
    texcoord[1] = 0; // Min Y
    texcoord[2] =
        (GLfloat)(((float)glyph_surface->w) / ((float)width));  // Max X
    texcoord[3] =
        (GLfloat)(((float)glyph_surface->h) / ((float)height)); // Max Y

    tmp = SDL_CreateRGBSurface(glyph_surface->flags,
                               width, height,
                               glyph_surface->format->BitsPerPixel,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN // OpenGL RGBA masks 
                               0x000000FF, 
                               0x0000FF00, 
                               0x00FF0000, 
                               0xFF000000
#else
                               0xFF000000,
                               0x00FF0000, 
                               0x0000FF00, 
                               0x000000FF
#endif
                            );

    if (!tmp) {
        ERR("Failed to make RGB surface");
        return (0);
    }

    //
    // Set up so that colorkey pixels become transparent
    //
    colorkey = SDL_MapRGBA(tmp->format, 0, 0, 0, 0);
    SDL_FillRect(tmp, NULL, colorkey);

    colorkey = SDL_MapRGBA(glyph_surface->format, ckr, ckg, ckb, 0);
    SDL_SetColorKey(glyph_surface, SDL_SRCCOLORKEY, colorkey);

    //
    // Copy the surface into the GL texture image
    //
    area.x = 0;
    area.y = 0;
    area.w = glyph_surface->w;
    area.h = glyph_surface->h;

    SDL_BlitSurface(glyph_surface, &area, tmp, &area);

    //
    // Create an OpenGL texture for the tmp
    //
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D,
        0,
        GL_RGBA,
        width, height,
        0,
        GL_RGBA,
        GL_UNSIGNED_BYTE,
        tmp->pixels);

    SDL_FreeSurface(tmp);

    return (texture);
}
コード例 #5
0
ファイル: global.cpp プロジェクト: AntonBogomolov/Models
void SDL_GL_RenderTextCyrillic(char *text, 
                      int fontId,
                      SDL_Color color,
                      SDL_Rect *location)
{
	SDL_Surface *initial;
	SDL_Surface *intermediary;

	int w,h;
	GLuint texture;

	TTF_Font *fnt = NULL;
	switch (fontId)
	{
		case 12:
			fnt = fnt_12pt;
		break;
		case 16:
			fnt = fnt_16pt;
		break;
		case 24:
			fnt = fnt_24pt;
		break;
		case 32:
			fnt = fnt_32pt;
		break;
		case 42:
			fnt = fnt_42pt;
		break;
		default:
			fnt = fnt_16pt;
		break;
	}
		
	 wchar_t *utext = MultiCharToUniChar(text);

	/* Use SDL_TTF to render our text */
	Uint16* stext = new Uint16[strlen(text)+1];
		for (size_t i = 0; i < strlen(text); ++i) {
			stext[i] = utext[i]; 
		}
	stext[strlen(text)] = 0;

	initial = TTF_RenderUNICODE_Blended(fnt,stext,color);
	delete[] stext;

	/* Convert the rendered text to a known format */
	w = nextpoweroftwo(initial->w);
	h = nextpoweroftwo(initial->h);
	
	intermediary = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);

	SDL_BlitSurface(initial, 0, intermediary, 0);
	
	/* Tell GL about our new texture */
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_BGRA, 
			GL_UNSIGNED_BYTE, intermediary->pixels );
	
	/* GL_NEAREST looks horrible, if scaled... */
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	

	/* prepare to render our texture */
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture);
	glColor3f(1.0f, 1.0f, 1.0f);
	
	/* Draw a quad at location */
	glBegin(GL_QUADS);
		glTexCoord2f(0.0f, 1.0f); 
			glVertex2f(location->x    , location->y);
		glTexCoord2f(1.0f, 1.0f); 
			glVertex2f((float)(location->x + w), location->y);
		glTexCoord2f(1.0f, 0.0f); 
			glVertex2f((float)(location->x + w), (float)(location->y - h));
		glTexCoord2f(0.0f, 0.0f); 
			glVertex2f(location->x    , (float)(location->y - h));
	glEnd();
		
	/* Clean up */
	SDL_FreeSurface(initial);
	SDL_FreeSurface(intermediary);
	glDeleteTextures(1, &texture);
}
コード例 #6
0
ファイル: global.cpp プロジェクト: AntonBogomolov/Models
void SDL_GL_RenderText(char *text, int fontId, SDL_Color color, SDL_Rect *location)
{
	SDL_Surface *initial;
	SDL_Surface *intermediary;

	int w,h;
	GLuint texture;

	TTF_Font *fnt = NULL;
	switch (fontId)
	{
		case 12:
			fnt = fnt_12pt;
		break;
		case 16:
			fnt = fnt_16pt;
		break;
		case 24:
			fnt = fnt_24pt;
		break;
		case 32:
			fnt = fnt_32pt;
		break;
		case 42:
			fnt = fnt_42pt;
		break;
		default:
			fnt = fnt_16pt;
		break;
	}

	initial = TTF_RenderText_Blended(fnt,text,color);

	/* Convert the rendered text to a known format */
	w = nextpoweroftwo(initial->w);
	h = nextpoweroftwo(initial->h);
	
	intermediary = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);

	SDL_BlitSurface(initial, 0, intermediary, 0);
	
	/* Tell GL about our new texture */
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_BGRA, 
			GL_UNSIGNED_BYTE, intermediary->pixels );
	
	/* GL_NEAREST looks horrible, if scaled... */
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	

	/* prepare to render our texture */
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture);
	glColor3f(1.0f, 1.0f, 1.0f);
	
	/* Draw a quad at location */
	glBegin(GL_QUADS);
		/* Recall that the origin is in the lower-left corner
		   That is why the TexCoords specify different corners
		   than the Vertex coors seem to. */
		glTexCoord2f(0.0f, 1.0f); 
			glVertex2f(location->x    , location->y);
		glTexCoord2f(1.0f, 1.0f); 
			glVertex2f((float)(location->x + w), location->y);
		glTexCoord2f(1.0f, 0.0f); 
			glVertex2f((float)(location->x + w), (float)(location->y - h));
		glTexCoord2f(0.0f, 0.0f); 
			glVertex2f(location->x    , (float)(location->y - h));
	glEnd();
	
	/* Bad things happen if we delete the texture before it finishes */
//	glFinish();
	
	/* return the deltas in the unused w,h part of the rect */
//	location->w = initial->w;
//	location->h = initial->h;
	
	SDL_FreeSurface(initial);
	SDL_FreeSurface(intermediary);
	glDeleteTextures(1, &texture);
}
コード例 #7
0
ファイル: ttf.c プロジェクト: goblinhack/MundusMeus
font *
ttf_write_tga (char *name, int32_t pointsize)
{
    uint32_t rmask, gmask, bmask, amask;
    double glyph_per_row;
    char filename[200];
    SDL_Surface *dst;
    uint32_t height;
    uint32_t width;
    double maxx;
    double maxy[TTF_GLYPH_MAX];
    uint32_t c;
    int x;
    int y;
    double h;
    font *f;

    snprintf(filename, sizeof(filename), "%s_pointsize%u.tga",
             name, pointsize);

    if (tex_find(filename)) {
        return (0);
    }

    /*
     * x glyphs horizontally and y vertically.
     */
    glyph_per_row = 16;

    f = ttf_new(name, pointsize, TTF_STYLE_NORMAL);
    if (!f) {
        ERR("could not create font %s", name);
    }

    maxx = 0;
    memset(maxy, 0, sizeof(maxy));

    /*
     * Find the largest font glyph pointsize.
     */
    x = 0;
    y = 0;
    height = 0;

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {

        if (f->tex[c].image) {
            maxx = max(maxx, f->tex[c].image->w);
            maxy[y] = max(maxy[y], f->tex[c].image->h);
        }

        if (++x >= glyph_per_row) {
            x = 0;
            height += maxy[y];
            y++;
        }
    }

    if (!maxx) {
        ERR("no glyphs in font %s", name);
    }

    width = glyph_per_row * maxx;

    if (MULTIPLE_BITS(width)) {
        width = nextpoweroftwo(width);
    }

    height += 40;

    if (MULTIPLE_BITS(height)) {
        height = nextpoweroftwo(height);
    }

    /*
     * Make a large surface for all glyphs.
     */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    rmask = 0xff000000;
    gmask = 0x00ff0000;
    bmask = 0x0000ff00;
    amask = 0x000000ff;
#else
    rmask = 0x000000ff;
    gmask = 0x0000ff00;
    bmask = 0x00ff0000;
    amask = 0xff000000;
#endif

    dst = SDL_CreateRGBSurface(0, width, height, 32,
                               rmask, gmask, bmask, amask);
    if (!dst) {
        ERR("no surface created for size %dx%d font %s", width, height, name);
    }

    newptr(dst, "SDL_CreateRGBSurface");

    /*
     * Blit each glyph to the large surface.
     */
    x = 0;
    y = 0;
    h = 0;

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {

        if (f->tex[c].image) {
            SDL_Rect dstrect = { maxx * x, h, maxx, maxy[y] };

            SDL_BlitSurface(f->tex[c].image, 0, dst, &dstrect);
        }

        if (++x >= glyph_per_row) {
            x = 0;
            h += maxy[y];
            y++;
        }
    }

    /*
     * Convert the black border smoothing that ttf adds into alpha.
     */
    {
        double x;
        double y;

        for (x = 0; x < dst->w; x++) {
            for (y = 0; y < dst->h; y++) {

                color c;

                c = getPixel(dst, x, y);

                if ((c.a == 255) &&
                    (c.r == 255) &&
                    (c.g == 255) &&
                    (c.b == 255)) {
                    /*
                     * Do nothing.
                     */
                } else if ((c.a == 0) &&
                    (c.r == 0) &&
                    (c.g == 0) &&
                    (c.b == 0)) {
                    /*
                     * Do nothing.
                     */
                } else {
                    /*
                     * Convery gray to white with alpha.
                     */
                    c.a = (c.r + c.g + c.b) / 3;
                    c.r = 255;
                    c.g = 255;
                    c.b = 255;
                }

                putPixel(dst, x, y, c);
            }
        }
    }

#define MAX_TEXTURE_HEIGHT 4096

    if (dst->h > MAX_TEXTURE_HEIGHT) {
        ERR("ttf is too large");
    }

    uint8_t filled_pixel_row[MAX_TEXTURE_HEIGHT] = {0};

    /*
     * What the hell am I doing here? The ttf library returns incorrect
     * boounds for the top and bottom of glyphs, so I'm looking for a line of
     * no pixels above and below each glyph so I can really find the texture
     * bounds of a glyph. This allows squeezing of text together.
     */
    {
        int x;
        int y;

        for (y = 0; y < dst->h; y++) {
            for (x = 0; x < dst->w; x++) {
                color c;
                c = getPixel(dst, x, y);
                if (c.r || c.g || c.b || c.a) {
                    filled_pixel_row[y] = true;
                    break;
                }
            }
        }
    }

    /*
     * Work our the tex co-ords for each glyph in the large tex.
     */
    x = 0;
    y = 0;
    h = 0;

    int d1_max = 0;
    int d2_max = 0;

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {

        {
            int y = (h + (h + f->glyphs[c].height)) / 2;

            int miny = y;
            int maxy = y;

            for (;;) {
                if (!filled_pixel_row[miny]) {
                    break;
                }

                miny--;
                if (miny <= 0) {
                    break;
                }
            }

            for (;;) {
                if (!filled_pixel_row[maxy]) {
                    break;
                }

                maxy++;
                if (maxy >= MAX_TEXTURE_HEIGHT - 1) {
                    break;
                }
            }

            int d1 = y - miny;
            if (d1 > d1_max) {
                d1_max = d1;
            }

            int d2 = maxy - y;
            if (d2 > d2_max) {
                d2_max = d2;
            }
        }

        if (++x >= glyph_per_row) {
            x = 0;
            h += maxy[y];
            y++;
        }
    }

    x = 0;
    y = 0;
    h = 0;

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {

        f->glyphs[c].texMinX =
                        (double)(x * maxx) / (double)dst->w;
        f->glyphs[c].texMaxX =
                        (double)((x * maxx) + f->glyphs[c].width) /
                        (double)dst->w;

        {
            int y = (h + (h + f->glyphs[c].height)) / 2;

            int y1 = y - d1_max;
            int y2 = y + d2_max;

            if (y1 < 0) {
                y1 = 0;
            }

            f->glyphs[c].texMinY =
                            (double)(y1) /
                            (double)dst->h;
            f->glyphs[c].texMaxY =
                            (double)(y2) /
                            (double)dst->h;
        }

        if (++x >= glyph_per_row) {
            x = 0;
            h += maxy[y];
            y++;
        }
    }

    SDL_LockSurface(dst);
    stbi_write_tga(filename, dst->w, dst->h, STBI_rgb_alpha, dst->pixels);
    SDL_UnlockSurface(dst);

    texp tex;
    tex = tex_from_surface(dst, filename, filename);
    if (!tex) {
        ERR("could not convert %s to tex", filename);
    }

    /*
     * Work our the tex co-ords for each glyph in the large tex.
     */
    x = 0;
    y = 0;
    h = 0;

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {

        f->tex[c].image = dst;
        f->tex[c].tex = tex_get_gl_binding(tex);
    }

    /*
     * Save the glyph data.
     */
    snprintf(filename, sizeof(filename), "%s_pointsize%u.data",
             name, pointsize);

    FILE *out = fopen(filename, "w");

    fwrite(f->glyphs, sizeof(f->glyphs), 1, out);

    fclose(out);

    printf("wrote %s\n",filename);
    return (f);
}