glTexImage2D未能在GLUT / FreeType的例子用OpenGL 3及以上(glTe

2019-09-18 08:46发布

我使用的是发现这里的例子: http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Text_Rendering_01

问题是,当我与上述3版本指定的OpenGL上下文,即:

glutInitContextVersion (3, 2); 

调用与GL_INVALID_ENUM(所报告的GLIntercept)glTexImage2D结果误差和实施例的输出是空白的。 据我可以从OpenGL的3.3参考所知,这应该只是发生的事情,如果类型不是有效类型常数或目标是一个无效的目标。

这是有问题的行:

glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, g->bitmap.width, g->bitmap.rows, 0, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);

另外,我曾尝试修改的例子来调整位图,这样它的尺寸为2最近的电源,如在讷河教程( http://nehe.gamedev.net/tutorial/freetype_fonts_in_opengl/24001/ ),但我仍然有同样的错误。

我也试着使用实现了GLFW例子,有同样的问题。

我使用的是不同的着色器加载代码的例子,但着色器两者编译/链接精细的例子仍然有效,如果我不指定一个现代的OpenGL版本。

如果它帮助我的环境是:Windows 7的64位,Visual Studio 2010中
AMD HD6950显卡,12.3催化剂驱动程序。

软件库是:
FreeGLUT 2.8.0
GLEW 1.7.0
2.4.9用于FreeType
GLM-0.9.3.0


作为参考,这里是gliLog.txt - 我省略了大部分日志的结尾,因为它是同样的错误重复了一遍又一遍。

GL Intercept Log. Version : 0.5    Compile Date: Dec  3 2005    Run on: Fri Jun 22 15:42:05 2012

===================================================
Diagnostic: Unknown function wglCreateContextAttribsARB being logged.
GL ERROR - Function wglGetPixelFormat(0x200110ef) generated error GL_INVALID_ENUM
GL ERROR - Function glGetString(GL_VERSION) generated error GL_INVALID_ENUM
GL ERROR - Function glGetString(GL_EXTENSIONS) generated error GL_INVALID_ENUM
...
InterceptShaderGLSL::CreateObjectPost - Unknown object type 0x8dd9
InterceptShaderGLSL::DeleteObjectPost - Unable to find shader ID 2
GL ERROR - Function glTexImage2D(GL_TEXTURE_2D,0,GL_ALPHA,27,35,0,GL_ALPHA,GL_UNSIGNED_BYTE,0x73ab670) generated error 0x0500
ImageSaveManager::Save2DImage - invalid width/height on image
InterceptImage::SaveTextureImage - Error saving image 1
GL ERROR - Function glDrawArrays(GL_TRIANGLE_STRIP,0,4) generated error 0x0502
GL ERROR - Function glTexImage2D(GL_TEXTURE_2D,0,GL_ALPHA,20,35,0,GL_ALPHA,GL_UNSIGNED_BYTE,0x73ac300) generated error 0x0500
ImageSaveManager::Save2DImage - invalid width/height on image
InterceptImage::SaveTextureImage - Error saving image 0
GL ERROR - Function glDrawArrays(GL_TRIANGLE_STRIP,0,4) generated error 0x0502
GL ERROR - Function glTexImage2D(GL_TEXTURE_2D,0,GL_ALPHA,23,28,0,GL_ALPHA,GL_UNSIGNED_BYTE,0x73ac580) generated error 0x0500
ImageSaveManager::Save2DImage - invalid width/height on image
InterceptImage::SaveTextureImage - Error saving image 0

这里是示例代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
/* Using GLM for our transformation matrix */
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
/* Using FreeType 2 for rendering fonts */
#include <ft2build.h>
#include FT_FREETYPE_H
#include "shader_utils.h"

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glew32.lib")
#pragma comment(lib, "freeglut.lib")
#pragma comment(lib, "freetypeD.lib")

GLuint program;
GLint attribute_coord;
GLint uniform_tex;
GLint uniform_color;

struct point {
    GLfloat x;
    GLfloat y;
    GLfloat s;
    GLfloat t;
};

GLuint vbo;

FT_Library ft;
FT_Face face;

const char *fontfilename;

int init_resources()
{

    /* Initialize the FreeType2 library */
    if(FT_Init_FreeType(&ft)) {
        fprintf(stderr, "Could not init freetype library\n");
        return 0;
    }

    /* Load a font */
    if(FT_New_Face(ft, fontfilename, 0, &face)) {
        fprintf(stderr, "Could not open font %s\n", fontfilename);
        return 0;
    }

    /* Compile and link the shader program */
    GLint link_ok = GL_FALSE;

    program = text::LoadShader("text.v.glsl", NULL, "text.f.glsl");

    const char* attribute_name;
    attribute_name = "coord";
    attribute_coord = glGetAttribLocation(program, attribute_name);
    if (attribute_coord == -1) {
        fprintf(stderr, "Could not bind attribute %s\n", attribute_name);
        return 0;
    }

    const char* uniform_name;
    uniform_name = "tex";
    uniform_tex = glGetUniformLocation(program, uniform_name);
    if (uniform_tex == -1) {
        fprintf(stderr, "Could not bind uniform %s\n", uniform_name);
        return 0;
    }

    uniform_name = "color";
    uniform_color = glGetUniformLocation(program, uniform_name);
    if (uniform_color == -1) {
        fprintf(stderr, "Could not bind uniform %s\n", uniform_name);
        return 0;
    }

    // Create the vertex buffer object
    glGenBuffers(1, &vbo);

    return 1;
}

/**
    * Render text using the currently loaded font and currently set font size.
    * Rendering starts at coordinates (x, y), z is always 0.
    * The pixel coordinates that the FreeType2 library uses are scaled by (sx, sy).
    */
void render_text(const char *text, float x, float y, float sx, float sy) {
    const char *p;
    FT_GlyphSlot g = face->glyph;

    /* Create a texture that will be used to hold one "glyph" */
    GLuint tex;
    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glUniform1i(uniform_tex, 0);

    /* We require 1 byte alignment when uploading texture data */
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    /* Clamping to edges is important to prevent artifacts when scaling */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    /* Linear filtering usually looks best for text */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    /* Set up the VBO for our vertex data */
    glEnableVertexAttribArray(attribute_coord);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(attribute_coord, 4, GL_FLOAT, GL_FALSE, 0, 0);

    /* Loop through all characters */
    for(p = text; *p; p++) {
        /* Try to load and render the character */
        if(FT_Load_Char(face, *p, FT_LOAD_RENDER))
            continue;

        /* Upload the "bitmap", which contains an 8-bit grayscale image, as an alpha texture */
        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, g->bitmap.width, g->bitmap.rows, 0, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);

        /* Calculate the vertex and texture coordinates */
        float x2 = x + g->bitmap_left * sx;
        float y2 = -y - g->bitmap_top * sy;
        float w = g->bitmap.width * sx;
        float h = g->bitmap.rows * sy;

        point box[4] = {
            {x2,     -y2    , 0, 0},
            {x2 + w, -y2    , 1, 0},
            {x2,     -y2 - h, 0, 1},
            {x2 + w, -y2 - h, 1, 1},
        };

        /* Draw the character on the screen */
        glBufferData(GL_ARRAY_BUFFER, sizeof box, box, GL_DYNAMIC_DRAW);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        /* Advance the cursor to the start of the next character */
        x += (g->advance.x >> 6) * sx;
        y += (g->advance.y >> 6) * sy;
    }

    glDisableVertexAttribArray(attribute_coord);
    glDeleteTextures(1, &tex);
}

