2016-06-28 5 views
0

頂点バッファオブジェクトやカラーバッファのようなOpenGLバッファを扱うクラスを作成したかったのです。ここでカスタムOpenGLバッファクラスに何も表示されない

はbuffer.hです:

#pragma once 
#include <GL/glew.h> 

class glBuffer 
{ 
public: 
    glBuffer(GLenum target); 
    void setdata(const void *data, GLenum mode); 
    void bind(GLuint index, GLint valuePerVertex, GLenum variableType = GL_FLOAT, GLsizei stride = 0, int offset = 0); 
    void unbind(); 
    GLuint getBufferID() const; 
    ~glBuffer(); 

private: 
    bool m_active; 
    GLuint m_buffer; 
    GLuint m_index; 
    GLenum m_target; 
}; 

そしてbuffer.cpp:ここ

#include "buffer.h" 
#include <GL/glew.h> 
#include <iostream> 


glBuffer::glBuffer(GLenum target) 
{ 
    m_target = target; 
    m_active = false; 
    glGenBuffers(1, &m_buffer); 
} 

void glBuffer::setdata(const void *data, GLenum mode) 
{ 
    glBindBuffer(m_target, m_buffer); 
    glBufferData(m_target, sizeof(data), data, mode); 
    glBindBuffer(m_target, 0); 
} 

void glBuffer::bind(GLuint index, GLint valuePerVertex, GLenum variableType, GLsizei stride, int offset) 
{ 
    m_active = true; 
    m_index = index; 
    glEnableVertexAttribArray(m_index); 
    glBindBuffer(m_target, m_buffer); 
    glVertexAttribPointer(
     m_index, 
     valuePerVertex,  
     variableType,  
     GL_FALSE,   //normalized? 
     stride,    
     (void*)offset  //buffer offset 
    ); 
} 

void glBuffer::unbind() 
{ 
    m_active = false; 
    glBindBuffer(m_target, 0); 
    glDisableVertexAttribArray(m_index); 
} 

GLuint glBuffer::getBufferID() const 
{ 
    return m_buffer; 
} 


glBuffer::~glBuffer() 
{ 
    if (!m_active){ 
     unbind(); 
    } 
    glDeleteBuffers(1, &m_buffer); 
} 

は私#include "buffer.h"私のアプリケーションでそれを使用する方法です:

glBuffer vbo(GL_ARRAY_BUFFER); 
vbo.setdata(color_buffer_data, GL_STATIC_DRAW); 
vbo.bind(0, 3); 

置き換え:

GLuint vbo; 
glGenBuffers(1, &vbo); 
glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STATIC_DRAW); 
glEnableVertexAttribArray(0); 
glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glVertexAttribPointer(
    0,     // attribute 0. No particular reason for 0, but must match the layout in the shader. 
    3,     // size 
    GL_FLOAT,   // type 
    GL_FALSE,   // normalized? 
    0,     // stride 
    (void*)0   // array buffer offset 
); 

コンパイルして実行すると、黒いウィンドウが表示され、何も描画されません。

何が起こっていますか?

PS:私はvs、glfw3、glewを使用しています。

+1

[mcve]で編集します。あなたがコア・コンテキストで、VAOを忘れていることはわかっています。 – genpfault

+3

また、 'glBuffer :: setdata()'の 'sizeof(data)'は、あなたが望むような 'data'の長さではなく、ほとんどのプラットフォームで' 4'または '8'になります。別の 'size'引数を渡すか、' std :: array <> '/' std :: vector <> 'のようなコンテナを使います。 – genpfault

答えて

2

は、ここでバッファデータ

glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STATIC_DRAW); 

私はあなたのvertex_buffer_dataは、この作業の理由である配列であることを想定していますを設定するための作業コードです。これをvoid *にキャストしているので、ポインタのsizeofを単純に呼び出すことはできません。必要なのは、配列全体のサイズ(バイト)です。

は、ここではsizeof(データ)が最初のケースと同じではないので、これは

void glBuffer::setdata(const void *data, GLenum mode) 
{ 
    glBindBuffer(m_target, m_buffer); 
    glBufferData(m_target, sizeof(data), data, mode); 
    glBindBuffer(m_target, 0); 
} 

動作しませんあなたのクラスであなたの関数です。 @genpfaultによって指摘されているように、4(32ビット)または8(64ビット)のいずれかです。簡単な解決策は、以下のように機能を変更することです。この関数「numElements」で

void glBuffer::setdata(const void *data, int numElements, size_t elementSize, GLenum mode) 
{ 
    glBindBuffer(m_target, m_buffer); 
    glBufferData(m_target, numElements * elementSize, data, mode); 
    glBindBuffer(m_target, 0); 
} 

はあなたのvoid *型のデータ点と「elementSize」に、各要素の大きさである配列の要素数です。ここで

は、上記の機能

float vertex_buffer_data[9] = {0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f}; 
glBuffer vbo(GL_ARRAY_BUFFER); 
vbo.setdata(vertex_buffer_data, 9, sizeof(float), GL_STATIC_DRAW); 
vbo.bind(0, 3); 

のコード例であり、それは動作するはずです。あなたがまだ混乱している場合は、コードが機能しなかった理由を示す小さなサンプルプログラムがあります。

#include "stdafx.h" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int a[5] = {1, 2, 3, 4, 5}; 
    void* ptr = a; 
    printf(" sizeof(a) = %d \n", sizeof(a)); 
    printf(" sizeof(a[0]) = %d \n", sizeof(a[0])); 
    printf(" sizeof(ptr) = %d \n", sizeof(ptr)); 
    getchar(); 

    return 0; 
} 

出力:

sizeof(a) = 20 
sizeof(a[0]) = 4 
sizeof(ptr) = 4 

注:これは、したがって、ポインタのサイズは4バイトであり、Visual StudioでWindows 32ビットでコンパイルしました。私が64ビットでコンパイルすると8になります。

+0

ありがとう!私はそれをベクトルを使って動作させることができました。すごくかっこいい ! – Talesseed

+0

いつでもサイズを印刷して、どちらの方法で正しいかを確認するだけで済みます。'std :: vector'の使用は、@ genpfaultによって以前のコメントで提案されました。コードの一部が意図したとおりに動作しない理由を誰かが理解すると、そこから簡単に実行できます。がんばろう。 – Harish

+0

はい、かなり簡単です。サイズについては、data.size()* sizeof(T)テンプレートを使用しています。 – Talesseed

関連する問題