glDrawElements分段错误

时间:2012-02-05 18:33:01

标签: c++ opengl

我目前正在尝试使用VBO绘制对象。 在Cube-Class中,我想出了测试VBO的功能,我创建了这样的VBO:

//Vertex
glGenBuffers(1, &m_bufVertex);
glBindBuffer(GL_ARRAY_BUFFER, m_bufVertex);
glBufferData(GL_ARRAY_BUFFER, 6*4*3*sizeof(GLfloat), vertex_data, GL_STATIC_DRAW);
//TexCoord
glGenBuffers(1, &m_bufTexCoord);
glBindBuffer(GL_ARRAY_BUFFER, m_bufTexCoord);
glBufferData(GL_ARRAY_BUFFER, 6*4*2*sizeof(GLfloat), texcoord_data, GL_STATIC_DRAW);
//Index
glGenBuffers(1,&m_bufIndex);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_bufIndex);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,24*sizeof(GLuint), indices, GL_STATIC_DRAW);

我已经仔细检查了数据是否在缓冲区中,例如像这样(顶点缓冲区在那时被绑定):

GLfloat* test = (GLfloat *) glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
for (unsigned int i = 0; i < 6*4*3; i++)
    cout << "Value " << i << " = " << test[i] << endl;

所以数据应该是它应该的位置,因此问题似乎在于Render-Function。调用glDrawElements()或glDrawArrays()时会发生分段错误。 这是代码:

glBindTexture(GL_TEXTURE_2D, m_texture);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// some translation, currently fixed, just testing code
glTranslatef(0.0f, 0.0f, -200.0f);
glRotatef(30.f, 1.f, 0.f, 0.f);
glRotatef(30.f, 0.f, 1.f, 0.f);
glRotatef(30.f, 0.f, 0.f, 1.f);
// enable client states
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// set pointers
glBindBuffer(GL_ARRAY_BUFFER, m_bufVertex);
glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, m_bufTexCoord);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bufIndex);
// just error check to see if something went wrong previously
GLenum err = glGetError();
if (GL_NO_ERROR != err)
    cout << "GL: " << err << " - " << gluErrorString(err) << endl;
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, 0);
// disable state and pop matrix
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();

我假设我使用的指针不正确或glDrawElements(),但我不知道是什么。 更多信息: 该代码使用GNU-toolchain和GLEW在MacOSX Lion(OpenGL2.1)上编译。

编辑:

GLfloat vertex_data[6*4*3] = {-m_fSize, -m_fSize, -m_fSize,
                       -m_fSize,  m_fSize, -m_fSize,
                        m_fSize,  m_fSize, -m_fSize,
                        m_fSize, -m_fSize, -m_fSize,
                        -m_fSize, -m_fSize, m_fSize,
                        -m_fSize,  m_fSize, m_fSize,
                         m_fSize,  m_fSize, m_fSize,
                         m_fSize, -m_fSize, m_fSize,
                       -m_fSize, -m_fSize, -m_fSize,
                       -m_fSize,  m_fSize, -m_fSize,
                       -m_fSize,  m_fSize,  m_fSize,
                       -m_fSize, -m_fSize,  m_fSize,
                        m_fSize, -m_fSize, -m_fSize,
                        m_fSize,  m_fSize, -m_fSize,
                        m_fSize,  m_fSize,  m_fSize,
                        m_fSize, -m_fSize,  m_fSize,
                       -m_fSize, -m_fSize,  m_fSize,
                       -m_fSize, -m_fSize, -m_fSize,
                        m_fSize, -m_fSize, -m_fSize,
                        m_fSize, -m_fSize,  m_fSize,
                        -m_fSize, m_fSize,  m_fSize,
                        -m_fSize, m_fSize, -m_fSize,
                         m_fSize, m_fSize, -m_fSize,
                        m_fSize, m_fSize,  m_fSize};
 GLfloat texcoord_data[6*4*2] = {0, 0, 0, 1, 1, 1, 1, 
                                0, 0, 0, 0, 1, 1, 1, 
                                1, 0, 0, 0, 0, 1, 1, 
                                1, 1, 0, 0, 0, 0, 1,
                                1, 1, 1, 0, 0, 1, 0, 
                                0, 1, 0, 1, 1, 0, 1,
                                0, 0, 1, 0, 1, 1};
GLuint indices[24] = {0,1,2,3,
                     4,5,6,7,
                     8,9,10,11,
                     12,13,14,15,
                     16,17,18,19,
                     20,21,22,23};

我知道定义每个顶点而不仅仅是8 ...

EDIT2: makefile:

OUT = bin/test
CC = g++
INCDIR = inc
OBJDIR = obj
SRCDIR = src
INC = -I$(INCDIR) -I/opt/local/include
LIBS = -L/opt/local/lib -lGLEW -lsfml-graphics -lsfml-window -lsfml-system -framework AGL -framework OpenGL -framework Foundation

_OBJS = Main.o \
    Timer.o \
    Cube.o \
    chrono.o process_cpu_clocks.o thread_clock.o error_code.o

OBJS = $(patsubst %,$(OBJDIR)/%,$(_OBJS))

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp 
$(CC) -c $(INC) -o $@ $< $(CFLAGS) 


$(OUT): $(OBJS)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
strip $(OUT)

clean:
rm -f $(OBJDIR)/*.o $(OUT)

2 个答案:

答案 0 :(得分:3)

我遇到了完全相同的问题。问题是SFML内部使用 glEnableClientState(GL_COLOR_ARRAY)和 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 所以如果你不自己使用它们,你需要禁用它们。

或者您可以使用sf :: Window而不是sf :: RenderWindow,因为它没有在内部设置任何OpenGL状态,我选择这样做。

Post on the SFML forum with this exact problem

答案 1 :(得分:1)

您是否有可能在之前的绘图中启用顶点数组?例如,如果您执行以下操作:

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(...);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(...);
glDrawElements(...); // draw first object

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(...);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(...);
glDrawElements(...); // draw second object

第二个glDrawElements可能会崩溃,因为正常数组仍然启用但可能不适合第二次绘制。