2016-06-28 62 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)'在大多數平臺上將是'4'或'8',而不是像你希望的'data'的長度。傳遞一個單獨的'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。你需要的是整個數組的大小,以字節爲單位。

下面是你們班的功能不起作用

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

這是因爲的sizeof(數據)是不一樣的,如第一種情況。它是由@genpfault指出的4(32位)或8(64位)。簡單的解決方案將如下所示更改您的功能。

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); 
} 
在此函數「包含numElements」

是您的無效*數據點和「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 

注意:這被編譯上的窗口在視覺工作室32位,因此指針大小爲4個字節。如果我將它編譯爲64位,那將是8。

+0

謝謝!我設法讓它使用矢量工作。真酷! – Talesseed

+0

您可以隨時打印尺寸並驗證其正確性,無論您使用哪種方法。在之前的評論中,@genpfault建議使用'std :: vector'。一旦有人明白爲什麼一段代碼無法按預期工作,那麼它很容易。祝你好運。 – Harish

+0

是的,這很容易。對於大小我使用data.size()* sizeof(T)其中T模板我定義:) – Talesseed