Ok, ich kann also ein Basismodell mit Vertices, Texturkoordinaten und Normalen laden und es ohne Probleme rendern.Senden von Bone-Daten an den Glsl-Shader
Wenn ich jedoch einige Knocheninformationen einwerfe, scheinen die Knochendaten beschädigt zu sein (oder etwas?), Wenn ich versuche, sie im Shader zu manipulieren.
Hier ist mein Code für das Laden und die Daten in opengl Rendering (Einstellung der Shader und Senden der Ansicht Matrix, Welt Matrix, etc. werden in einer anderen Klasse durchgeführt):
/*
* Mesh.cpp
*
* Created on: 2011-05-08
* Author: jarrett
*/
#include <boost/log/trivial.hpp>
#include "../common/utilities/AssImpUtilities.h"
#include "Mesh.h"
namespace glr {
namespace glw {
Mesh::Mesh(IOpenGlDevice* openGlDevice,
const std::string path,
std::vector<glm::vec3> vertices,
std::vector<glm::vec3> normals,
std::vector<glm::vec2> textureCoordinates,
std::vector<glm::vec4> colors,
std::vector<VertexBoneData > bones,
BoneData boneData)
: openGlDevice_(openGlDevice), vertices_(vertices), normals_(normals), textureCoordinates_(textureCoordinates), colors_(colors), bones_(bones), boneData_(boneData)
{
BOOST_LOG_TRIVIAL(debug) << "loading mesh into video memory...";
// create our vao
glGenVertexArrays(1, &vaoId_);
glBindVertexArray(vaoId_);
// create our vbos
glGenBuffers(5, &vboIds_[0]);
glBindBuffer(GL_ARRAY_BUFFER, vboIds_[0]);
glBufferData(GL_ARRAY_BUFFER, vertices_.size() * sizeof(glm::vec3), &vertices_[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vboIds_[1]);
glBufferData(GL_ARRAY_BUFFER, textureCoordinates_.size() * sizeof(glm::vec2), &textureCoordinates_[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vboIds_[2]);
glBufferData(GL_ARRAY_BUFFER, normals_.size() * sizeof(glm::vec3), &normals_[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);
std::cout << "SIZE: " << vertices_.size() << " " << sizeof(glm::ivec4) << " " << bones_.size() << " " << sizeof(VertexBoneData) << std::endl;
// Convert data into simple vectors, then send to OpenGL
std::vector<glm::ivec4> boneIds = std::vector<glm::ivec4>();
std::vector<glm::vec4> weights = std::vector<glm::vec4>();
for (VertexBoneData& d : bones_)
{
boneIds.push_back(d.boneIds);
weights.push_back(d.weights);
}
glBindBuffer(GL_ARRAY_BUFFER, vboIds_[3]);
glBufferData(GL_ARRAY_BUFFER, boneIds.size() * sizeof(glm::ivec4), &boneIds[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_INT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vboIds_[4]);
glBufferData(GL_ARRAY_BUFFER, weights.size() * sizeof(glm::vec4), &weights[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 0, 0);
// Disable our Vertex Array Object
//glEnableVertexAttribArray(0);
// Disable our Vertex Buffer Object
glBindVertexArray(0);
GlError err = openGlDevice_->getGlError();
if (err.type != GL_NONE)
{
// TODO: throw error
BOOST_LOG_TRIVIAL(error) << "Error loading mesh in opengl";
BOOST_LOG_TRIVIAL(error) << "OpenGL error: " << err.name;
}
else
{
BOOST_LOG_TRIVIAL(debug) << "Successfully loaded mesh.";
}
}
Mesh::~Mesh()
{
}
void Mesh::render()
{
glBindVertexArray(vaoId_);
glDrawArrays(GL_TRIANGLES, 0, vertices_.size());
glBindVertexArray(0);
}
BoneData& Mesh::getBoneData()
{
return boneData_;
}
}
}
Meine eigentliche Shader ist dies:
#version 150 core
struct Light {
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 position;
vec4 direction;
};
in vec3 in_Position;
in vec2 in_Texture;
in vec3 in_Normal;
in ivec4 in_BoneIds;
in vec4 in_BoneWeights;
out vec2 textureCoord;
out vec3 normalDirection;
out vec3 lightDirection;
out float bug;
layout(std140) uniform Lights
{
Light lights[ 1 ];
};
void main() {
gl_Position = pvmMatrix * vec4(in_Position, 1.0);
vec4 lightDirTemp = viewMatrix * lights[0].direction;
textureCoord = in_Texture;
//vec4 normalDirTemp = boneTransform * vec4(in_Normal, 1.0);
//normalDirection = normalize(normalMatrix * normalDirTemp.xyz);
normalDirection = normalize(normalMatrix * in_Normal);
lightDirection = normalize(vec3(lightDirTemp));
// If we have any bugs, should highlight the vertex red or green
bug = 0.0;
float sum = in_BoneWeights[0] + in_BoneWeights[1] + in_BoneWeights[2] + in_BoneWeights[3];
if (sum > 1.5f)
bug = 1.0;
else if (sum < 0.95f)
bug = 2.0;
// disable bug highlighting
//bug = 0.0;
}
wenn bug = 1.0
, dann werden die Eckpunkte rot gefärbt, und wenn but = 2.0
, dann sind die Eckpunkte grün gefärbt. Ich sehe, dass alle Vertices gerade rot gefärbt sind, was bedeutet, dass sum
größer ist als 1.5f
.
Ich habe bestätigt, dass die Summe der einzelnen Gewichte in der Tat ist <= 1.0f
... so wie in der Welt ist dies nicht der Fall in den Shader?
Wer sieht etwas offensichtlich Ich vermisse?
EDIT: Sieht aus wie ich das Problem gefunden - ich glBindAttribLocation
auf keinem meiner in
Variablen nicht anrief - nach Zugabe:
glBindAttribLocation(programId_, 0, "in_Position");
glBindAttribLocation(programId_, 1, "in_Texture");
glBindAttribLocation(programId_, 2, "in_Color");
glBindAttribLocation(programId_, 3, "in_BoneIds");
glBindAttribLocation(programId_, 4, "in_BoneWeights");
meinem Shader-Laden-Code, es funktioniert gut. Sonderbare Sache ist - ich musste dies nicht für die ersten 3 (Position, Textur und Farbe) tun, und es hat gut funktioniert. Aber als ich die Knocheninformation hinzugefügt habe, brauche ich das plötzlich ... warum?
Das war es - nachdem ich das getan hatte, konnte ich auch die 'glBindAttribLocation' Aufrufe entfernen. Ich habe jetzt Animation funktioniert! (zu einem gewissen Grad - es scheint an einigen Stellen zu verschwinden, also denke ich, dass die Normalen durcheinander kommen könnten.). Danke @Andon! – Jarrett