Можете ли вы сделать это с массивами вершин OpenGL 4.4?

Я загружаю Collada (файл .dae), и модель имеет 2 объекта. Первый — это ткань с множеством вершин из светло-голубого материала.
И вторая коробка, которую ткань должна складывать, когда она падает.

Предполагается, что это анимация 250 кадров, но я не уверен, так ли это на самом деле или нет. Когда я загружаю его в Assimp’s aiScene* это говорит HasAnimation() == 0… Это также говорит о том, что сетка для ткани не имеет цвета, с HasVertexColors() == 0 Что меня беспокоит, я должен еще раз взглянуть на экспорт. Я не знаю, может быть, вы можете сказать?
Я свяжу его с внешней стороны, так как он слишком велик для этого поста. (Простите за это)

Падающая ткань (Collada animation .dae):
http://pastebin.com/54LkKq8k

Моя проблема в том, что я не вижу голубую ткань, а коробка черная, как в (0, 0, 0)

Инициализация VBO:

void AssimpMesh::initMesh(aiMesh *mesh, MeshData *data) {
//Buffer for temporary storage of new ids
GLuint id;

//Make vertex array
glGenVertexArrays(1, &id);
data->meshArray = id;

//Tell OpenGL to use this array
glBindVertexArray(id);

//Assign vertices
if (mesh->HasPositions()) {
//Make buffer
glGenBuffers(1, &id);
data->buffers.push_back(id);
data->bufferNames.push_back("Positions");

//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D) * mesh->mNumVertices, &mesh->mVertices[0], GL_STATIC_DRAW);

//Set shader attribute data
glEnableVertexAttribArray(VBO_VERTEX);
glVertexAttribPointer(VBO_VERTEX, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
}

//Assign colors
if (mesh->HasVertexColors(0)) {
//Make buffer
glGenBuffers(1, &id);
data->buffers.push_back(id);
data->bufferNames.push_back("Colors");

//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, sizeof(aiColor4D) * mesh->mNumVertices, &mesh->mColors[0], GL_STATIC_DRAW);

//Set shader attribute data
glEnableVertexAttribArray(VBO_COLOR);
glVertexAttribPointer(VBO_COLOR, 4, GL_FLOAT, GL_FALSE, NULL, NULL);
}

//Assign texture coords
if (mesh->HasTextureCoords(0)) {
//Make buffer
glGenBuffers(1, &id);
data->buffers.push_back(id);
data->bufferNames.push_back("TextureCoords");

//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D) * mesh->mNumVertices, &mesh->mTextureCoords[0], GL_STATIC_DRAW);

//Set shader attribute data
glEnableVertexAttribArray(VBO_TEXCORD);
glVertexAttribPointer(VBO_TEXCORD, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
}

//Assign colors
if (mesh->HasNormals()) {
//Make buffer
glGenBuffers(1, &id);
data->buffers.push_back(id);
data->bufferNames.push_back("Normals");

//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D) * mesh->mNumVertices, &mesh->mNormals[0], GL_STATIC_DRAW);

//Set shader attribute data
glEnableVertexAttribArray(VBO_NORMAL);
glVertexAttribPointer(VBO_NORMAL, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
}

if (mesh->HasFaces()) {
vector <unsigned int> indices;
aiFace face;
for (int i = 0; i < mesh->mNumFaces; i++) {
face = mesh->mFaces[i];
for (int j = 0; j < face.mNumIndices; j++) {
indices.push_back(face.mIndices[j]);
}
}

//Make buffer
glGenBuffers(1, &id);
data->buffers.push_back(id);
data->bufferNames.push_back("Faces");

//Set buffer data
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indices.size(), &indices.front(), GL_STATIC_DRAW);
}

//Unbind vertex array
glBindVertexArray(NULL);
}

Нарисовать модель:

void AssimpMesh::draw() {
//Draw all vertex arrays
aiMesh *mesh;
aiFace face;
MeshData *data;
for (int i = 0; i < meshes.size(); i++) {
mesh = scene->mMeshes[i];
face = mesh->mFaces[0];
data = meshes[i];

//Tell OpenGL to use this array
glBindVertexArray(data->meshArray);

//Tell OpenGL which shader to use
glUseProgram(data->program);

//Draw the elements of the array
glDrawElements(GL_TRIANGLES, face.mNumIndices * mesh->mNumFaces, GL_UNSIGNED_INT, 0);
}

//Unbind vertex array
glBindVertexArray(NULL);

//Unbind shader
glUseProgram(NULL);
}

Вершинный шейдер:

#version 120

attribute vec3 vertex;
attribute vec4 color;
attribute vec3 texCoord;
attribute vec3 normal;

uniform mat4 transform;

varying vec3 shared_color;
varying vec2 shared_texCoord;
varying vec3 shared_normal;

void main() {
gl_Position = transform * vec4(vertex, 1.0);

//Send data to fragment shader
shared_color = color.xyz;
shared_texCoord = texCoord.xy;
shared_normal = (transform * vec4(normal, 0.0)).xyz;
}

Фрагмент шейдера:

#version 120

uniform sampler2D diffuse;
uniform int flagTexture;

varying vec3 shared_color;
varying vec2 shared_texCoord;
varying vec3 shared_normal;

void main() {
vec4 color = vec4(shared_color, 1);
vec4 texture = texture2D(diffuse, shared_texCoord);
vec4 finalColor = color;

if (flagTexture >= 1) {
finalColor = vec4(mix(color.rgb, texture.bgr, texture.a), 1);
//finalColor = color * texture;
}

float shade = 0;
if (shade >= 1) {
vec3 lightPosition = vec3(0, 0, -1);
float shadowDarkness = 0.8;
vec3 actualLightPos = vec3(-lightPosition.x, lightPosition.y, lightPosition.z);
float lightStrength = clamp(dot(actualLightPos, shared_normal), 1 - shadowDarkness, 1.0);
vec4 litColor = finalColor * lightStrength;
finalColor = litColor;
}

gl_FragColor = finalColor;
}

1

Решение

Я вижу пару проблем здесь после просмотра документации библиотеки, которую вы используете:

  • Для цветов вы получаете тип aiColor4D. Как следует из названия, это класс, содержащий 4 числа с плавающей запятой. Но вы передаете 3 для размера на соответствующий вызов glVertexAttribPointer(),
  • Для текстурных координат тип aiVector3D, который содержит 3 числа с плавающей точкой. Но вы передаете 2 для размера на соответствующий вызов glVertexAttribPointer(),
  • aiFace это класс, который содержит индекс индекса и указатель на индексы для лица. Вы не можете просто передать массив этих парней glBufferData() как ваши показатели. По сути, вы передаете последовательность индексов и указателей вместо последовательности индексов.
  • Второй аргумент glDrawElements() это количество индексов, а не количество треугольников.

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

2

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

1) это работает?

Вы проверяли это? Похоже, он должен отображаться правильно, хотя ваше освобождение выглядит неправильно.
glDelete* принимает указатель на свой второй аргумент; вы передаете ссылку на передний элемент.

Измените это на это:

for (int i = 0; i < buffers.size(); i++) {
glDeleteBuffers(buffers[i].size(), &buffers[i].front());
}

glDeleteVertexArrays(meshes.size(), &meshes.front());

2) это хорошо?

