我的OpenGL应用程序中存在一个问题,OpenGL似乎在我的某些网格的原点添加了一个顶点。这个问题让我感到困惑,因为它似乎只影响由三角形条带组成的网格。在帖子末尾用于创建屏幕截图的基本过程如下:
glDrawElements()
在发布之前,我在过程的每个阶段检查了我的网格的(简化版本)顶点数据,并且在原点(模型空间)中没有任何顶点。但是,如果您查看帖子末尾的屏幕截图,网格中心显然有一个顶点,它的存在会使我的网格变形并导致纹理问题。
我对3D图形缺乏经验,之前从未听说过这样的问题,所以我不确定我能提供哪些其他有用的信息。如果还有其他内容,请在评论中告诉我。
(地球的相同模型分别为GL_POINTS
,GL_LINE_LOOP
和GL_TRIANGLE_STRIP
)
UPDATE:根据要求,这是设置和绘制顶点数组的代码:
public void init(GL3 gl){
//If there is no graphics data, this object isn't going to get rendered and we should just leave
if(gData == null){
return;
}
//Prepare the index data
short[] indexData = gData.getIndexArray();
indexCount = indexData.length;
//This is required because interleaving the data
//screws with how the data is laid out in memory
for(int i = 0; i < indexCount; i++){
indexData[i] *= gData.getVertexData().size();
indexData[i] = indexData[i] < 0 ? -1 : indexData[i];
}
//Put the program together
glProgram = gl.glCreateProgram();
for(Shader shader : gData.getShaders()){
shader.compile(gl);
gl.glAttachShader(glProgram, shader.location);
}
gl.glLinkProgram(glProgram);
int[] result = new int[1];
gl.glGetProgramiv(glProgram, GL3.GL_LINK_STATUS, result, 0);
if(result[0] != GL3.GL_TRUE){
byte[] info = new byte[512];
gl.glGetProgramInfoLog(glProgram, 512, result, 0, info, 0);
Logger.log(new String(info), Logger.ERROR, "GameObject -- init -- Link Error");
}
//Interleave the per-vertex data
float[] vertexData = interleave(gData.getVertexData().toArray(new VertexData[0]));
//Generate buffers
gl.glGenVertexArrays(1, glBuffer, 0);
gl.glGenBuffers(2, glBuffer, 1);
if(checkGLErrors(gl, "After generating VAO and buffers")){
sHandler.Quit();
}
//Bind the VAO, program, and buffers. In that order.
gl.glBindVertexArray(glBuffer[0]);
if(checkGLErrors(gl, "After binding VAO")){
sHandler.Quit();
}
gl.glUseProgram(glProgram);
if(checkGLErrors(gl, "After binding program")){
sHandler.Quit();
}
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, glBuffer[1]);
gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, glBuffer[2]);
if(checkGLErrors(gl, "After binding buffers")){
sHandler.Quit();
}
//Send in the per-vertex data
gl.glBufferData(
GL3.GL_ARRAY_BUFFER,
vertexData.length * SIZEOF_FLOAT,
FloatBuffer.wrap(vertexData),
GL3.GL_STATIC_DRAW);
if(checkGLErrors(gl, "After loading data into the buffers")){
sHandler.Quit();
}
//Set up pointers to the vertex attributes
for(VertexData a : gData.getVertexData()){
a.location = gl.glGetAttribLocation(glProgram, a.name);
gl.glVertexAttribPointer(a.location, a.components, GL3.GL_FLOAT, false, a.stride * SIZEOF_FLOAT, a.offset * SIZEOF_FLOAT);
gl.glEnableVertexAttribArray(a.location);
if(checkGLErrors(gl, "After setting pointers to the vertex attributes")){
sHandler.Quit();
}
}
//Set up pointers to the uniform variables
for(UniformData uniform : gData.getUniformData()){
uniform.location = gl.glGetUniformLocation(glProgram, uniform.name);
if(checkGLErrors(gl, "After setting pointers to the uniform variables")){
sHandler.Quit();
}
}
//Send in index data
gl.glBufferData(
GL3.GL_ELEMENT_ARRAY_BUFFER,
indexData.length * SIZEOF_SHORT,
ShortBuffer.wrap(indexData),
GL3.GL_STATIC_DRAW);
if(checkGLErrors(gl, "After loading in index data")){
sHandler.Quit();
}
//Load textures
for(int i = 0; i < glTextures.length; i++){
glTextures[i] = gData.getTextureData().get(i).loadTexture(gl);
if(checkGLErrors(gl, "After loading texture "+i)){
sHandler.Quit();
}
}
//Bind only the first texture....
if(glTextures.length >= 1){
gl.glBindTexture(GL3.GL_TEXTURE_2D, glTextures[0]);
if(checkGLErrors(gl, "After binding textures")){
sHandler.Quit();
}
}
//-----BEGIN OPENGL STATE SETTINGS-----
//Depth Testing
gl.glEnable(GL3.GL_DEPTH_TEST);
gl.glDepthFunc(GL3.GL_LEQUAL);
//Primitive Restart
gl.glEnable(GL3.GL_PRIMITIVE_RESTART);
gl.glPrimitiveRestartIndex(-1);
//Enlargen points
gl.glPointSize(5.0f);
//-----END OPENGL STATE SETTINGS-----
//...And we're done here.
gl.glBindVertexArray(0);
if(checkGLErrors(gl, "After completing Object Initialization")){
sHandler.Quit();
}
}
public void draw(GL3 gl){
//Check to see if this object actually needs to be drawn
if(gData == null){
return;
}
//Bind the vertex array
gl.glBindVertexArray(glBuffer[0]);
gl.glUseProgram(glProgram);
checkGLErrors(gl, "After binding vertex array");
//Load the uniform data
for(UniformData uniform: gData.getUniformData()){
uniform.loadData(gl);
}
checkGLErrors(gl, "After loading uniform data");
//Draw
gl.glDrawElements(gData.getPrimitive(), indexCount, GL3.GL_UNSIGNED_SHORT, 0);
//Unbind
gl.glBindVertexArray(0);
checkGLErrors(gl, "After finishing draw");
}
答案 0 :(得分:1)
gl.glPrimitiveRestartIndex(-1);
这看起来不正确,因为the parameter to glPrimitiveRestartIndex
是无符号的。结果是重启索引设置为4294967295。
gl.glDrawElements(gData.getPrimitive(),indexCount,GL3.GL_UNSIGNED_SHORT,0);
在这里,指数是无符号的。 (GLuint)-1 != (GLushort)-1
,因此VBO中的“重启”点不会导致重启,它们导致使用索引65535(超出数据范围)被视为(0,0,0)