C++ 特定于程序的OpenGL运行时错误:蒙皮动画的多个输入缓冲区

C++ 特定于程序的OpenGL运行时错误:蒙皮动画的多个输入缓冲区,c++,opengl,animation,runtime,shader,C++,Opengl,Animation,Runtime,Shader,问题: 似乎第二个GLuint缓冲区没有被正确读取 更新:所以问题一定是在我尝试将数据输入着色器时。我重写了代码(旧代码仍在下面),以便对索引参数使用swizzling。这是我能让它工作的唯一方法。我想使用多个glvertexattributepointer,但每次我尝试给我相同的未定义结果 我想做什么: 我正在用一个非常简化的着色器测试非常简单的蒙皮动画 #version 330 core in vec2 model; in uint jointID; const int MAX_JOIN

问题:

似乎第二个GLuint缓冲区没有被正确读取

更新:所以问题一定是在我尝试将数据输入着色器时。我重写了代码(旧代码仍在下面),以便对索引参数使用swizzling。这是我能让它工作的唯一方法。我想使用多个glvertexattributepointer,但每次我尝试给我相同的未定义结果

我想做什么:

我正在用一个非常简化的着色器测试非常简单的蒙皮动画

#version 330 core

in vec2 model;
in uint jointID;

const int MAX_JOINTS = 10;

uniform mat4 joints[MAX_JOINTS];

void main()
{
    gl_Position = joints[jointID] * vec4(model, 0.0f, 1.0f);
}
我输入一些简单的数据

const GLfloat vertices[] =
{
    // upper arm
    0.0f, 0.0f,
    0.4f, 0.0f,
    0.4f, 0.2f,

    0.0f, 0.0f,
    0.4f, 0.2f,
    0.0f, 0.2f,

    // lower arm
    0.4f, 0.0f,
    0.8f, 0.0f,
    0.8f, 0.2f,

    0.4f, 0.0f,
    0.8f, 0.2f,
    0.4f, 0.2f
};

const GLuint indices[] =
{
    // upper arm
    0,
    1,
    1,

    0,
    1,
    0,

    // lower arm
    1,
    1,
    1,

    1,
    1,
    1
};
(第一个数组包含顶点,第二个数组包含相应的boneID。)奇怪的是,boneID看起来从来都不太相等1,因为当我将索引1处的矩阵设为一个非常时髦的值时,顶点仍然未转换。这让我相信这是我设置GlvertexAttributePointer的方式的问题

void SkinnedModel::draw()
{
    shaderProgram.use();

    glEnableVertexAttribArray(modelLoc);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glVertexAttribPointer(modelLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);

    glEnableVertexAttribArray(jointIDLoc);
    glBindBuffer(GL_ARRAY_BUFFER, indexBuffer);
    glVertexAttribPointer(jointIDLoc, 1, GL_UNSIGNED_INT, GL_FALSE, 0, NULL);

    glUniformMatrix4fv(jointsLoc, 10, GL_FALSE, (GLfloat*)&poseMatrices);

    glDrawArrays(GL_TRIANGLES, 0, numVertices); 

    glDisableVertexAttribArray(modelLoc);
    glDisableVertexAttribArray(jointIDLoc);
}
在过去的几个小时里,我一直把头撞在桌子上,看什么似乎是正确的代码。不管怎么说,我可能错过了一些愚蠢的事情。感谢您的帮助

以下是所有相关的源代码(以防万一):

皮肤模型

#pragma once

#include "stl/DataTypes.h"
#include "Shader.h"
#include <Dense>

using namespace Eigen;

struct Joint
{
    Joint** children;
    Joint* parent;
    U32 index;
};

class SkinnedModel
{
public:
    static void init();
    static void destroy();

    SkinnedModel();
    ~SkinnedModel();
    void create(const GLfloat* vertices, const GLuint* jointIndices, GLint numVertices, Joint* rootJoint);
    void draw();
    void rotate(Joint* joint, F32 angle, F32 x, F32 y);

    GLuint vertexBuffer;
    GLuint indexBuffer;
    GLint numVertices;
    //GLint numJoints;
    Joint* root;
    Matrix<GLfloat,4,4> poseMatrices[10];

