Opengl 矩形不会渲染

Opengl Rectangle wont render

要么是我太笨,要么是我经验不足(可能两者都是),但我不知怎么地坚持使用 opengl 绘制一个简单的彩色矩形。这应该不是问题,因为我刚刚完成了一个简单的 opengl 模型加载器(但这是我的第一个项目,所以我只做了一次参考)。无论如何,除了蓝色背景,什么都没有出现。

我尝试为基本形状制作简单的 classes。这是矩形 class:

class AVRect{
private:
    AVcolor Color;
    GLuint VBO, VAO, EBO;
    GLuint indices[6] = {  // Note that we start from 0!
        0, 1, 3,   // First Triangle
        1, 2, 3    // Second Triangle
    };
public:
    GLfloat geometry[12];
    AVRect(int Drawmode, GLfloat x, GLfloat y, GLfloat x2, GLfloat y2,GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4,GLfloat r,GLfloat b,GLfloat g,GLfloat a);
    void Draw(Shader shader);
};

不用担心颜色。我只在源代码中设置了它,但它没有在其他任何地方使用 atm。我将在我得到使用固定颜色的矩形后立即实施它。

矩形来源 class:

#include "stdafx.h"
#include "Shapes.h"

AVRect::AVRect(int Drawmode,GLfloat x, GLfloat y, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4, GLfloat r, GLfloat b, GLfloat g, GLfloat a) {
    geometry[0] = x;
    geometry[1] = y;
    geometry[2] = 0.0f;
    geometry[3] = x2;
    geometry[4] = y2;
    geometry[5] = 0.0f;
    geometry[6] = x3;
    geometry[7] = y3;
    geometry[8] = 0.0f;
    geometry[9] = x4;
    geometry[10] = y4;
    geometry[11] = 0.0f;
    Color.r = r;
    Color.b = b;
    Color.g = g;
    Color.a = a;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(geometry), geometry, Drawmode);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, Drawmode);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

}

void AVRect::Draw(Shader shader) {
    glUseProgram(shader.Program);
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

主要内容不言自明:

// Bullethell.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <GL/glew.h>
#include <SDL.h>
#include <SDL_opengl.h>
#include <GLTextures.h>
#include <Shaders.h>
#include <ctime>
#include "Shapes.h"
#define HEIGHT 600
#define WIDTH 600

int main(int argc, char* args[])
{
    SDL_Window *window;
    SDL_Renderer *renderer;
    window = SDL_CreateWindow("BulletHell", 100, 100, HEIGHT, WIDTH, SDL_WINDOW_OPENGL);
    SDL_GLContext glcontext = SDL_GL_CreateContext(window);

    glewExperimental = GL_TRUE;
    if (GLEW_OK != glewInit())
    {
        // GLEW failed!
        printf("GLEW INIT FAILED!");
    }
    Shader basic("./shaders/colorTest/colorTest.vs", "./shaders/colorTest/colorTest.frag");
    AVRect test(GL_STATIC_DRAW,0.5f,0.5f,0.5f,-0.5f,-0.5f,-0.5f,0.5f,-0.5f,0.5f,0.9f,0.2f,0.5f);
    int error = 0;
    while (SDL_PollEvent(NULL))
    {
        clock_t start = clock();
        glClearColor(0.2, 0.2, 0.5, 1);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        test.Draw(basic);
        SDL_GL_SwapWindow(window);
        error = glGetError();
        if (error != GL_NO_ERROR)
            printf("GL ERROR:%d ", error);
        while (((clock() - start) * 1000 / CLOCKS_PER_SEC) <16)
            ;

        float MS = (float)((clock() - start) * 1000 / CLOCKS_PER_SEC);
        // Frames per seconds
        float FPS = 1000.0f / MS;
        //printf("%f \n",FPS);
        //    printf( "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
    }
    return 1;
}

着色器 class 已经过测试并且正在运行。着色器很简单,也应该可以工作(只传递值并分配固定颜色)。

我可能只是瞎了眼,因为我看不到错误。请帮我解决这个问题。


为了完整起见,这里是着色器源代码:

#include "stdafx.h"
#include "Shaders.h"

Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
{
    // 1. Retrieve the vertex/fragment source code from filePath
    std::string vertexCode;
    std::string fragmentCode;
    std::ifstream vShaderFile;
    std::ifstream fShaderFile;

    // ensures ifstream objects can throw exceptions:
    vShaderFile.exceptions (std::ifstream::badbit);
    fShaderFile.exceptions (std::ifstream::badbit);
    try
    {
        // Open files
        vShaderFile.open(vertexPath);
        fShaderFile.open(fragmentPath);
        std::stringstream vShaderStream, fShaderStream;
        // Read file's buffer contents into streams
        vShaderStream << vShaderFile.rdbuf();
        fShaderStream << fShaderFile.rdbuf();
        // close file handlers
        vShaderFile.close();
        fShaderFile.close();
        // Convert stream into string
        vertexCode = vShaderStream.str();
        fragmentCode = fShaderStream.str();
    }
    catch (std::ifstream::failure e)
    {
        std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
    }
    const GLchar* vShaderCode = vertexCode.c_str();
    const GLchar * fShaderCode = fragmentCode.c_str();
    // 2. Compile shaders
    GLuint vertex, fragment;
    GLint success;
    GLchar infoLog[512];
    // Vertex Shader
    vertex = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex, 1, &vShaderCode, NULL);
    glCompileShader(vertex);
    // Print compile errors if any
    glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertex, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // Fragment Shader
    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment, 1, &fShaderCode, NULL);
    glCompileShader(fragment);
    // Print compile errors if any
    glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragment, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // Shader Program
    this->Program = glCreateProgram();
    glAttachShader(this->Program, vertex);
    glAttachShader(this->Program, fragment);
    glLinkProgram(this->Program);
    // Print linking errors if any
    glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
    if (!success)
    {
        glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
    }
    // Delete the shaders as they're linked into our program now and no longer necessery
    glDeleteShader(vertex);
    glDeleteShader(fragment);

}
// Uses the current shader
void Shader::Use()
{
    glUseProgram(this->Program);
}

您正在绘制退化三角形,因此不会渲染任何像素。如果您查看 "rectangle" 的坐标,为了便于阅读,请间隔:

 0.5f,  0.5f,
 0.5f, -0.5f,
-0.5f, -0.5f,
 0.5f, -0.5f

可以看到第2个和第4个顶点坐标相同。您的顶点排列如下所示:

      0

2     1/3

将其与您的指数进行比较:

0, 1, 3,   // First Triangle
1, 2, 3    // Second Triangle

你会看到两个三角形都是退化的,因为它们的两个顶点是相同的。

您可能打算使用的坐标是:

 0.5f,  0.5f,
 0.5f, -0.5f,
-0.5f, -0.5f,
-0.5f,  0.5f

我实际上建议您对几何图形使用逆时针方向,因为这是 OpenGL 中的默认缠绕顺序。尽管这并不重要,除非您计划启用剔除。