我目前正在为一个库添加对SDL2窗口系统的支持,该库目前使用GLUT。这包括渲染文本。有问题的部分是,我无法访问文本呈现位置的Window
或Renderer
。以前的文本是使用glutBitmapCharacter
函数用GLUT呈现的。
通过使用glDrawPixels
,我非常接近解决这个问题,但输出看起来像这样:
的数据
看起来,纹理被翻转,上面渲染了一些噪点。我试着使用GL_UNPACK_XXX
函数,但找不到如何修复这个问题。你有什么想法吗?
下面是一个示例应用程序,它再现了这个问题:main.cpp:
个
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <GL/glew.h>
#include <string>
#include <stdint.h>
#include <chrono>
#include <thread>
const int width = 400;
const int height = 400;
TTF_Font* font = nullptr;
// THIS FUNCTION IS THE ONLY THING I CAN CHANGE!
void drawText(std::string text) {
SDL_Color color = {
static_cast<Uint8>(255),
static_cast<Uint8>(0),
static_cast<Uint8>(255),
static_cast<Uint8>(255)
};
SDL_Surface* textRender = TTF_RenderUTF8_Blended(font, text.c_str(), color);
SDL_Surface* surface = SDL_ConvertSurfaceFormat(textRender, SDL_PIXELFORMAT_RGBA8888, 0);
SDL_FreeSurface(textRender);
glPushAttrib(GL_BLEND);
glPushAttrib(GL_BLEND_EQUATION);
glPushAttrib(GL_CLIENT_PIXEL_STORE_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glDrawPixels(surface->w, surface->h, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
glPopAttrib();
glPopAttrib();
glPopAttrib();
SDL_FreeSurface(surface);
}
// EVERYTHING BELOW HERE IS ONLY TO PROVIDE A MINIMUM REPRODUCABLE EXAMPLE!
void loop(int64_t frame) {
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glRasterPos2f(-1.0, 0);
drawText(std::string("Hello World!") + std::to_string(frame));
}
int main() {
SDL_InitSubSystem(SDL_INIT_VIDEO);
TTF_Init();
auto* window = SDL_CreateWindow("sdl-text", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
auto* context = SDL_GL_CreateContext(window);
glewInit();
bool quit = false;
int64_t frame = 0;
font = TTF_OpenFont("arial.ttf", 42);
if (!font) {
quit = true;
}
while (!quit) {
loop(frame++);
SDL_GL_SwapWindow(window);
SDL_Event e;
while (SDL_PollEvent(&e)) {
switch(e.type) {
case SDL_QUIT:
quit = true;
break;
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(16));
}
TTF_Quit();
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return 0;
}
字符串
使用以下命令编译:
g++ main.cpp -lSDL2 -lSDL2_ttf -lGLEW -lGL
型
1条答案
按热度按时间oxf4rvwz1#
好的,看起来OpenGL以像素为单位获取行长度,而SDL以字节为单位提供。这很容易解决。
我们也不需要将曲面转换为RGBA。我们可以直接告诉OpenGL绘制BGRA(尽管SDL说它提供AGBR,但它是有效的)。
最后,我们在使用
glPixelZoom(1, -1)
绘制之前翻转图像。为了抵消翻转,我们必须向上移动高度。解决方案如下:
字符串