    static ShaderProgram shaderProgram;
    static GLuint modelLoc;
    static GLuint jointIDLoc;
    static GLuint modelViewMatrixLoc;
    static GLuint jointsLoc;
};
#pragma一次
#包括“stl/DataTypes.h”
#包括“Shader.h”
#包括
使用名称空间特征;
结构接头
{
联合**儿童;
联名*母公司;
U32指数;
};
类皮肤模型
{
公众:
静态void init();
静态空洞破坏();
皮肤模型();
~skindmodel();
void create(常量GLfloat*顶点、常量GLuint*jointindice、闪烁亮度、关节*根关节);
无效抽取();
空洞旋转(关节*关节,F32角度,F32 x,F32 y);
GLuint顶点缓冲区;
胶合指数缓冲器;
闪烁的亮度;
//闪烁的光点;
关节*根部;
矩阵正矩阵[10];
静态着色器程序着色器程序;
静态GLuint模型;
静态胶接接头;
静态GLuint modelViewMatrixLoc;
静态胶接接头;
};
skindmodel.cpp

#include "SkinnedModel.h"

ShaderProgram SkinnedModel::shaderProgram;
GLuint SkinnedModel::modelLoc = -1;
GLuint SkinnedModel::jointIDLoc = -1;
GLuint SkinnedModel::modelViewMatrixLoc = -1;
GLuint SkinnedModel::jointsLoc = -1;

void SkinnedModel::init()
{
    ShaderProgramSettings shaderPS;
    shaderPS.loadShader("Skinned.v.glsl", ShaderType::VERTEX);
    shaderPS.loadShader("Skinned.f.glsl", ShaderType::FRAGMENT);
    shaderProgram = shaderPS.create();
    shaderProgram.use();

    modelLoc = shaderProgram.getAttrib("model");
    jointIDLoc = shaderProgram.getAttrib("jointID");
    //modelViewMatrixLoc = shaderProgram.getUniform("modelViewMatrix");
    jointsLoc = shaderProgram.getUniform("joints");
}

void SkinnedModel::destroy()
{
    shaderProgram.destroy();
}

SkinnedModel::SkinnedModel()
{

}

SkinnedModel::~SkinnedModel()
{
    glDeleteBuffers(1, &vertexBuffer);
    glDeleteBuffers(1, &indexBuffer);
}

void SkinnedModel::create(const GLfloat* vertices, const GLuint* jointIndices, GLint numVertices, Joint* rootJoint)
{
    this->numVertices = numVertices;
    this->root = rootJoint;

    for(U32 i=0;i<10;++i)
    {
        poseMatrices[i] = Matrix<GLfloat,4,4>::Identity();
    }
    poseMatrices[1] = Matrix<GLfloat,4,4>::Zero(); // <--- This should mess it up!

    // Creating buffers
    glDeleteBuffers(1, &vertexBuffer);
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, numVertices*2*sizeof(GLfloat), vertices, GL_STATIC_DRAW);

    glDeleteBuffers(1, &indexBuffer);
    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(GLuint), jointIndices, GL_STATIC_DRAW);
}

void SkinnedModel::draw()
{
    shaderProgram.use();

    glEnableVertexAttribArray(modelLoc);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glVertexAttribPointer(modelLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);

    glEnableVertexAttribArray(jointIDLoc);
    glBindBuffer(GL_ARRAY_BUFFER, indexBuffer);
    glVertexAttribPointer(jointIDLoc, 1, GL_UNSIGNED_INT, GL_FALSE, 0, NULL);

    glUniformMatrix4fv(jointsLoc, 10, GL_FALSE, (GLfloat*)&poseMatrices);

    glDrawArrays(GL_TRIANGLES, 0, numVertices); 

    glDisableVertexAttribArray(modelLoc);
    glDisableVertexAttribArray(jointIDLoc);
}

