0

VBO を使用して OpenGL でオブジェクトを描画する際に問題が発生しているようです。http://www.opengl.org/wiki/VBO_-_just_examples (番号 2)から例をコピーしようとしましたが、平面を画面に表示できません。

Vertex.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 からの抜粋 (三角形オブジェクトの作成):

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

createShader(GLenum , char *):

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

fragmentShader.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
}

頂点シェーダーがこれに影響を与えるとは知らなかったので、行列関数を使用しました。スタックの一番上にあるマトリックスに設定されたマトリックスを想定しました(描画する前にプッシュしたもの)。

これは間違った仮定です。非推奨のマトリックス スタックを参照する唯一の変数は、特別な (非推奨ですが) variable です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 に答える