0

我似乎在使用 VBO 在 OpenGL 中绘制对象时遇到了一些麻烦。我试图从以下位置复制示例:http ://www.opengl.org/wiki/VBO__-_just_examples (第 2 号),但我无法让飞机出现在屏幕上。

顶点.h:

#include <freeglut>

struct Vertex {
    GLfloat position[3];
    GLfloat normal[3];
    GLfloat *uvs[2];
    unsigned short uvCount;
};

三角形.h:

#include <GL/glew.h>
#include "Vertex.h"

class Triangles {
public: 
    Triangles(GLuint program, Vertex *vertices, unsigned int vertexCount, unsigned int *indices[3], unsigned int indiceCount);
    ~Triangles();
    void Draw();

private:
    GLuint program;
    GLuint VertexVBOID;
    GLuint IndexVBOID;
    GLuint VaoID;

    unsigned int *indices[3];
    unsigned int indiceCount;
};

三角形.cpp:

#include "Triangles.h"
#include <stdio.h>
#include <stddef.h>

Triangles::Triangles(GLuint program, unsigned int *indices[3], unsigned int indiceCount) {
    memcpy(this->indices, indices, sizeof(int) * indiceCount * 3);
    this->indiceCount = indiceCount;
    this->program = program;

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

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

    GLuint attributeLocation = glGetAttribLocation(program, "position");
    glEnableVertexAttribArray(attributeLocation);
    glVertexAttribPointer(attributeLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *)(offsetof(Vertex, position)));

    attributeLocation = glGetAttribLocation(program, "normal");
    glEnableVertexAttribArray(attributeLocation);
    glVertexAttribPointer(attributeLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *)(offsetof(Vertex, normal)));

    glGenBuffers(1, &IndexVBOID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * 3 * indiceCount, indices, GL_STATIC_DRAW);
};

Triangles::~Triangles() {
    glDisableVertexAttribArray(glGetAttribLocation(program, "position"));
    glDisableVertexAttribArray(glGetAttribLocation(program, "normal"));

    glDeleteBuffers(1, &VertexVBOID);
    glDeleteBuffers(1, &IndexVBOID);
    glDeleteVertexArrays(1, &VaoID);
}

void Triangles::Draw() {
    glBindVertexArray(VaoID);
    glDrawElements(GL_TRIANGLES, indiceCount, GL_UNSIGNED_INT, 0);
};

摘自 main.cpp(创建 triagle 对象):

Vertex vertices[4];
vertices[0].position[0] = -1;
vertices[0].position[1] = 1;
vertices[0].position[2] = 0;
vertices[0].normal[0] = 0;
vertices[0].normal[0] = 0;
vertices[0].normal[0] = 1;
vertices[0].uvCount = 0;

vertices[1].position[0] = 1;
vertices[1].position[1] = 1;
vertices[1].position[2] = 0;
vertices[1].normal[0] = 0;
vertices[1].normal[0] = 0;
vertices[1].normal[0] = 1;
vertices[1].uvCount = 0;

vertices[2].position[0] = 1;
vertices[2].position[1] = -1;
vertices[2].position[2] = 0;
vertices[2].normal[0] = 0;
vertices[2].normal[0] = 0;
vertices[2].normal[0] = 1;
vertices[2].uvCount = 0;

vertices[3].position[0] = -1;
vertices[3].position[1] = -1;
vertices[3].position[2] = 0;
vertices[3].normal[0] = 0;
vertices[3].normal[0] = 0;
vertices[3].normal[0] = 1;
vertices[3].uvCount = 0;

unsigned int **indices;
indices = new unsigned int*[2];
indices[0] = new unsigned int[3];
indices[0][0] = 0;
indices[0][1] = 1;
indices[0][2] = 2;
indices[1] = new unsigned int[3];
indices[1][0] = 2;
indices[1][1] = 3;
indices[1][2] = 0;

Triangles *t = new Triangles(program, vertices, 4 indices, 2);

创建着色器(GLenum,字符 *):

GLuint createShader(GLenum type, char *file) {
    GLuint shader = glCreateShader(type);
    const char *fileData = textFileRead(file);
    glShaderSource(shader, 1, &fileData, NULL);

    glCompileShader(shader);
    return shader;
}

着色器加载:

    GLuint v = createShader(GL_VERTEX_SHADER);
    GLuint f = createShader(GL_FRAGMENT_SHADER, "fragmentShader.frag");

    program = glCreateProgram();

    glAttachShader(program, v);
    glAttachShader(program, f);
    glLinkProgram(program);

    glUseProgram(program);

vertexShader.vert:

in vec3 position;
in vec3 normal;

out vec3 a_normal;

void main() {
    gl_Position = vec4(position, 1.0);
}

片段着色器.frag:

in vec3 a_normal;

out vec4 out_color;

void main() {
    out_color = vec4(1.0, 1.0, 1.0, 1.0);
}

如果需要更多代码,请告诉我。作为旁注,一切都编译得很好,我只是看不到我在屏幕上构建的飞机(可能是因为我没有使用颜色?)

我的OpenGL信息如下:

  • 供应商:ATI Technologies Inc.
  • 渲染器:ATI Radeon HD 5700 系列
  • 版本:3.2.9756 兼容性配置文件上下文
  • 扩展: extensions = GL_AMDX_name_gen_delete GL_AMDX_random_access_target GL_AMDX_vertex_shader_tessellator GL_AMD_conservative_depth GL_AMD_draw_buffers_blend GL_AMD_performance_monitor GL_AMD_seamless_cubemap_per_texture GL_AMD_shader_stencil_export GL_AMD_texture
4

1 回答 1

0

回应您的评论:

不幸的是我不做错误检查

您应该始终添加一些 OpenGL 错误检查,它可以帮助您避免很多问题。它应该如下所示:

int err = glGetError();
if(err != 0) {
   //throw exception or log message or die or something
}

我使用矩阵函数是因为我没有意识到顶点着色器会影响它。我假设矩阵设置为堆栈顶部的矩阵(我在绘制之前推送的那个。)

这是一个不正确的假设。唯一引用已弃用的矩阵堆栈的变量是特殊的(尽管已弃用)变量gl_ModelViewProjectionMatrix。您目前拥有的只是一个未使用的未初始化矩阵,它完全忽略了您的矩阵堆栈。

至于指数,我不确定你的意思。我只是在纸上画了顶点,并以此为基础确定了索引。

我指的不是索引缓冲区中三角形的索引,而是 glAttrib* 函数的第一个参数。我想“属性位置”是比索引更正确的术语。

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, ...   //attrib location 0

glEnableVertexAttribArray(1);  
glVertexAttribPointer(1, ...   //attrib location 1

您似乎只是随机假设“0”和“1”映射到“位置”和“正常”。这不是一个安全的假设。您应该使用 glGetAttribLocation 查询“位置”和“正常”的属性位置值,然后将该值用于 glEnableVertexAttribArray 和 glVertexAttribPointer。

于 2012-09-25T20:31:47.363 回答