I'm working on a program that creates an SDL_Surface using http://www.fontspace.com/work-ins-studio/variane-script. I set the background of the surface to be transparent. Then I extract the pixels from the surface, and place them in part of an opengl texture.
It all works fine, except that the text ends up looking like this (the text should read "testing")
My question: Did I mess up the math somehow and do this myself, or is this just the behaviour of SDL_TTF? And, if it is just the behaviour of SDL_TTF, how do I work around it to get pixel data that I can use?
Here is the relevant code:
int main(int argc, char* args[]) {
//other sdl and opengl overhead stuff here...
TTF_Init();
//shader setup here...
TTF_Font *font;
font = TTF_OpenFont("VarianeScript.ttf", 50);
SDL_Surface* surface;
SDL_Color color = { 255, 0, 0 };
surface = TTF_RenderText_Solid(font, "testing", color);
SDL_SetSurfaceAlphaMod(surface, 255);
int surfaceWidth = surface->w;
int surfaceHeight = surface->h;
Uint8 red, green, blue, alpha;
float* textImage = new float[(surfaceWidth * surfaceHeight) * 4];
int countText = 0;
SDL_LockSurface(surface);
Uint8* p = (Uint8*)surface->pixels;
for (int y = 0; y < surfaceHeight; ++y) {
for (int x = 0; x < (surfaceWidth); ++x) {
Uint8 pixel = p[(y * surface->w) + x];
SDL_GetRGBA(pixel, surface->format, &red, &green, &blue, &alpha);
textImage[countText] = ((float)red / 255.0f);
++countText;
textImage[countText] = ((float)green / 255.0f);
++countText;
textImage[countText] = ((float)blue / 255.0f);
++countText;
textImage[countText] = ((float)alpha / 255.0f);
++countText;
}
}
SDL_UnlockSurface(surface);
SDL_FreeSurface(surface);
GLuint texture;
float* image;
int width = 1000, height = 1000;
int textX = width - (int)(width / 1.5);
int textY = height - (int)(height / 1.5);
setupTexture(texture, shader, width, height, image, textImage, textX, textY, surfaceWidth, surfaceHeight);
//etc...
also (the important part starts around where I declare the startpos variables)
void setupTexture(GLuint &texture, Shader &shader, int &width, int &height, float* &image, float* text, int textX, int textY, int textW, int textH) {
glGenTextures(1, &texture);
image = new float[(width * height) * 3];
for (int a = 0; a < (width * height) * 3; ) {
if (a < ((width * height) * 3) / 2) {
image[a] = 0.5f;
++a;
image[a] = 1.0f;
++a;
image[a] = 0.3f;
++a;
}
else {
image[a] = 0.0f;
++a;
image[a] = 0.5f;
++a;
image[a] = 0.7f;
++a;
}
}
int startpos1, startpos2;
for(int y = 0; y < textH; ++y) {
for(int x = 0; x < textW; ++x) {
startpos1 = (((y + textY) * width) * 3) + ((x + textX) * 3);
startpos2 = ((y * textW) *4) + (x * 4);
if (text[startpos2 + 3] != 0.0) {
image[startpos1] = text[startpos2];
image[startpos1 + 1] = text[startpos2 + 1];
image[startpos1 + 2] = text[startpos2 + 2];
}
}
}
glActiveTexture(GL_TEXTURE0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, image);
glUniform1i(glGetUniformLocation(shader.shaderProgram, "texSampler"), 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
glPixelStore(GL_UNPACK_ALIGNMENT, 1)
– Rabbid76textX
andtextY
calculated from hardcoded constant 1000 and does not represent actual pitch oftextImage
. What's that constants supposed to mean? Shouldn't it besurfaceWidth
andsurfaceHeight
instead? – keltar