Ok, vì vậy tôi có thể tải một mô hình cơ bản với các đỉnh, tọa độ kết cấu và các tiêu chuẩn và hiển thị nó mà không có vấn đề.Gửi dữ liệu xương tới bóng đổ bóng mờ
Tuy nhiên, khi tôi thử ném một số thông tin về xương, dữ liệu xương dường như bị hỏng (hoặc cái gì đó?) Khi tôi thử và thao tác nó trong trình đổ bóng.
Dưới đây là mã của tôi để tải và render dữ liệu vào OpenGL (thiết lập các shader và gửi ma trận điểm, ma trận trên thế giới, vv được thực hiện trong lớp khác):
/*
* 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_;
}
}
}
đổ bóng thực sự của tôi là thế này:
#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;
}
Nếu bug = 1.0
, thì các đỉnh có màu đỏ và nếu but = 2.0
thì các đỉnh có màu xanh lục. Tôi thấy tất cả các đỉnh có màu đỏ ngay bây giờ, có nghĩa là sum
lớn hơn 1.5f
.
Tôi đã xác nhận rằng tổng của mỗi tập trọng số thực tế là <= 1.0f
... vậy làm thế nào trên thế giới này không phải là trường hợp trong trình đổ bóng?
Bất cứ ai nhìn thấy bất cứ điều gì rõ ràng tôi đang thiếu?
EDIT: Hình như tôi thấy vấn đề - Tôi đã không gọi glBindAttribLocation
trên bất kỳ in
biến của tôi - sau khi thêm:
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");
mã shader tải của tôi, nó hoạt động tốt. Điều kỳ lạ là - Tôi không phải làm điều này cho 3 đầu tiên (vị trí, kết cấu và màu sắc) và nó hoạt động tốt. Nhưng khi tôi thêm thông tin về xương, tôi đột nhiên cần điều này ... tại sao?
Đó là nó - sau khi làm điều đó tôi có thể loại bỏ các 'glBindAttribLocation' cuộc gọi là tốt. Tôi bây giờ có hoạt hình hoạt động! (đến một mức độ - nó dường như biến mất ở những nơi, vì vậy tôi nghĩ rằng các normals có thể nhận được messed up.). Cảm ơn @Andon! – Jarrett