У меня возникла проблема в приложении OpenGL, в которой OpenGL добавляет вершину в некоторые из моих сеток.Этот вопрос меня озадачил, потому что, кажется, он затрагивает только сетки, состоящие из треугольных полос.Основная процедура, используемая для создания скриншота в конце поста, выглядит следующим образом:
- Использование простая математика для генерации вершин, которые лежат на единичной сфере, а также текстурыкоординаты и индексы элементов.
- Загрузка данных из шага 1 в буферы, привязанные к VAO.
- Каждый кадр: связать VAO и рисовать с помощью
glDrawElements()
Перед публикацией,Я проверял данные вершин для (упрощенной версии) своей сетки на каждой стадии процесса, и ни разу не было вершины в начале координат (в модельном пространстве).Однако, если вы посмотрите на скриншот в конце поста, очевидно, что в центре меша есть вершина, и ее присутствие деформирует мой меш и вызывает проблемы с текстурированием.
Я не очень разбираюсь в 3D-графике и никогда раньше не слышал о подобных проблемах, поэтому я не уверен, какую другую полезную информацию я могу предоставить.Если есть что-то еще, дайте мне знать в комментариях.
(та же модель Земли, что и GL_POINTS
, GL_LINE_LOOP
и GL_TRIANGLE_STRIP
соответственно)
ОБНОВЛЕНИЕ: По запросу,вот код, который устанавливает и рисует мои массивы вершин:
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");
}