c – 将骨骼数据发送到glsl着色器

c – 将骨骼数据发送到glsl着色器,第1张

概述好的,所以我能够加载一个带有顶点,纹理坐标和法线的基本模型,并且可以毫无问题地渲染它. 但是,当我尝试投入一些骨骼信息时,当我尝试在着色器中 *** 作骨骼数据时,骨骼数据似乎正在被破坏(或其他什么?). 这是我加载和渲染数据到opengl的代码(设置着色器并发送视图矩阵,世界矩阵等在另一个类中完成): /* * Mesh.cpp * * Created on: 2011-05-08 * 好的,所以我能够加载一个带有顶点,纹理坐标和法线的基本模型,并且可以毫无问题地渲染它.

但是,当我尝试投入一些骨骼信息时,当我尝试在着色器中 *** 作骨骼数据时,骨骼数据似乎正在被破坏(或其他什么?).

这是我加载和渲染数据到opengl的代码(设置着色器并发送视图矩阵,世界矩阵等在另一个类中完成):

/* * 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);    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,vboIDs_[2]);    glBufferData(GL_ARRAY_BUFFER,normals_.size() * sizeof(glm::vec3),&normals_[0],GL_STATIC_DRAW);    glEnabLevertexAttribarray(2);    glVertexAttribPointer(2,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,vboIDs_[4]);    glBufferData(GL_ARRAY_BUFFER,weights.size() * sizeof(glm::vec4),&weights[0],GL_STATIC_DRAW);    glEnabLevertexAttribarray(4);    glVertexAttribPointer(4,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,vertices_.size());    glBindVertexArray(0);}BoneData& Mesh::getBoneData(){    return boneData_;}}}

我的实际着色器是这样的:

#version 150 corestruct 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;        }

如果BUG = 1.0,则顶点为红色,如果= = 2.0,则顶点为绿色.我看到所有的顶点现在都是红色的,这意味着总和大于1.5f.

我已经确认每组权重的总和实际上是<= 1.0f ...所以在世界中如何在着色器中不是这种情况? 有人看到任何明显我失踪的东西吗? 编辑:看起来我发现了问题 – 我没有在任何变量上调用glBindAttribLocation – 添加后:

glBindAttribLocation(programID_,"in_position");    glBindAttribLocation(programID_,1,"in_Texture");    glBindAttribLocation(programID_,"in_color");    glBindAttribLocation(programID_,"in_BoneIDs");    glBindAttribLocation(programID_,"in_BoneWeights");

我的着色器加载代码,它工作正常.奇怪的是 – 我没有必要为前3(位置,纹理和颜色)这样做,它工作得很好.但是当我添加骨骼信息时,我突然需要这个……为什么?

解决方法 您需要使用glVertexAttribIPointer(…)将数据提供给ivec< N>顶点属性.如果您认为在设置属性位置之前遇到“损坏”,请等到您在着色器中编写实际需要骨骼ID的代码…这些值将毫无意义,因为您使用了错误的API调用来关联属性具有特定绑定位置的数据.

glVertexAttribPointer(…)变体在获取GL_INT数据类型时没有问题,但它会将其转换为浮点(并且它可以在过程中规范化定点值,因此额外的参数).因此,期望该变体将数据提供给vec< N>.顶点属性,而不是ivec< N>.

更简洁地说,对整数顶点属性使用glVertexAttribIPointer,对浮点使用glVertexAttribPointer.

总结

以上是内存溢出为你收集整理的c – 将骨骼数据发送到glsl着色器全部内容,希望文章能够帮你解决c – 将骨骼数据发送到glsl着色器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1244416.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存