OpenGL - C ++ VS 2013没有显示,只有黑色窗口

时间:2014-10-29 11:22:32

标签: c++ opengl

这是我在计算机图形学课程中的练习,但我不是要求解决方案,只是为了能够实际练习练习,因为我现在不能,因为所有的输出都是黑色的窗口 - 我知道它应该生产什么,因为我在学校的计算机上工作,我现在正试图在家里工作。

代码在学校的计算机上工作正常,我已经向助教提出了帮助,但到目前为止他们找不到我的问题。

学校计算机在VS 2010 Windows 7上运行,而我只有VS 2013 Windows 8.1可用。当我第一次打开项目时,它要求我将其转换为VS2013等,我这样做了。

我能够很好地运行其他一些练习,但是我对2.1以上的所有练习都有问题。

以下代码来自练习2.2

// 02561-02-02

#include <iostream>
#include <string>
#include <GL/glew.h>
#include <GL/freeglut.h>

#include "Angel.h"

using namespace std;
using namespace Angel;

int WINDOW_WIDTH = 500;
int WINDOW_HEIGHT = 500;

GLuint shaderProgram;
GLuint projectionUniform,
    modelViewUniform,
    colorUniform;
GLuint positionAttribute;
GLuint unitCubeVertexArrayObject,
    axisVertexArrayObject,
    vertexBuffer;

const int axisSize = 6;

struct Vertex {
    vec4 position;
};

void loadShader();
void display();
GLuint loadBufferData(Vertex* vertices, int vertexCount);

void buildUnitCube() {
    const int cubeSize = 8;
    Vertex cubeData[cubeSize] = {
        { vec4( 1.0,  1.0,  1.0, 1.0 ) },
        { vec4( 1.0,  0.0,  1.0, 1.0 ) },
        { vec4( 1.0,  1.0,  0.0, 1.0 ) },
        { vec4( 1.0,  0.0,  0.0, 1.0 ) },
        { vec4(-0.0,  1.0,  0.0, 1.0 ) },
        { vec4(-0.0,  0.0,  0.0, 1.0 ) },
        { vec4(-0.0,  1.0,  1.0, 1.0 ) },
        { vec4(-0.0,  0.0,  1.0, 1.0 ) }
    };
    unitCubeVertexArrayObject = loadBufferData(cubeData, cubeSize);
}

void buildAxis() {
    Vertex axisData[axisSize] = {
        {vec4(0., 0., 0., 1.0)}, // v0
        {vec4(4., 0., 0., 1.0)}, // vx
        {vec4(0., 4., 0., 1.0)}, // vy
        {vec4(0., 0., 4., 1.0)}, // vz
        {vec4(1., 0., 0., 1.0)}, // v0x1
        {vec4(1., 3., 0., 1.0)} // vyx1
    };
    axisVertexArrayObject = loadBufferData(axisData, axisSize);
}

GLuint loadBufferData(Vertex* vertices, int vertexCount) {
    GLuint vertexArrayObject;

    glGenVertexArrays(1, &vertexArrayObject);
    glBindVertexArray(vertexArrayObject);

    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(positionAttribute);
    glVertexAttribPointer(positionAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)0);

    return vertexArrayObject;
}

void loadShader(){
    shaderProgram = InitShader("const-shader.vert",  "const-shader.frag", "fragColor");
    projectionUniform = glGetUniformLocation(shaderProgram, "projection");
    if (projectionUniform == GL_INVALID_INDEX) {
        cerr << "Shader did not contain the 'projection' uniform."<<endl;
    }
    modelViewUniform = glGetUniformLocation(shaderProgram, "modelView");
    if (modelViewUniform == GL_INVALID_INDEX) {
        cerr << "Shader did not contain the 'modelView' uniform."<<endl;
    }
    colorUniform = glGetUniformLocation(shaderProgram, "color");
    if (colorUniform == GL_INVALID_INDEX) {
        cerr << "Shader did not contain the 'color' uniform."<<endl;
    }
    positionAttribute = glGetAttribLocation(shaderProgram, "position");
    if (positionAttribute == GL_INVALID_INDEX) {
        cerr << "Shader did not contain the 'position' attribute." << endl;
    }
}

void drawWireUnitCube() {
    GLuint indices[24] = {
        0,1,
        1,3,
        3,2,
        2,0,
        4,5,
        5,7,
        7,6,
        6,4,
        7,1,
        6,0,
        4,2,
        5,3
    };
    glBindVertexArray(unitCubeVertexArrayObject);
    glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, indices);
}

void drawAxis() {
    GLuint indices[8] = {
        0,1,
        0,2,
        0,3,
        4,5
    };
    glBindVertexArray(axisVertexArrayObject);
    glDrawElements(GL_LINES, 8, GL_UNSIGNED_INT, indices);
}

void display() {    
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(shaderProgram);

    mat4 projection = Ortho(-6., 6., -6., 6., -6., 10.);
    glUniformMatrix4fv(projectionUniform, 1, GL_TRUE, projection);

    mat4 modelView(1.0f);

    vec4 red(1.0, 0.0, 0.0, 1.0);
    glUniform4fv(colorUniform, 1, red);
    glUniformMatrix4fv(modelViewUniform, 1, GL_TRUE, modelView);
    drawAxis();

    // todo multiply model transformations 

    vec4 white(1.0, 1.0, 1.0, 1.0);
    glUniform4fv(colorUniform, 1, white);
    glUniformMatrix4fv(modelViewUniform, 1, GL_TRUE, modelView);
    drawWireUnitCube();



    glutSwapBuffers();

    Angel::CheckError();
}

void reshape(int W, int H) {
    WINDOW_WIDTH = W;
    WINDOW_HEIGHT = H;
    glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
}

int main(int argc, char* argv[]) {
    glutInit(&argc, argv);
    glutInitContextVersion(3, 2);
    glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
    glutInitContextProfile(GLUT_CORE_PROFILE);

    glutSetOption(
        GLUT_ACTION_ON_WINDOW_CLOSE,
        GLUT_ACTION_GLUTMAINLOOP_RETURNS
    );

    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_3_2_CORE_PROFILE);
    glutCreateWindow("02561-02-02");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutReshapeWindow(WINDOW_WIDTH, WINDOW_HEIGHT);

    Angel::InitOpenGL();


    loadShader();
    buildUnitCube();
    buildAxis();

    Angel::CheckError();

    glutMainLoop();
}

1 个答案:

答案 0 :(得分:0)

您的代码请求核心配置文件上下文:

glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);

但它与Core Profile不完全兼容。在核心配置文件中,所有顶点数据都需要从缓冲区获取。不再支持为顶点数据传递客户端数组。这包括索引数据。所以不允许以下内容:

GLuint indices[8] = {
    0,1,
    0,2,
    0,3,
    4,5
};
glBindVertexArray(axisVertexArrayObject);
glDrawElements(GL_LINES, 8, GL_UNSIGNED_INT, indices);

您需要将索引存储在GL_ELEMENT_ARRAY_BUFFER中。扩展loadBufferData()函数的签名以获取索引数据,并添加代码以创建索引缓冲区:

GLuint loadBufferData(Vertex* vertices, int vertexCount
                      GLuint* indices, int indexCount) {
    ...

    GLuint indexBuffer;
    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(GLuint), indices, GL_STATIC_DRAW);

    return vertexArrayObject;
}

然后绘制函数看起来像这样:

glBindVertexArray(axisVertexArrayObject);
glDrawElements(GL_LINES, 8, GL_UNSIGNED_INT, 0);