【问题标题】:glDrawElements Fails to drawglDrawElements 绘制失败
【发布时间】:2013-12-13 13:02:19
【问题描述】:

我正在研究最终将成为地形抽屉的东西,但是目前我只是想获得一对基本的三角形来使用 glDrawElements 绘制。代码如下所示:

公共类 TerrainFlat 扩展 AbstractTerrain {

IntBuffer ib = BufferUtils.createIntBuffer(3);

 int vHandle = ib.get(0);
 int cHandle = ib.get(1);
 int iHandle = ib.get(2);

FloatBuffer vBuffer = BufferUtils.createFloatBuffer(19);
FloatBuffer cBuffer = BufferUtils.createFloatBuffer(18);
ShortBuffer iBuffer = BufferUtils.createShortBuffer(6);


@Override
public void initilize(){


    float[] vertexData = {50, 20, 100,      50, -20, 100,      10, -20, 100,             -10, -20, 100,     -50, -20, 100,     -50, 20, 100};
    float[] colorData = {1, 0, 0, 0, 1, 0, 0, 0, 1,  0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 0 };
    short[] indexData = {0,1,2,3,4,5};

    vBuffer.put(vertexData);
    vBuffer.flip();


    cBuffer.put(colorData);
    cBuffer.flip();


    iBuffer.put(indexData);
    iBuffer.flip();

  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_COLOR_ARRAY);

  glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iHandle);
  glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iBuffer, GL_STATIC_DRAW_ARB);
  glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);

  glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle);
  glBufferDataARB(GL_ARRAY_BUFFER_ARB, vBuffer, GL_STATIC_DRAW_ARB);
  glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);


  glBindBufferARB(GL_ARRAY_BUFFER_ARB, cHandle);
  glBufferDataARB(GL_ARRAY_BUFFER_ARB, cBuffer, GL_STATIC_DRAW_ARB);
  glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);






}

@Override
public void setUp(float posX, float posY, float posZ){



}

@Override
public void draw(){

                   glClear(GL_COLOR_BUFFER_BIT);

  glGenBuffersARB(ib);
  vHandle = ib.get(0);
  cHandle = ib.get(1);
  iHandle = ib.get(2);

  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_COLOR_ARRAY);

  glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle);
  glVertexPointer(3, GL_FLOAT,  3 << 2 , 0L);
  glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

  glBindBufferARB(GL_ARRAY_BUFFER_ARB, cHandle);
  glColorPointer(3, GL_FLOAT,  3 << 2  , 0L);
  glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

  glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iHandle);

  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0L);

  glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
  glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);


}

@Override
public void destroy(){
    ib.put(0, vHandle);
  ib.put(1, cHandle);
  ib.put(2, iHandle);
  glDeleteBuffersARB(ib);
} 



}

这并没有绘制任何东西,屏幕完全是黑色的。 GL_CULL_FACE 未启用,并且没有照明(或缺少照明)导致此错误。将数据绑定移动到 Draw() 函数中可以让它工作(如果你愿意,我可以在其中添加该代码)。然而,这意味着我创建了缓冲区的每个绘制函数(即:坏)。我完全想知道我在这里做错了什么,因为我已经把它四处移动并把它打傻了 4 天。

【问题讨论】:

  • 我很确定您不应该在每次绘制时都生成新的 VBO。如果您希望他们使用您在initialize (...) 中生成的数据,则不会。我会认真考虑将呼叫glGenBuffersARB (...) 转移到initialize (...)。也就是说,你为什么要为缓冲区对象使用 ARB 扩展?自 OpenGL 1.5 以来,它们一直是核心。
  • 我已经解决了,等 8 小时过去了我会发布解决方案。
  • 在这两种情况下,您的缓冲区数据步幅都应该为零。

标签: opengl drawing game-engine lwjgl


【解决方案1】:

您将 vHandle、cHandle 和 iHandle 设置为 0。

无论如何,您永远不需要在第 1 行创建 IntBuffer。替换

 int vHandle = ib.get(0);
 int cHandle = ib.get(1);
 int iHandle = ib.get(2);

 int vHandle = glGenBuffers();
 int cHandle = glGenBuffers();
 int iHandle = glGenBuffers();

【讨论】:

  • 这不会解决问题,因为每次调用 draw (...) 时 OP 仍在生成新的缓冲区。最终,GL 实现将用尽名称来给出,而不是首先清空缓冲区的名称会带来很多好处。部分解决方案是将非空白行 2-5 从 draw (...) 移动到 initialize (...)
猜你喜欢
  • 2014-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多