void display()
{
    float sx = 2.0 / glutGet(GLUT_WINDOW_WIDTH);
    float sy = 2.0 / glutGet(GLUT_WINDOW_HEIGHT);

    glUseProgram(program);

    /* White background */
    glClearColor(1, 1, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT);

    /* Enable blending, necessary for our alpha texture */
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    GLfloat black[4] = {0, 0, 0, 1};
    GLfloat red[4] = {1, 0, 0, 1};
    GLfloat transparent_green[4] = {0, 1, 0, 0.5};

    /* Set font size to 48 pixels, color to black */
    FT_Set_Pixel_Sizes(face, 0, 48);
    glUniform4fv(uniform_color, 1, black);

    /* Effects of alignment */
    render_text("The Quick Brown Fox Jumps Over The Lazy Dog",          -1 + 8 * sx,   1 - 50 * sy,    sx, sy);
    render_text("The Misaligned Fox Jumps Over The Lazy Dog",           -1 + 8.5 * sx, 1 - 100.5 * sy, sx, sy);

    /* Scaling the texture versus changing the font size */
    render_text("The Small Texture Scaled Fox Jumps Over The Lazy Dog", -1 + 8 * sx,   1 - 175 * sy,   sx * 0.5, sy * 0.5);
    FT_Set_Pixel_Sizes(face, 0, 24);
    render_text("The Small Font Sized Fox Jumps Over The Lazy Dog",     -1 + 8 * sx,   1 - 200 * sy,   sx, sy);
    FT_Set_Pixel_Sizes(face, 0, 48);
    render_text("The Tiny Texture Scaled Fox Jumps Over The Lazy Dog",  -1 + 8 * sx,   1 - 235 * sy,   sx * 0.25, sy * 0.25);
    FT_Set_Pixel_Sizes(face, 0, 12);
    render_text("The Tiny Font Sized Fox Jumps Over The Lazy Dog",      -1 + 8 * sx,   1 - 250 * sy,   sx, sy);
    FT_Set_Pixel_Sizes(face, 0, 48);

    /* Colors and transparency */
    render_text("The Solid Black Fox Jumps Over The Lazy Dog",          -1 + 8 * sx,   1 - 430 * sy,   sx, sy);

    glUniform4fv(uniform_color, 1, red);
    render_text("The Solid Red Fox Jumps Over The Lazy Dog",            -1 + 8 * sx,   1 - 330 * sy,   sx, sy);
    render_text("The Solid Red Fox Jumps Over The Lazy Dog",            -1 + 28 * sx,  1 - 450 * sy,   sx, sy);

    glUniform4fv(uniform_color, 1, transparent_green);
    render_text("The Transparent Green Fox Jumps Over The Lazy Dog",    -1 + 8 * sx,   1 - 380 * sy,   sx, sy);
    render_text("The Transparent Green Fox Jumps Over The Lazy Dog",    -1 + 18 * sx,  1 - 440 * sy,   sx, sy);

    glutSwapBuffers();
}

