【问题标题】:Render TTF SDL2.0 opengl 3.1渲染TTF SDL2.0 opengl 3.1
【发布时间】:2013-10-30 15:09:41
【问题描述】:

我正在使用 SDL2.0,并使用(半现代)opengl (3.1)。我正在寻找向我的应用程序添加文本覆盖,并在应用程序中呈现 TTF。我将如何使用现代 OpenGL 来解决这个问题?

编辑: 根据 genpfault 的建议,我尝试使用 SDL_TTF 库,但我得到的只是屏幕上的垃圾 http://i.stack.imgur.com/FqyCT.png 我附上了我的着色器的要点,这对于这个程序来说非常简单,还有我用来将文本加载到表面并将其绑定到纹理的片段。我根本不想在这里做任何疯狂的事情。你能看到我做错了什么吗?我不太确定如何调试着色器等。

https://gist.github.com/anonymous/7284430

【问题讨论】:

    标签: opengl fonts sdl sdl-2 opengl-3


    【解决方案1】:

    在我发现实际的文本数据在 Alpha 通道中之前,我花了太多时间在黑屏上。

    GLuint shader_program_text;
    
    void drawText()
    {
        //Render the message to an SDL_Surface, as that's what TTF_RenderText_X returns
        text_font = TTF_OpenFont("bpl_binary/waltographUI.ttf", 50);
        SDL_Color color = {255, 0, 0, 0};
        SDL_Surface* sdl_surface = TTF_RenderText_Blended(text_font, "hello world", color);
        GLuint texture_id;
        glGenTextures(1, &texture_id);
        glBindTexture(GL_TEXTURE_2D, texture_id);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sdl_surface->w, sdl_surface->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, sdl_surface->pixels);
        glBindTexture(GL_TEXTURE_2D, 0);
        SDL_FreeSurface(sdl_surface);
        TTF_CloseFont(text_font);
    
        //glDrawPixels(sdl_surface->w, sdl_surface->h, GL_RGBA, GL_UNSIGNED_BYTE, sdl_surface->pixels);
        //FILE* file = fopen("output.txt", "w+");
    
        //for(int h=0; h<sdl_surface->h; h++)
        //{
        //  
        //  for(int w=0; w<sdl_surface->w; w++)
        //  {
        //      unsigned int xxx = ((unsigned int*)sdl_surface->pixels)[h*sdl_surface->w + w];
        //      /*if(xxx != 0)
        //          fprintf(file, "x", xxx);
        //      else
        //          fprintf(file, " ", xxx);*/
        //      fprintf(file, "%08x ", xxx);
        //  }
        //  fprintf(file, "\n");
        //}
    
        //fclose(file);
    
        //MULTIPLY WITH ALPHA TO ACTUALLY SEE SOMETHING
    
        glUseProgram(shader_program_text);
        glEnable(GL_TEXTURE_2D);
    
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture_id);
    
        glBegin(GL_TRIANGLE_STRIP);
        //texcoord; position;
        glVertexAttrib2f(1, 0, 1); glVertexAttrib2f(0, -1, -1); //top left
        glVertexAttrib2f(1, 1, 1); glVertexAttrib2f(0, +1, -1); //top right
        glVertexAttrib2f(1, 0, 0); glVertexAttrib2f(0, -1, +1); //bottom left
        glVertexAttrib2f(1, 1, 0); glVertexAttrib2f(0, +1, +1); //bottom right
        glEnd();
    
        glDisable(GL_TEXTURE_2D);
        glUseProgram(0);
    } 
    

    【讨论】:

    • glBegin 和 glEnd 在 OpenGL 3+ 中是不允许的
    • 嗯,所以我想你只使用 VBO?
    • VAO + VBO 是的:这意味着很多代码只需执行与使用简单 glDrawPixels 相同的操作(创建纹理,创建 VBO 并创建着色器),只需将一些像素复制到屏幕。我正在寻找更简单的方法,但直到现在我还没有找到任何东西。
    • @AdrianMaire:因为无论如何我们都必须使用着色器,也许这对于几何着色器来说甚至是一个不错的用例?就像提供字体纹理和包含要渲染的字符串的 1D-1-Byte-Per-Index (=GL_RED8 afaik) 纹理,然后渲染一个定义文本边界框的四边形(=4 顶点三角形条)。还是会引入太多开销?计划我自己的 openGL 4.3 GUI 系统,我不希望我的游戏被 UI 拖慢:D
    • @nonchip:每个字符都有自己的大小、位置等,因此仅从字符网格渲染全文并不容易。如果您能够创建高质量的文本,这可能会很好,但就个人而言,我只是使用文本库(SDL_TTF 或等效项)在纹理(文本第一次出现时)上渲染了全文。
    【解决方案2】:

    使用TTF_Render*() 调用返回的the pixels member of the SDL_Surface 填充纹理。

    【讨论】:

    • 我猜那是在使用 SDL_TTF 库?感谢您的回复,我已经尝试过了,但运气不佳。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 2018-06-11
    • 2012-06-13
    • 2013-12-27
    • 2013-04-16
    相关资源
    最近更新 更多