即使数据是正确的,OpenGL也只是拒绝呈现任何内容

时间:2013-07-27 20:22:49

标签: c opengl glsl glut

在同一个地方使用相同的OpenGL调用从Qt切换到GLUT后,我一直在努力使用OpenGL! OpenGL在切换后停止工作是非常奇怪的,我尝试了互联网上的每一种方法都没有运气。

很明显,Qt对GL上下文做了一些事情,这使得它可以正常工作而没有痛苦。

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;
}

Point :: data是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;
}

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

如果您需要更多代码,请与我们联系。

2 个答案:

答案 0 :(得分:3)

原来问题是Point::data is double data[8];所以double[]传递给glVertexAttribPointer GL_FLOAT作为类型显然是错误的。

答案 1 :(得分:0)

point_t *__p

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