Рисование нескольких объектов с текстурой не работает

Я работаю над загрузчиком 3D-моделей. Он может загружать мой собственный формат. Я написал свой собственный экспортер для Blender, он работает хорошо. Формат модели может обрабатывать несколько сеток (объектов) в одной модели. Каждая сетка может иметь различную текстуру. Я уже написал загрузчик, который работает хорошо, но не использует шейдеры.

Я переключился на шейдеры, но что-то идет не так, текстуры не отображаются правильно. Вот моя функция рисования, я уверен, что ошибка где-то здесь:

void CModel::draw(glm::mat4 &MVP)
{
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);

for(unsigned int i=0; i<m_numObjects; i++)
{
glUseProgram(m_programID);
glUniformMatrix4fv(m_matrixUniform, 1, GL_FALSE, &MVP[0][0]);

glBindTexture(GL_TEXTURE_2D, m_textureIDs[i]);
glUniform1i(m_textureUniform, 0);

glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);

// vertices
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,                  // must match the layout in the shader.
3,                  // size
GL_FLOAT,           // type
GL_FALSE,           // normalized?
sizeof(float)*8,    // stride
(void*)0            // array buffer offset
);

// UVs
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
2,
GL_FLOAT,
GL_FALSE,
sizeof(float)*8,
(void*)6
);

glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glUseProgram(0);
}

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisable(GL_TEXTURE_2D);
}

Вершинный и фрагментный шейдеры также работают хорошо.

Предыдущая версия (без шейдеров) была такой (это работало хорошо):

void CModel::draw()
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);

glClientActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);

for(unsigned int i=0; i<m_numObjects; i++)
{
glBindTexture(GL_TEXTURE_2D, m_textureIDs[i]);

glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);

glTexCoordPointer(2, GL_FLOAT, sizeof(float)*8, (float*)(sizeof(float)*6));
glNormalPointer(     GL_FLOAT, sizeof(float)*8, (float*)(sizeof(float)*3));
glVertexPointer(  3, GL_FLOAT, sizeof(float)*8, 0);

glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]);

glBindBuffer(GL_ARRAY_BUFFER, 0);
}

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

glDisable(GL_TEXTURE_2D);
}

Вот весь класс:

#include "global.h"#include "CModel.h"#include "CModelLoader.h"#include "CShaderLoader.h"
CModel::CModel(){}

CModel::~CModel()
{
// TODO free memory
}

/** @brief Load mbm file
*
* @fileName: mdm model file name we want to load and draw
*/
void CModel::init(char *fileName)
{
CModelLoader   loader;
CShaderLoader  shaders;

loader.loadData(fileName);

loader.createDataArray( m_dataArray,
m_dataArraySizes,
m_numObjects,
m_numElements,
m_textureIDs );

glGenVertexArrays(1, &m_vertexArrayID);
glBindVertexArray(m_vertexArrayID);

m_programID      = shaders.loadShaders("vertexshader.vert", "fragmentshader.frag");

m_bufferIDs      = new unsigned int[m_numObjects];

glGenBuffers(m_numObjects, m_bufferIDs);
for(unsigned int i=0; i<m_numObjects; i++)
{
glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*m_dataArraySizes[i], m_dataArray[i], GL_STATIC_DRAW);
}

}

/** @brief Drawing the mdm model
*
*/
void CModel::draw(glm::mat4 &MVP)
{

glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);

for(unsigned int i=0; i<m_numObjects; i++)
{
glUseProgram(m_programID);

unsigned int matrixUniform  = glGetUniformLocation(m_programID, "MVP");
unsigned int textureUniform = glGetUniformLocation(m_programID, "myTextureSampler");

glUniformMatrix4fv(matrixUniform, 1, GL_FALSE, &MVP[0][0]);
glUniform1i(textureUniform, 0);

glBindTexture(GL_TEXTURE_2D, m_textureIDs[i]);
glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);

// vertices
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,                  // must match the layout in the shader.
3,                  // size
GL_FLOAT,           // type
GL_FALSE,           // normalized?
sizeof(float)*8,    // stride
(void*)0            // array buffer offset
);

// UVs
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
2,
GL_FLOAT,
GL_FALSE,
sizeof(float)*8,
(void*)6
);

glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glUseProgram(0);
}

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);glDisable(GL_TEXTURE_2D);
}

2

Решение

Наконец я решил это. Проблема заключалась в том, что я использовал один массив для вершин, нормалей и координат текстуры вместо того, чтобы хранить их в отдельных массивах и связывать их отдельно.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]