C++ 从SDL_TTF创建的SDL2曲面提取像素

C++ 从SDL_TTF创建的SDL2曲面提取像素,c++,opengl,sdl,sdl-2,sdl-ttf,C++,Opengl,Sdl,Sdl 2,Sdl Ttf,我正在开发一个程序,用它创建SDL_曲面。我将曲面的背景设置为透明。然后,我从表面提取像素,并将它们放置在opengl纹理的一部分 这一切都很好,除了文本最终看起来像这样(文本应为“测试”) 我的问题:是我自己搞砸了数学,还是这只是SDL_TTF的行为?而且,如果这只是SDL_TTF的行为,我如何处理它以获得我可以使用的像素数据 以下是相关代码: int main(int argc, char* args[]) { //other sdl and opengl overhead stuff h

我正在开发一个程序,用它创建SDL_曲面。我将曲面的背景设置为透明。然后,我从表面提取像素,并将它们放置在opengl纹理的一部分

这一切都很好,除了文本最终看起来像这样(文本应为“测试”)

我的问题:是我自己搞砸了数学,还是这只是SDL_TTF的行为?而且,如果这只是SDL_TTF的行为,我如何处理它以获得我可以使用的像素数据

以下是相关代码:

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...
intmain(intargc,char*args[]){
//其他sdl和opengl开销的东西在这里。。。
TTF_Init();
//着色器设置在这里。。。
TTF_字体*字体;
font=TTF_OpenFont(“VarianeScript.TTF”,50);
SDL_表面*表面;
SDL_颜色={255,0,0};
表面=TTF_RenderText_实体(字体,“测试”,颜色);
SDL_设置曲面AlphaMod(曲面,255);
int SURFACHEWIDTH=曲面->w;
int SURFACHEIGHT=曲面->h;
Uint8红、绿、蓝、阿尔法;
浮点*文本图像=新浮点[(表面宽度*表面高度)*4];
int countText=0;
SDL_锁面(表面);
Uint8*p=(Uint8*)表面->像素;
对于(int y=0;yw)+x];
SDL_GetRGBA(像素、曲面->格式、红色、绿色、蓝色和alpha);
text图像[countText]=((浮点)红色/255.0f);
++统计文本;
text图像[countText]=((浮点)绿色/255.0f);
++统计文本;
text图像[countText]=((浮点)蓝色/255.0f);
++统计文本;
text图像[countText]=((浮点)alpha/255.0f);
++统计文本;
}
}
SDL_解锁表面(表面);
SDL_自由曲面(曲面);
胶合结构;
浮动*图像;
内部宽度=1000,高度=1000;
int textX=宽度-(int)(宽度/1.5);
int textY=高度-(int)(高度/1.5);
setupTexture(纹理、着色器、宽度、高度、图像、textImage、textX、textY、表面宽度、表面高度);
//等等。。。
另外(重要的部分从我声明startpos变量开始)

void setupTexture(GLuint和纹理、着色器和着色器、int和宽度、int和高度、float*&图像、float*文本、int textX、int textY、int textW、int textH){
glGenTextures(1,&纹理);
图像=新浮动[(宽度*高度)*3];
对于(int a=0;a<(宽度*高度)*3;){
如果(a<((宽*高)*3)/2){
图像[a]=0.5f;
++a;
图像[a]=1.0f;
++a;
图像[a]=0.3f;
++a;
}
否则{
图像[a]=0.0f;
++a;
图像[a]=0.5f;
++a;
图像[a]=0.7f;
++a;
}
}
int startpos1,startpos2;
对于(int y=0;y
您的问题在于从曲面提取像素的方式:

Uint8 pixel = p[(y * surface->w) + x];
假设每个像素占用一个字节(可以通过检查
surface->format->bytesperpoixel
进行验证),并且每行
surface->w*1
字节长-但它不是。相反,每行
surface->pitch
字节长,因此代码应该是

Uint8 pixel = p[y * surface->pitch + x];
(这仍然假设它的长度为1字节,但这并不重要)


使用浮点数表示像素数据非常奇怪,因为除了加载速度慢得多之外,这里什么都没有。

由于您创建了一个紧凑的RGB纹理,您必须设置如何在代码中实现它?我对opengl非常陌生,抱歉
textX
textY
是从硬编码的cons计算出来的tant 1000,不代表
textImage
的实际节距。这些常量应该是什么意思?它不应该是
surfaceWidth
surfaceHeight
吗?textX和textY代表原点(左上角)文本中的像素将覆盖图像中的像素。我认为问题不在于我的代码本身。问题在于sdl_ttf将文本环绕到像素阵列的前面以节省空间(我假设)我不知道如何处理这个问题。或者我可能把数学搞砸了。我会尝试实现你的代码并向你汇报。我想我在什么地方读到opengl将8位0-255值转换为浮点数?也许我错了。你建议只使用8位无符号整数吗?我还更改了你建议的行,现在是程序崩溃而不显示任何内容。是否需要任何进一步的更改才能使其正常工作?另外,我会检查bytesperpixel,谢谢,我希望有人能向我解释如何在格式中找到我想要的内容,很好。我添加了一行代码:std::cout format->bytesperpixel我认为不需要任何技术就无法诊断崩溃hnical信息。在调试器中运行它以查看崩溃的位置和原因。如果您无法找到它,请将该信息和当前代码编辑到问题中。我还尝试了BitsPerPixel,它输出8。我不确定为什么使用pitch会使程序崩溃,如果pitch是每行的字节数。
Uint8 pixel = p[y * surface->pitch + x];