void free_resources()
{
    glDeleteProgram(program);
}

int main(int argc, char* argv[]) {
    glutInitContextVersion (3, 2);
    glutInitContextFlags (GLUT_FORWARD_COMPATIBLE | GLUT_DEBUG);
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA|GLUT_ALPHA|GLUT_DOUBLE);
    glutInitWindowSize(640, 480);
    glutCreateWindow("Basic Text");

    if(argc > 1)
        fontfilename = argv[1];
    else
        fontfilename = "FreeSans.ttf";

    GLenum glew_status = glewInit();
    if (GLEW_OK != glew_status) {
        fprintf(stderr, "Error: %s\n", glewGetErrorString(glew_status));
        return 1;
    }

    if (!GLEW_VERSION_2_0) {
        fprintf(stderr, "No support for OpenGL 2.0 found\n");
        return 1;
    }
    if (init_resources()) {
        glutDisplayFunc(display);
        glutMainLoop();
    }

    free_resources();
    return 0;
}

Answer 1:

GL_ALPHA不是有效的图像格式在GL 3.2核心,因此在GL_INVALID_ENUM误差 。 如果你想有一个单通道图像格式,则必须使用有效的单通道图像格式。 即,一些从GL_RED位深度。 我建议GL_R8

这也意味着,在像素传送格式 (从端第三个参数)也必须被GL_RED

请注意,当您使用相容性分布这些教程仅适用3.2+工作。 他们不是向前兼容,因为他们必须与GL ES兼容。



文章来源: glTexImage2D failing in GLUT/FreeType example with OpenGL 3 and above