Open GL ES 2.0 Почему мой VBO не работает? - PullRequest
0 голосов
/ 03 марта 2019

Привет, я пытаюсь нарисовать простой четырехугольник с 2 треугольниками в OpenGL через vbo.Однако я просмотрел свой код несколько раз и не вижу, что мне не хватает.Я не эксперт по Open GL, код работал нормально без каких-либо буферов, однако, когда я переключился на VBO, я больше ничего не вижу.OpenGL также не предоставляет никаких полезных ошибок.

Image::Image(Graphics * GFX)
{

    glm::vec2 corners[2];
    corners[0] = glm::vec2(0, 0);
    corners[1] = glm::vec2(1, 1);

    vertices = new GLfloat[30]
    {
        //Vertices XYZ                      TexCoord X,Y
        corners[0].x, corners[0].y, 0.0f,   0,0,
        corners[0].x, corners[1].y, 0.0f,   0,1,
        corners[1].x, corners[0].y, 0.0f,   1,0,

        corners[1].x,corners[1].y,0.0f,     1,1,
        corners[0].x, corners[1].y,0.0f,    0,1,
        corners[1].x, corners[0].y, 0.0f,   1,0
    };

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //Setting up some stuff
    const char *vertexShaderSource =
        "attribute vec4 vPosition; \n"
        "attribute vec2 vTexCoord; \n"
        "void main() \n"
        "{ \n"
        " gl_Position = vPosition; \n"
        "} \n";
    const char *fragmentShaderSource =
        "precision mediump float; \n"
        "void main() \n"
        "{ \n"
        " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); \n"
        "} \n";


    // Load and compile the vertex/fragment shaders
    vertexShader = GFX->LoadShader(GL_VERTEX_SHADER, (const char*)vertexShaderSource);
    fragmentShader = GFX->LoadShader(GL_FRAGMENT_SHADER, (const char*)fragmentShaderSource);

    // Create the program object    
    programObject = glCreateProgram();


    // now we have the V and F shaders  attach them to the progam object
    glAttachShader(programObject, vertexShader);
    glAttachShader(programObject, fragmentShader);

    // Link the program
    glLinkProgram(programObject);
    // Check the link status

    // Link the program
    GLint AreTheylinked;
    glGetProgramiv(programObject, GL_LINK_STATUS, &AreTheylinked);
    if (!AreTheylinked)
    {
        GLint RetinfoLen = 0;
        // check and report any errors
        glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &RetinfoLen);
        if (RetinfoLen > 1)
        {
            GLchar* infoLog = (GLchar*)malloc(sizeof(char) * RetinfoLen);
            glGetProgramInfoLog(programObject, RetinfoLen, NULL, infoLog);
            fprintf(stderr, "Error linking program:\n%s\n", infoLog);
            free(infoLog);
        }
        glDeleteProgram(programObject);
    }

    positionLocation = glGetAttribLocation(programObject, "vPosition");
    textureCoordLocation = glGetAttribLocation(programObject, "vTexCoord");

    if (glGetError() == GL_NO_ERROR) {}
    else
        printf("Init failed!\n");
    //End setting up

}

Image::~Image()
{
}

void Image::Draw()
{
    std::cout << "Calling Draw on Image" << std::endl;
    glUseProgram(programObject);
    glEnable(GL_DEPTH_TEST);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    GLsizei stride = (5) * sizeof(GLfloat);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, 0);
    glEnableVertexAttribArray(0);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    if (glGetError() != GL_NO_ERROR)
    {
        printf("UI Draw error\n");
    }
    glDisableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

}

И как я загружаю шейдеры:

GLuint Graphics::LoadShader(GLenum type, const char *shaderSrc)
{
    // 1st create the shader object
    GLuint TheShader = glCreateShader(type);

    if (TheShader == 0) return FALSE; // can't allocate so stop.

// pass the shader source then compile it
    glShaderSource(TheShader, 1, &shaderSrc, NULL);
    glCompileShader(TheShader);

    GLint  IsItCompiled;

    // After the compile we need to check the status and report any errors
    glGetShaderiv(TheShader, GL_COMPILE_STATUS, &IsItCompiled);
    if (!IsItCompiled)
    {
        GLint RetinfoLen = 0;
        glGetShaderiv(TheShader, GL_INFO_LOG_LENGTH, &RetinfoLen);
        if (RetinfoLen > 1)
        { // standard output for errors
            char* infoLog = (char*)malloc(sizeof(char) * RetinfoLen);
            glGetShaderInfoLog(TheShader, RetinfoLen, NULL, infoLog);
            fprintf(stderr, "Error compiling this shader:\n%s\n", infoLog);
            free(infoLog);
        }
        glDeleteShader(TheShader);
        return FALSE;
    }
    return TheShader;
}

Ранее он работал нормально без буфера и видел белый квадратиспользуя:

glVertexAttribPointer(0, 6, GL_FLOAT, GL_FALSE, 0, vertices);

Но теперь я хочу добавить текстурные координаты в мой квад через VBO, но больше ничего не отображается.

Smoothy101

1 Ответ

0 голосов
/ 04 марта 2019

Создание вашего буфера выглядит хорошо - проблема в настройке указателя вашего атрибута.Вы добавили координаты текстуры, которые изменили расположение данных для каждой вершины, но вы не обработали это в своем коде.

Вам нужно что-то вроде этого:

glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, stride, 0);
glVertexAttribPointer(textureCoordLocation, 2, GL_FLOAT, GL_FALSE, stride, 8);

...не это:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, 0);
...