0

在从 Qt 切换到 GLUT 并在相同的地方使用相同的 OpenGL 调用后,我一直在与 OpenGL 作斗争!OpenGL在此切换后停止工作非常奇怪,我已经尝试了互联网上可用的每一种方法,但没有运气。

很明显,Qt 对 GL Context 做了一些事情,使其正常工作而没有痛苦。

OpenGL 供应商:NVIDIA Corporation

OpenGL 渲染器:GeForce GT 430/PCIe/SSE2

OpenGL 版本:4.2.0 NVIDIA 304.88

着色器:(编译没有任何错误):

static const char *vertexSource =
    "uniform mat3 proj;\n"
    "varying vec2 TexCoord;\n"
    ""
    "attribute vec2 texcoord;\n"
    "attribute vec2 vertex;\n"
    ""
    "void main() {\n"
    "   gl_Position = vec4(proj * vec3(vertex.xy, 1), 1);\n"
    "   TexCoord = texcoord;\n"
    "}";

static const char *fragmentSource =
    "varying vec2 TexCoord;\n"
    "uniform sampler2D texture;\n"
    ""
    "void main() {\n"
    "   gl_FragColor = texture2D(texture, TexCoord);\n"
    "}";

初始化所有内容(纹理、着色器、...) - 这在调用 glutMainLoop() 之前和初始化 GLEW 之后调用:

static void initialize(void)
{
    sp_init(&sp);
    if (!sp_compile_shader(&sp, Vertex, vertexSource))
        exit(EXIT_FAILURE);

    if (!sp_compile_shader(&sp, Fragment, fragmentSource))
        exit(EXIT_FAILURE);

    if (!sp_link(&sp)) {
        fprintf(stderr, "Failed to link the GL shader program: %s\n", sp_log(&sp));
        exit(EXIT_FAILURE);
    }

    sp_bind_attrib_loc(&sp, Position, "vertex");
    sp_bind_attrib_loc(&sp, TexCoord, "texcoord");
    sp_bind(&sp);

    if (!texture_load(&grassTexture, "textures/grass.png")) {
        fprintf(stderr, "Failed to load the grass texture.\n");
        exit(EXIT_FAILURE);
    }

    snakeTextures = calloc(sizeof(directions) / sizeof(directions[0]), sizeof(texture_t));
    if (!snakeTextures) {
        fprintf(stderr, "Failed to allocate memory for snake textures\n");
        exit(EXIT_FAILURE);
    }

    int i;
    for (i = 0; directions[i]; ++i) {
        char fileName[512];
        snprintf(fileName, sizeof fileName, "textures/snake_%s.png", directions[i]);

        texture_t tex;
        if (!texture_load(&tex, fileName)) {
            fprintf(stderr, "Failed to load snake texture '%s'\n", fileName);
            continue;
        }

        snakeTextures[i] = tex;
    }
    currentSnakeTexture = &snakeTextures[0]; /* Looking right.  */
    point_make_data(&snakePos, g_width / 2, g_height / 2);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

将投影矩阵和对 glViewport 的调用设置在与 Qt 中相同的位置(重塑):

static void reshape(int w, int h)
{
    //  Coordinate      Projection Matrix                   GL Coordinate (Transformed)
    //                  | 2.0 / width |   0.0           | 0.0  |
    //  | x  y  1 |  *  | 0.0         |  -2.0 / height  | 0.0  | =  | x' y' 1 |
    //                  |-1.0         |   1.0           | 1.0  |
    GLfloat projectionMatrix[] = {
         2.0f/w*g_zoom,   0.0f,      0.0f,
         0.0f,       -2.0f/h*g_zoom, 0.0f,
        -1.0f,        1.0f,      1.0f
    };

    sp_set_projection_matrix(&sp, projectionMatrix);
    glViewport(0, 0, w, h);
    g_width = w;
    g_height = h;
}

sp_set_projection_matrix (只是 glUniform 的包装器......)和 sp_set_vertex_data:

void sp_set_vertex_data(shaderprogram_t *sp, GLint attribLoc, const GLvoid *values, GLint size)
{
    return glVertexAttribPointer(attribLoc, size, GL_FLOAT, GL_FALSE, 0, values);
}

void sp_set_projection_matrix(shaderprogram_t *sp, const GLfloat *values)
{
    GLint loc = sp_uniform_location(sp, "proj");
    if (loc < 0)
        return;

    return glUniformMatrix3fv(loc, 1, GL_FALSE, values);
}

渲染函数回调:

static void render(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    double width = ceil((double)g_width / 32);
    double x, y;
    for (x = 0, y = 0; y < g_height; x += 32.f) {
        if (x == width * 32.f) {
            y += 32.f;
            x  = 0;
        }

        point_t placePoint;
        point_make_data(&placePoint, x, y);

        sp_set_vertex_data(&sp, Position, placePoint.data, 2);
        sp_set_vertex_data(&sp, TexCoord, texcoord, 2);

        texture_bind(&grassTexture);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
    }

    renderSnake();
    glutSwapBuffers();
}

point_make_data():

void point_make_data(point_t *__p, real __x, real __y)
{
    __p->x = __x;
    __p->y = __y;

    __p->data[0] = __x;
    __p->data[1] = __y;

    __p->data[2] = __x;
    __p->data[3] = __y + 32;

    __p->data[4] = __x + 32;
    __p->data[5] = __y + 32;

    __p->data[6] = __x + 32;
    __p->data[7] = __y;
}

点::数据是double data[8];

主功能:

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitWindowSize(g_width, g_height);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutCreateWindow("Snake");

    glutReshapeFunc(&reshape);
    glutDisplayFunc(&render);

    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if (err != GLEW_OK) {
        printf("Failed to initialize GLEW: %s\n", glewGetErrorString(err));
        return 1;
    }

    printf("OpenGL Vendor:   %s\n",  glGetString(GL_VENDOR));
    printf("OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
    printf("OpenGL Version:  %s\n", glGetString(GL_VERSION));

    initialize();
    glutMainLoop();
    return 0;
}

如果我发布了很多代码,我很抱歉,但这只是为了说清楚。

如果您需要更多代码,请告诉我。

4

2 回答 2

3

原来的问题是,Point::data is double data[8];所以 adouble[]被传递给glVertexAttribPointerGL_FLOATas 类型,这显然是错误的。

于 2013-07-27T22:59:26.777 回答
0
point_t *__p

在您自己的代码中使用任何带双下划线前缀的名称都是未定义的行为。这些名称是为实现保留的。

于 2013-07-27T20:29:02.813 回答