Это довольно стандартный цикл рендеринга, скорость которого практически полностью зависит от сложности ваших шейдеров. ХОТЯ, я бы сделал изменение объявления указателя вне цикла, а затем переназначения его, вместо объявления нового указателя для каждой сетки:

aiMesh *mesh;
for (int i = 0; i < meshes.size(); i++) {
mesh = scene->mMeshes[i];

//Tell OpenGL to use this array
glBindVertexArray(meshes[i]);

//Draw the elements of the array
glDrawElements(GL_TRIANGLES, mesh->mNumFaces, GL_UNSIGNED_INT, 0);
}

3) Дополнительная информация

В него входит ужасная маленькая математическая библиотека, которую я бы никогда не порекомендовал, но вы все равно должны знать, что делать с вершинами и тому подобным позже (например, когда вы позже отобразите свои буферы)

Так что если вы хотите отобразить свой GL_ARRAY_BUFFER чтобы изменить сохраненные вершины, вам нужно использовать что-то вроде этого:

glBindVertexArray(the_vao);
aiVector3D *data = reinterpret_cast<aiVector3D*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));

// do all the changes!

glUnmapBuffer(GL_ARRAY_BUFFER);
1

Я посмотрел в документации и увидел, что HasVertexColors() на самом деле не было диффузного значения из материала, который я хотел. Поэтому я решил это, используя материал, проиндексированный в сетке, и извлек диффузный цвет в массив размера mNumVertices,

unsigned int matId = mesh->mMaterialIndex;
aiMaterial *material = scene->mMaterials[matId];
vector <aiColor3D> colors;
aiColor3D diffuse(0, 0, 0);
material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);

for (int i = 0; i < mesh->mNumVertices; i++) {
colors.push_back(diffuse);
}
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector