GL11.glDrawElements 无效
GL11.glDrawElements does not work
首先,我使用的是 LWJGL 3 和 OpenGL 3.2
我正在尝试将 "indices" 与函数 GL11.glDrawElements 一起使用,但 window 中没有任何渲染。
缓冲区生成代码(没有真正使用索引,但我认为它仍然可以工作):
public void updateBuffers(Game game, int positionsAttrib, int texCoordsAttrib) { // positionsAttrib and texCoordsAttrib are pointer to shader program attribs
FloatBuffer positionsBuffer = null;
FloatBuffer texCoordsBuffer = null;
IntBuffer indicesBuffer = null;
try {
this.vertexCount = this.tiles.size() * 4;
positionsBuffer = MemoryUtil.memAllocFloat( this.tiles.size() * 3 * 4 );
texCoordsBuffer = MemoryUtil.memAllocFloat( this.tiles.size() * 2 * 4 );
indicesBuffer = MemoryUtil.memAllocInt( this.vertexCount );
int i = 0;
for ( Entry<TilePosition, Tile> tilesEntry : this.tiles.entrySet() ) {
TilePosition tilePosition = tilesEntry.getKey();
Tile tile = tilesEntry.getValue();
String tileTextureIdentifier = tile.getTextureIdentifier();
TextureDefinition tileTextureDefinition = game.getTexturesManager().getTextureDefinition("tiles");
Rectangle tileTextureRectangle = tileTextureDefinition.getTilePosition( tileTextureIdentifier );
if ( tileTextureRectangle == null ) continue;
positionsBuffer.put( tilePosition.getX() ).put( tilePosition.getY() + 1 ).put( 0 );
positionsBuffer.put( tilePosition.getX() + 1 ).put( tilePosition.getY() + 1 ).put( 0 );
positionsBuffer.put( tilePosition.getX() + 1 ).put( tilePosition.getY() ).put( 0 );
positionsBuffer.put( tilePosition.getX() ).put( tilePosition.getY() ).put( 0 );
texCoordsBuffer.put( tileTextureRectangle.x ).put( tileTextureRectangle.y );
texCoordsBuffer.put( tileTextureRectangle.x + tileTextureRectangle.width ).put( tileTextureRectangle.y );
texCoordsBuffer.put( tileTextureRectangle.x + tileTextureRectangle.width ).put( tileTextureRectangle.y + tileTextureRectangle.height );
texCoordsBuffer.put( tileTextureRectangle.x ).put( tileTextureRectangle.y + tileTextureRectangle.height );
indicesBuffer.put( i ).put( i + 1 ).put( i + 2 ).put( i + 3 );
i += 4;
}
positionsBuffer.flip();
texCoordsBuffer.flip();
indicesBuffer.flip();
this.vao.bind(); // vbo and vao are class VertexBufferObject and VertexArrayObject which save internal id of buffers and most usefull functions
this.positionsVbo.bind( GL15.GL_ARRAY_BUFFER );
VertexBufferObject.uploadData( GL15.GL_ARRAY_BUFFER, positionsBuffer, GL15.GL_STATIC_DRAW );
ShaderProgram.pointVertexAttribute( positionsAttrib, 3, 0, 0 );
this.texCoordsVbo.bind( GL15.GL_ARRAY_BUFFER );
VertexBufferObject.uploadData( GL15.GL_ARRAY_BUFFER, texCoordsBuffer, GL15.GL_STATIC_DRAW );
ShaderProgram.pointVertexAttribute( texCoordsAttrib, 2, 0, 0 );
this.indicesVbo.bind( GL15.GL_ELEMENT_ARRAY_BUFFER );
VertexBufferObject.uploadData( GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW );
VertexArrayObject.unbind();
} finally {
if ( positionsBuffer != null ) MemoryUtil.memFree( positionsBuffer );
if ( texCoordsBuffer != null ) MemoryUtil.memFree( texCoordsBuffer );
if ( indicesBuffer != null ) MemoryUtil.memFree( indicesBuffer );
}
}
使用的着色器程序:
// scene.vs :
#version 330 // edit : I have to change this line because of OpenGL used version
layout (location=0) in vec3 position;
layout (location=1) in vec2 texCoord;
out vec2 outTexCoord;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
void main() {
mat4 mvp = projection * view * model;
gl_Position = mvp * vec4( position, 1.0 );
outTexCoord = texCoord;
}
// scene.fs :
#version 330
in vec2 outTexCoord;
out vec4 fragColor;
uniform sampler2D textureSampler;
void main() {
vec3 vertexColor = vec3( 1.0, 1.0, 1.0 );
vec4 textureColor = texture( textureSampler, outTexCoord );
fragColor = vec4( vertexColor, 1.0 ) * textureColor;
}
渲染函数:
private void beginRender(Game game, int positionsAttrib, int texCoordsAttrib) {
Texture texture = game.getTexturesManager().getTextureDefinition("tiles").getTexture();
GL13.glActiveTexture( GL13.GL_TEXTURE0 );
texture.bind();
this.vao.bind();
ShaderProgram.enableVertexAttribute( positionsAttrib );
ShaderProgram.enableVertexAttribute( texCoordsAttrib );
}
private void endRender(Game game, int positionsAttrib, int texCoordsAttrib) {
ShaderProgram.disableVertexAttribute( positionsAttrib );
ShaderProgram.disableVertexAttribute( texCoordsAttrib );
VertexArrayObject.unbind();
Texture.unbind();
}
// render is called by render loop between clear and swapbuffer GL functions
public void render(Game game, int positionsAttrib, int texCoordsAttrib) {
this.beginRender( game, positionsAttrib, texCoordsAttrib );
GL11.glDrawElements( GL11.GL_QUADS, this.vertexCount, GL11.GL_UNSIGNED_INT, 0 );
this.endRender( game, positionsAttrib, texCoordsAttrib );
}
我不确定它是否很清楚,尤其是我的英语大概..
您没有明确说明,但看起来您正在使用核心配置文件(您应该这样做)。但是,如果是这样,GL_QUADS
将不可用,您的绘图调用只会导致 GL_INVALID_ENUM
错误。
附带说明:既然你说你使用 OpenGL 4.5,我强烈建议你在开发过程中使用 OpenGL 的 debug output 功能,它将更容易发现和解释任何 GL 错误,并且可能此外提供有用的性能提示。
首先,我使用的是 LWJGL 3 和 OpenGL 3.2
我正在尝试将 "indices" 与函数 GL11.glDrawElements 一起使用,但 window 中没有任何渲染。
缓冲区生成代码(没有真正使用索引,但我认为它仍然可以工作):
public void updateBuffers(Game game, int positionsAttrib, int texCoordsAttrib) { // positionsAttrib and texCoordsAttrib are pointer to shader program attribs
FloatBuffer positionsBuffer = null;
FloatBuffer texCoordsBuffer = null;
IntBuffer indicesBuffer = null;
try {
this.vertexCount = this.tiles.size() * 4;
positionsBuffer = MemoryUtil.memAllocFloat( this.tiles.size() * 3 * 4 );
texCoordsBuffer = MemoryUtil.memAllocFloat( this.tiles.size() * 2 * 4 );
indicesBuffer = MemoryUtil.memAllocInt( this.vertexCount );
int i = 0;
for ( Entry<TilePosition, Tile> tilesEntry : this.tiles.entrySet() ) {
TilePosition tilePosition = tilesEntry.getKey();
Tile tile = tilesEntry.getValue();
String tileTextureIdentifier = tile.getTextureIdentifier();
TextureDefinition tileTextureDefinition = game.getTexturesManager().getTextureDefinition("tiles");
Rectangle tileTextureRectangle = tileTextureDefinition.getTilePosition( tileTextureIdentifier );
if ( tileTextureRectangle == null ) continue;
positionsBuffer.put( tilePosition.getX() ).put( tilePosition.getY() + 1 ).put( 0 );
positionsBuffer.put( tilePosition.getX() + 1 ).put( tilePosition.getY() + 1 ).put( 0 );
positionsBuffer.put( tilePosition.getX() + 1 ).put( tilePosition.getY() ).put( 0 );
positionsBuffer.put( tilePosition.getX() ).put( tilePosition.getY() ).put( 0 );
texCoordsBuffer.put( tileTextureRectangle.x ).put( tileTextureRectangle.y );
texCoordsBuffer.put( tileTextureRectangle.x + tileTextureRectangle.width ).put( tileTextureRectangle.y );
texCoordsBuffer.put( tileTextureRectangle.x + tileTextureRectangle.width ).put( tileTextureRectangle.y + tileTextureRectangle.height );
texCoordsBuffer.put( tileTextureRectangle.x ).put( tileTextureRectangle.y + tileTextureRectangle.height );
indicesBuffer.put( i ).put( i + 1 ).put( i + 2 ).put( i + 3 );
i += 4;
}
positionsBuffer.flip();
texCoordsBuffer.flip();
indicesBuffer.flip();
this.vao.bind(); // vbo and vao are class VertexBufferObject and VertexArrayObject which save internal id of buffers and most usefull functions
this.positionsVbo.bind( GL15.GL_ARRAY_BUFFER );
VertexBufferObject.uploadData( GL15.GL_ARRAY_BUFFER, positionsBuffer, GL15.GL_STATIC_DRAW );
ShaderProgram.pointVertexAttribute( positionsAttrib, 3, 0, 0 );
this.texCoordsVbo.bind( GL15.GL_ARRAY_BUFFER );
VertexBufferObject.uploadData( GL15.GL_ARRAY_BUFFER, texCoordsBuffer, GL15.GL_STATIC_DRAW );
ShaderProgram.pointVertexAttribute( texCoordsAttrib, 2, 0, 0 );
this.indicesVbo.bind( GL15.GL_ELEMENT_ARRAY_BUFFER );
VertexBufferObject.uploadData( GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW );
VertexArrayObject.unbind();
} finally {
if ( positionsBuffer != null ) MemoryUtil.memFree( positionsBuffer );
if ( texCoordsBuffer != null ) MemoryUtil.memFree( texCoordsBuffer );
if ( indicesBuffer != null ) MemoryUtil.memFree( indicesBuffer );
}
}
使用的着色器程序:
// scene.vs :
#version 330 // edit : I have to change this line because of OpenGL used version
layout (location=0) in vec3 position;
layout (location=1) in vec2 texCoord;
out vec2 outTexCoord;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
void main() {
mat4 mvp = projection * view * model;
gl_Position = mvp * vec4( position, 1.0 );
outTexCoord = texCoord;
}
// scene.fs :
#version 330
in vec2 outTexCoord;
out vec4 fragColor;
uniform sampler2D textureSampler;
void main() {
vec3 vertexColor = vec3( 1.0, 1.0, 1.0 );
vec4 textureColor = texture( textureSampler, outTexCoord );
fragColor = vec4( vertexColor, 1.0 ) * textureColor;
}
渲染函数:
private void beginRender(Game game, int positionsAttrib, int texCoordsAttrib) {
Texture texture = game.getTexturesManager().getTextureDefinition("tiles").getTexture();
GL13.glActiveTexture( GL13.GL_TEXTURE0 );
texture.bind();
this.vao.bind();
ShaderProgram.enableVertexAttribute( positionsAttrib );
ShaderProgram.enableVertexAttribute( texCoordsAttrib );
}
private void endRender(Game game, int positionsAttrib, int texCoordsAttrib) {
ShaderProgram.disableVertexAttribute( positionsAttrib );
ShaderProgram.disableVertexAttribute( texCoordsAttrib );
VertexArrayObject.unbind();
Texture.unbind();
}
// render is called by render loop between clear and swapbuffer GL functions
public void render(Game game, int positionsAttrib, int texCoordsAttrib) {
this.beginRender( game, positionsAttrib, texCoordsAttrib );
GL11.glDrawElements( GL11.GL_QUADS, this.vertexCount, GL11.GL_UNSIGNED_INT, 0 );
this.endRender( game, positionsAttrib, texCoordsAttrib );
}
我不确定它是否很清楚,尤其是我的英语大概..
您没有明确说明,但看起来您正在使用核心配置文件(您应该这样做)。但是,如果是这样,GL_QUADS
将不可用,您的绘图调用只会导致 GL_INVALID_ENUM
错误。
附带说明:既然你说你使用 OpenGL 4.5,我强烈建议你在开发过程中使用 OpenGL 的 debug output 功能,它将更容易发现和解释任何 GL 错误,并且可能此外提供有用的性能提示。