【发布时间】:2015-05-27 09:33:45
【问题描述】:
正如标题中所述,我从 glDrawElements 收到 GL_INVALID_OPERATION 错误,但是,这只发生在 GL 3.1 以上的 GL 上下文中,在 3.1 及以下的上下文中,它可以正常呈现,没有任何问题。我的模型是这样加载的:
public IModel LoadData( Shape a_Shape ) {
int VertexStride = BlittableValueType<Vertex>.Stride;
int IndexStride = sizeof ( uint );
m_Backing = a_Shape;
m_GLDataBuffer = GL.GenBuffer( );
GL.BindBuffer( BufferTarget.ArrayBuffer, m_GLDataBuffer );
GL.BufferData( BufferTarget.ArrayBuffer, ( IntPtr ) ( m_Backing.Vertices.Count * VertexStride ), m_Backing.Vertices.ToArray( ), BufferUsageHint.StaticDraw );
m_GLIndexBuffer = GL.GenBuffer( );
GL.BindBuffer( BufferTarget.ElementArrayBuffer, m_GLIndexBuffer );
GL.BufferData( BufferTarget.ElementArrayBuffer, ( IntPtr ) ( m_Backing.Indices.Count * IndexStride ), m_Backing.Indices.ToArray( ), BufferUsageHint.StaticDraw );
GL.EnableVertexAttribArray( 0 );
GL.EnableVertexAttribArray( 1 );
GL.EnableVertexAttribArray( 2 );
GL.VertexAttribPointer( 0, 3, VertexAttribPointerType.Float, false, VertexStride, 0 );
GL.VertexAttribPointer( 1, 3, VertexAttribPointerType.Float, false, VertexStride, ( sizeof ( float ) * 3 ) );
GL.VertexAttribPointer( 2, 2, VertexAttribPointerType.Float, false, VertexStride, ( sizeof ( float ) * 6 ) );
GL.DisableVertexAttribArray( 2 );
GL.DisableVertexAttribArray( 1 );
GL.DisableVertexAttribArray( 0 );
GL.BindBuffer( BufferTarget.ArrayBuffer, 0 );
GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 );
return this;
}
其中 a_Shape 只是从文件加载或由用户定义的任意形状,它包含一个顶点列表,其中仅包含两个 Vector3(位置和法线)和一个 Vector2(TexCoords)。然后我用这个函数绘制模型:
void IModel.Draw( ) {
GL.BindBuffer( BufferTarget.ElementArrayBuffer, m_GLIndexBuffer );
GL.EnableVertexAttribArray( 0 );
GL.EnableVertexAttribArray( 1 );
GL.EnableVertexAttribArray( 2 );
GL.DrawElements( PrimitiveType.Triangles, m_Backing.Indices.Count, DrawElementsType.UnsignedInt, 0 ); //This is the line that's producing the Error
GL.DisableVertexAttribArray( 2 );
GL.DisableVertexAttribArray( 1 );
GL.DisableVertexAttribArray( 0 );
GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 );
}
正如我所说,在我尝试使用高于 3.1 版本的 GL 上下文之前,这一切正常。我真的很困惑,因为它在 3.1 以上就无法工作。我查看了它,我在 OpenGL 参考上说:
如果非零缓冲区对象名称绑定到启用的数组或元素数组并且缓冲区对象的数据存储当前已映射,则会生成 GL_INVALID_OPERATION。
不过,我不太明白这意味着什么。所以我想我的问题是:什么可能导致 glDrawElements 只能在某些情况下工作,我该如何解决它?还是我的代码中有一些我没有看到的问题?
任何帮助都将不胜感激,经过大约 5 个小时的努力,我想是时候寻求帮助了。
更新
所以我将我的代码修改为以下内容:
public IModel LoadData( Shape a_Shape ) {
m_Backing = a_Shape;
Single[] Positions = new Single[a_Shape.Vertices.Count * 3];
Single[] Normals = new Single[a_Shape.Vertices.Count * 3];
Single[] TexCoords = new Single[a_Shape.Vertices.Count * 2];
for ( int i = 0; i < Positions.Length; i += 3 ) {
Positions[i + 0] = a_Shape.Vertices[i / 3].Position.X;
Positions[i + 1] = a_Shape.Vertices[i / 3].Position.Y;
Positions[i + 2] = a_Shape.Vertices[i / 3].Position.Z;
Normals[i + 0] = a_Shape.Vertices[i / 3].Normal.X;
Normals[i + 1] = a_Shape.Vertices[i / 3].Normal.Y;
Normals[i + 2] = a_Shape.Vertices[i / 3].Normal.Z;
}
for ( int i = 0; i < TexCoords.Length; i += 2 ) {
TexCoords[i + 0] = a_Shape.Vertices[i / 2].TexCoord.X;
TexCoords[i + 1] = a_Shape.Vertices[i / 2].TexCoord.Y;
}
m_GLVertexArray = GL.GenVertexArray( );
GL.BindVertexArray( m_GLVertexArray );
m_GLIndexBuffer = GL.GenBuffer( );
GL.GenBuffers( 3, m_GLDataBuffers );
GL.EnableVertexAttribArray( 0 );
GL.EnableVertexAttribArray( 1 );
GL.EnableVertexAttribArray( 2 );
GL.BindBuffer( BufferTarget.ElementArrayBuffer, m_GLIndexBuffer );
GL.BufferData( BufferTarget.ElementArrayBuffer, ( IntPtr ) ( sizeof ( uint ) * a_Shape.Indices.Count ), a_Shape.Indices.ToArray( ), BufferUsageHint.StaticDraw );
GL.BindBuffer( BufferTarget.ArrayBuffer, m_GLDataBuffers[0] ); // Bind the Position Buffer
GL.BufferData( BufferTarget.ArrayBuffer, ( IntPtr ) ( sizeof ( Single ) * Positions.Length ), Positions, BufferUsageHint.StaticDraw );
GL.VertexAttribPointer( 0, 3, VertexAttribPointerType.Float, false, 0, 0 );
GL.BindBuffer( BufferTarget.ArrayBuffer, m_GLDataBuffers[1] ); // Bind the Normal Buffer
GL.BufferData( BufferTarget.ArrayBuffer, ( IntPtr ) ( sizeof ( Single ) * Normals.Length ), Normals, BufferUsageHint.StaticDraw );
GL.VertexAttribPointer( 1, 3, VertexAttribPointerType.Float, false, 0, 0 );
GL.BindBuffer( BufferTarget.ArrayBuffer, m_GLDataBuffers[2] ); // Bind the TexCoord Buffer
GL.BufferData( BufferTarget.ArrayBuffer, ( IntPtr ) ( sizeof ( Single ) * TexCoords.Length ), TexCoords, BufferUsageHint.StaticDraw );
GL.VertexAttribPointer( 2, 2, VertexAttribPointerType.Float, false, 0, 0 );
GL.BindBuffer( BufferTarget.ArrayBuffer, 0 );
GL.BindBuffer( BufferTarget.ElementArrayBuffer, 0 );
GL.BindVertexArray( 0 );
return this;
}
对于加载和:
void IModel.Draw( ) {
GL.BindVertexArray( m_GLVertexArray );
GL.DrawElements( PrimitiveType.Triangles, m_Backing.Indices.Count, DrawElementsType.UnsignedInt, 0 );
GL.BindVertexArray( 0 );
}
对于绘图,使用我从 Reto 的评论中可以找到的内容。我不再收到任何 GL 错误,但现在根本没有任何渲染。我又看不到问题出在哪里。
编辑 修复了未正确将顶点转换为位置、法线和 TexCoord 数组的问题。
【问题讨论】:
-
您可能会获得 3.1 以上版本的核心配置文件上下文,并且您的代码与核心配置文件不兼容。例如:stackoverflow.com/questions/29336227/….
-
@RetoKoradi 我已经使用顶点数组更新了我的代码,但是现在什么都没有渲染。我已经用我当前的代码更新了我的主要帖子。
-
我刚刚意识到我实际上并没有正确地将数据存储在我的数组中。我将编辑我的主要帖子以解决此问题。
-
如果支持,您可以请求兼容性配置文件。
-
我没有看到使用 OpenTK 的方法,我会继续寻找,但这不是我所看到的。