void SkinnedModel::rotate(Joint* joint, F32 angle, F32 x, F32 y)
{
    F32 rcos = cos(angle);
    F32 rsin = sin(angle);
    Matrix<GLfloat, 4, 4> rotMatrix = Matrix<GLfloat, 4, 4>::Identity();
    rotMatrix(0,0) = rcos;
    rotMatrix(0,1) = -rsin;
    rotMatrix(1,0) = rsin;
    rotMatrix(1,1) = rcos;
    rotMatrix(0,3) = x-rcos*x+rsin*y;
    rotMatrix(1,3) = y-rsin*x-rcos*y;
    poseMatrices[joint->index] *= rotMatrix;
}
#包括“skindmodel.h”
ShaderProgram skindmodel::ShaderProgram;
GLuint SkinnedModel::modelLoc=-1;
GLuint SkinnedModel::jointIDLoc=-1;
GLuint SkinnedModel::modelViewMatrixLoc=-1;
GLuint SkinnedModel::jointsLoc=-1;
void skindmodel::init()
{
着色器程序设置着色器;
loadShader(“skined.v.glsl”,ShaderType::VERTEX);
loadShader(“skined.f.glsl”,ShaderType::FRAGMENT);
shaderProgram=shaderPS.create();
shaderProgram.use();
modelLoc=shaderProgram.getAttrib(“模型”);
jointIDLoc=shaderProgram.getAttrib(“jointID”);
//modelViewMatrixLoc=shaderProgram.getUniform(“modelViewMatrix”);
jointsLoc=shaderProgram.getUniform(“接缝”);
}
void skindmodel::destroy()
{
shaderProgram.destroy();
}
SkinnedModel::SkinnedModel()
{
}
SkinnedModel::~SkinnedModel()
{
glDeleteBuffers(1和vertexBuffer);
glDeleteBuffers(1和indexBuffer);
}
void skindmodel::create(常量GLfloat*顶点、常量GLuint*jointindice、闪烁亮度、关节*根关节)
{
此->numVertices=numVertices;
这->根=根关节;
适用于(U32 i=0;isetBackgroundColor(1.0f、1.0f、1.0f);
常量GLfloat顶点[]=
{
//上臂
0.0f,0.0f,
0.4f,0.0f,
0.4f,0.2f,
0.0f,0.0f,
0.4f,0.2f,
0.0f,0.2f,
//下臂
0.4f,0.0f,
0.8f,0.0f,
0.8f,0.2f,
0.4f,0.0f,
0.8f,0.2f,
0.4f,0.2f
};
常数GLuint指数[]=
{
//上臂
0,
1.
1.
0,
1.
0,
//下臂
1.
1.
1.
1.
1.
1.
};
upperArm.parent=0;
上臂儿童=新关节*[1];
上臂。儿童[0]=&lowerArm;
上臂指数=0;
lowerArm.parent=&upperArm;
Loweraram.children=0;
下限指数=1;
m、 创建(顶点、索引、12和上臂);
//m、 旋转(&lowerram,PI/4,0.4f,0.1f);
//调试(“大小%i”,sizeof(特征::矩阵));
}
无效游戏::循环(双dt)
{
m、 draw();
}

更新:显然,如果boneID的所有值都设置为1,它也不会在着色器中使用1@。因此,第二个数组甚至没有被读取,或者没有被正确读取。

如果使用整数顶点属性,则需要使用
glvertexattributeinter
(即,在顶点着色器的uint或int等中声明的内容)

替换

glVertexAttribPointer(jointIDLoc, 1, GL_UNSIGNED_INT, GL_FALSE, 0, NULL);


(请注意,
glVertexAttribIPointer
不接受规格化参数)

如果您不确定着色器中的某个特定值,则始终可以将其传递到输出颜色(可能需要重新缩放以更好地匹配视景范围)好主意!我试试。你调用你的
rotate
函数吗?当程序进入
draw
时,检查
posematrics
的内容。另外,
x
y
在rotate中应该是什么意思?rotate函数不相关,我只是把它放在类中某个点进行测试。我检查了矩阵的内容是的,它们是正确的。jointID出于某种原因仍然喜欢为0,即使我将所有值设置为1,使其不可能为0。我还检查了设置后的索引缓冲区,并确认那里的所有内容都是正确的。问题在于draw调用中的某个地方。为什么在
cr中调用
glDeleteBuffers
eate
功能?
glVertexAttribPointer(jointIDLoc, 1, GL_UNSIGNED_INT, GL_FALSE, 0, NULL);
glVertexAttribIPointer(jointIDLoc, 1, GL_UNSIGNED_INT, 0, NULL);