将不推荐使用的 opengl 函数转换为现代 opengl (3.3)
convert deprecated opengl function to modern opengl (3.3)
我需要帮助将 IQM 模型的渲染函数 (void renderiqm()) 转换为现代 OpenGL(没有弃用的函数,如 enableClientState() 等)。
renderiqm()函数的代码在这里:
https://github.com/lsalzman/iqm/blob/master/demo/gpu-demo.cpp
这些是着色器:
顶点着色器:
"#version 120\n"
"#ifdef GL_ARB_uniform_buffer_object\n"
" #extension GL_ARB_uniform_buffer_object : enable\n"
" layout(std140) uniform animdata\n"
" {\n"
" uniform mat3x4 bonemats[80];\n"
" };\n"
"#else\n"
" uniform mat3x4 bonemats[80];\n"
"#endif\n"
"attribute vec4 vweights;\n"
"attribute vec4 vbones;\n"
"attribute vec4 vtangent;\n"
"void main(void)\n"
"{\n"
" mat3x4 m = bonemats[int(vbones.x)] * vweights.x;\n"
" m += bonemats[int(vbones.y)] * vweights.y;\n"
" m += bonemats[int(vbones.z)] * vweights.z;\n"
" m += bonemats[int(vbones.w)] * vweights.w;\n"
" vec4 mpos = vec4(gl_Vertex * m, gl_Vertex.w);\n"
" gl_Position = gl_ModelViewProjectionMatrix * mpos;\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
" mat3 madjtrans = mat3(cross(m[1].xyz, m[2].xyz), cross(m[2].xyz, m[0].xyz), cross(m[0].xyz, m[1].xyz));\n"
" vec3 mnormal = gl_Normal * madjtrans;\n"
" vec3 mtangent = vtangent.xyz * madjtrans; // tangent not used, just here as an example\n"
" vec3 mbitangent = cross(mnormal, mtangent) * vtangent.w; // bitangent not used, just here as an example\n"
" gl_FrontColor = gl_Color * (clamp(dot(normalize(gl_NormalMatrix * mnormal), gl_LightSource[0].position.xyz), 0.0, 1.0) * gl_LightSource[0].diffuse + gl_LightSource[0].ambient);\n"
"}\n",
片段着色器:
"uniform sampler2D tex;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = gl_Color * texture2D(tex, gl_TexCoord[0].xy);\n"
"}\n",
我试图将其转换为现代 opengl(vbo、vao、着色器版本 330 等),但我不知道哪个失败了。你能告诉我将其转换为现代 opengl 的正确形式吗?
PD:我使用的是 3.3 版的 opengl。
添加重要信息:
好的,这是我的 renderiqm() 修改函数:
void renderiqm(GLSLProgram& mainShader)
{
m_matrix->loadIdentity();
matrixTransformations();
mainShader.sendUniform("modelYAxisDiff",getYAxisDiff());
mainShader.sendUniform4x4("modelMatrix", m_matrix->getModelMatrix());
//envía la matriz de normales
// mainShader.sendUniform4x4("normalMatrix", m_matrix->getNormalMatrix());
mainShader.sendUniform3x3("normalMatrix", glm::value_ptr(m_matrix->getNormalMatrix()));
//envía la matriz de transformación (modelview)
mainShader.sendUniform4x4("modelViewMatrix", glm::value_ptr(m_matrix->getModelViewMatrix()));
mainShader.sendUniform("objColor", m_color);
m_matrix->pushMatrix(MODEL_MATRIX);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferData(GL_UNIFORM_BUFFER, ubosize, NULL, GL_STREAM_DRAW);
glBufferSubData(GL_UNIFORM_BUFFER, bonematsoffset, numjoints*sizeof(Matrix3x4), outframe[0].a.v);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
vertex *vert = NULL;
GLsizei stride = sizeof(vert->position)+sizeof(vert->normal)+sizeof(vert->tangent)+sizeof(vert->texcoord);
if(numframes > 0)
{
stride+= sizeof(vert->blendindex)+sizeof(vert->blendweight);
}
//vertices
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE, stride, 0);
//normales
glEnableVertexAttribArray(1);
glVertexAttribPointer(1,3,GL_FLOAT, GL_FALSE, stride, (void*)sizeof(vert->position));
//tangente
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, stride, (void*)sizeof(vert->position)+sizeof(vert->normal));
//texturas
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, stride, (void*)sizeof(vert->position)+sizeof(vert->normal)+sizeof(vert->tangent));
if(numframes > 0)
{
//blendweight
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (void*)sizeof(vert->position)+sizeof(vert->normal)+sizeof(vert->tangent)+sizeof(vert->texcoord));
//blendindex
glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 4, GL_UNSIGNED_BYTE, GL_FALSE, stride, (void*)sizeof(vert->position)+sizeof(vert->normal)+sizeof(vert->tangent)+sizeof(vert->texcoord)+sizeof(vert->blendindex));
}
iqmtriangle *tris = NULL;
//DEBUG
int i=0;
for(i = 0; i < m_textureIndices.size(); i++)
{
iqmmesh &m = meshes[i];
glBindTexture(GL_TEXTURE_2D, textures[i] ? textures[i] : notexture);
tTextures[i].bindTexture(0);
glDrawElements(GL_TRIANGLES, 3*m.num_triangles, GL_UNSIGNED_INT, &tris[m.first_triangle]);
}
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
if(numframes > 0)
{
glDisableVertexAttribArray(4);
glDisableVertexAttribArray(5);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//glPopMatrix();
m_matrix->popMatrix(MODEL_MATRIX);
}
澄清:
mainShader 是一个经过测试的着色器接口,可以正常工作(这里没有错误),
m_matrix 是一个 GLM 接口,也可以正常工作。
vertexShader 应该是这个:
string vAnimationShader = "\n\
#version 330 \n\
\n\
uniform mat4 projectionMatrix; \n\
uniform mat4 modelViewMatrix; \n\
uniform mat4 normalMatrix; \n\
uniform mat4 modelMatrix; \n\
uniform vec3 objColor; \n\
\n\
uniform mat4 DepthBiasMVP; \n\
smooth out vec4 ShadowCoord;\n\
\n\
smooth out vec2 texCoord; \n\
smooth out vec3 vNormal; \n\
smooth out vec3 vEyeSpacePos; \n\
smooth out vec3 vWorldPos; \n\
smooth out vec3 vObjColor; \n\
\n\
layout (location = 0) in vec3 inPosition; \n\
layout (location = 3) in vec2 inCoord; \n\
layout (location = 1) in vec3 inNormal; \n\
\n\
uniform mat3x4 bonemats[80];\n\
\n\
layout (location = 4) in vec4 vweights;\n\
layout (location = 5) in vec4 vbones;\n\
layout (location = 2) in vec4 vtangent;\n\
void main(void)\n\
{\n\
vObjColor = objColor; \n\
mat3x4 m = bonemats[int(vbones.x)] * vweights.x;\n\
m += bonemats[int(vbones.y)] * vweights.y;\n\
m += bonemats[int(vbones.z)] * vweights.z;\n\
m += bonemats[int(vbones.w)] * vweights.w;\n\
vec4 vEyeSpacePosVertex = modelViewMatrix*vec4(inPosition, 1.0); \n\
gl_Position = projectionMatrix*vEyeSpacePosVertex; \n\
mat3 madjtrans = mat3(cross(m[1].xyz, m[2].xyz), cross(m[2].xyz, m[0].xyz), cross(m[0].xyz, m[1].xyz));\n\
vec3 mnormal = inNormal * madjtrans;\n\
vec3 mtangent = vtangent.xyz * madjtrans; // tangent not used, just here as an example\n\
vec3 mbitangent = cross(mnormal, mtangent) * vtangent.w; // bitangent not used, just here as an example\n\
texCoord = inCoord; \n\
vec4 vRes = normalMatrix*vec4(inNormal, 0.0); \n\
vNormal = vRes.xyz; \n\
vEyeSpacePos = vEyeSpacePosVertex.xyz; \n\
vec4 vWorldPosVertex = modelMatrix*vec4(inPosition, 1.0); \n\
vWorldPos = vWorldPosVertex.xyz; \n\
ShadowCoord = DepthBiasMVP * vWorldPosVertex; \n\
}\n\
";
我没有发现错误...在屏幕上我没有看到 iqm 模型..所有其他的东西都画得很好,但没有出现 iqm 模型。
重要发现:
最近发现问题出现在Opengl Context为3.2+的时候。如果我切换到 3.1 版的 opengl 上下文,它可以与我修改后的函数完美配合。
我没有找到问题所在...我将其与已弃用的函数相关联,但我找不到。拜托,你能帮帮我吗?非常感谢。
问题是没有 vao 的 vbo 初始化,我修复了它,现在模型可以正确渲染。
我需要帮助将 IQM 模型的渲染函数 (void renderiqm()) 转换为现代 OpenGL(没有弃用的函数,如 enableClientState() 等)。
renderiqm()函数的代码在这里:
https://github.com/lsalzman/iqm/blob/master/demo/gpu-demo.cpp
这些是着色器:
顶点着色器:
"#version 120\n"
"#ifdef GL_ARB_uniform_buffer_object\n"
" #extension GL_ARB_uniform_buffer_object : enable\n"
" layout(std140) uniform animdata\n"
" {\n"
" uniform mat3x4 bonemats[80];\n"
" };\n"
"#else\n"
" uniform mat3x4 bonemats[80];\n"
"#endif\n"
"attribute vec4 vweights;\n"
"attribute vec4 vbones;\n"
"attribute vec4 vtangent;\n"
"void main(void)\n"
"{\n"
" mat3x4 m = bonemats[int(vbones.x)] * vweights.x;\n"
" m += bonemats[int(vbones.y)] * vweights.y;\n"
" m += bonemats[int(vbones.z)] * vweights.z;\n"
" m += bonemats[int(vbones.w)] * vweights.w;\n"
" vec4 mpos = vec4(gl_Vertex * m, gl_Vertex.w);\n"
" gl_Position = gl_ModelViewProjectionMatrix * mpos;\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
" mat3 madjtrans = mat3(cross(m[1].xyz, m[2].xyz), cross(m[2].xyz, m[0].xyz), cross(m[0].xyz, m[1].xyz));\n"
" vec3 mnormal = gl_Normal * madjtrans;\n"
" vec3 mtangent = vtangent.xyz * madjtrans; // tangent not used, just here as an example\n"
" vec3 mbitangent = cross(mnormal, mtangent) * vtangent.w; // bitangent not used, just here as an example\n"
" gl_FrontColor = gl_Color * (clamp(dot(normalize(gl_NormalMatrix * mnormal), gl_LightSource[0].position.xyz), 0.0, 1.0) * gl_LightSource[0].diffuse + gl_LightSource[0].ambient);\n"
"}\n",
片段着色器:
"uniform sampler2D tex;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = gl_Color * texture2D(tex, gl_TexCoord[0].xy);\n"
"}\n",
我试图将其转换为现代 opengl(vbo、vao、着色器版本 330 等),但我不知道哪个失败了。你能告诉我将其转换为现代 opengl 的正确形式吗?
PD:我使用的是 3.3 版的 opengl。
添加重要信息:
好的,这是我的 renderiqm() 修改函数:
void renderiqm(GLSLProgram& mainShader)
{
m_matrix->loadIdentity();
matrixTransformations();
mainShader.sendUniform("modelYAxisDiff",getYAxisDiff());
mainShader.sendUniform4x4("modelMatrix", m_matrix->getModelMatrix());
//envía la matriz de normales
// mainShader.sendUniform4x4("normalMatrix", m_matrix->getNormalMatrix());
mainShader.sendUniform3x3("normalMatrix", glm::value_ptr(m_matrix->getNormalMatrix()));
//envía la matriz de transformación (modelview)
mainShader.sendUniform4x4("modelViewMatrix", glm::value_ptr(m_matrix->getModelViewMatrix()));
mainShader.sendUniform("objColor", m_color);
m_matrix->pushMatrix(MODEL_MATRIX);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferData(GL_UNIFORM_BUFFER, ubosize, NULL, GL_STREAM_DRAW);
glBufferSubData(GL_UNIFORM_BUFFER, bonematsoffset, numjoints*sizeof(Matrix3x4), outframe[0].a.v);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
vertex *vert = NULL;
GLsizei stride = sizeof(vert->position)+sizeof(vert->normal)+sizeof(vert->tangent)+sizeof(vert->texcoord);
if(numframes > 0)
{
stride+= sizeof(vert->blendindex)+sizeof(vert->blendweight);
}
//vertices
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE, stride, 0);
//normales
glEnableVertexAttribArray(1);
glVertexAttribPointer(1,3,GL_FLOAT, GL_FALSE, stride, (void*)sizeof(vert->position));
//tangente
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, stride, (void*)sizeof(vert->position)+sizeof(vert->normal));
//texturas
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, stride, (void*)sizeof(vert->position)+sizeof(vert->normal)+sizeof(vert->tangent));
if(numframes > 0)
{
//blendweight
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (void*)sizeof(vert->position)+sizeof(vert->normal)+sizeof(vert->tangent)+sizeof(vert->texcoord));
//blendindex
glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 4, GL_UNSIGNED_BYTE, GL_FALSE, stride, (void*)sizeof(vert->position)+sizeof(vert->normal)+sizeof(vert->tangent)+sizeof(vert->texcoord)+sizeof(vert->blendindex));
}
iqmtriangle *tris = NULL;
//DEBUG
int i=0;
for(i = 0; i < m_textureIndices.size(); i++)
{
iqmmesh &m = meshes[i];
glBindTexture(GL_TEXTURE_2D, textures[i] ? textures[i] : notexture);
tTextures[i].bindTexture(0);
glDrawElements(GL_TRIANGLES, 3*m.num_triangles, GL_UNSIGNED_INT, &tris[m.first_triangle]);
}
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
if(numframes > 0)
{
glDisableVertexAttribArray(4);
glDisableVertexAttribArray(5);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//glPopMatrix();
m_matrix->popMatrix(MODEL_MATRIX);
}
澄清: mainShader 是一个经过测试的着色器接口,可以正常工作(这里没有错误), m_matrix 是一个 GLM 接口,也可以正常工作。
vertexShader 应该是这个:
string vAnimationShader = "\n\
#version 330 \n\
\n\
uniform mat4 projectionMatrix; \n\
uniform mat4 modelViewMatrix; \n\
uniform mat4 normalMatrix; \n\
uniform mat4 modelMatrix; \n\
uniform vec3 objColor; \n\
\n\
uniform mat4 DepthBiasMVP; \n\
smooth out vec4 ShadowCoord;\n\
\n\
smooth out vec2 texCoord; \n\
smooth out vec3 vNormal; \n\
smooth out vec3 vEyeSpacePos; \n\
smooth out vec3 vWorldPos; \n\
smooth out vec3 vObjColor; \n\
\n\
layout (location = 0) in vec3 inPosition; \n\
layout (location = 3) in vec2 inCoord; \n\
layout (location = 1) in vec3 inNormal; \n\
\n\
uniform mat3x4 bonemats[80];\n\
\n\
layout (location = 4) in vec4 vweights;\n\
layout (location = 5) in vec4 vbones;\n\
layout (location = 2) in vec4 vtangent;\n\
void main(void)\n\
{\n\
vObjColor = objColor; \n\
mat3x4 m = bonemats[int(vbones.x)] * vweights.x;\n\
m += bonemats[int(vbones.y)] * vweights.y;\n\
m += bonemats[int(vbones.z)] * vweights.z;\n\
m += bonemats[int(vbones.w)] * vweights.w;\n\
vec4 vEyeSpacePosVertex = modelViewMatrix*vec4(inPosition, 1.0); \n\
gl_Position = projectionMatrix*vEyeSpacePosVertex; \n\
mat3 madjtrans = mat3(cross(m[1].xyz, m[2].xyz), cross(m[2].xyz, m[0].xyz), cross(m[0].xyz, m[1].xyz));\n\
vec3 mnormal = inNormal * madjtrans;\n\
vec3 mtangent = vtangent.xyz * madjtrans; // tangent not used, just here as an example\n\
vec3 mbitangent = cross(mnormal, mtangent) * vtangent.w; // bitangent not used, just here as an example\n\
texCoord = inCoord; \n\
vec4 vRes = normalMatrix*vec4(inNormal, 0.0); \n\
vNormal = vRes.xyz; \n\
vEyeSpacePos = vEyeSpacePosVertex.xyz; \n\
vec4 vWorldPosVertex = modelMatrix*vec4(inPosition, 1.0); \n\
vWorldPos = vWorldPosVertex.xyz; \n\
ShadowCoord = DepthBiasMVP * vWorldPosVertex; \n\
}\n\
";
我没有发现错误...在屏幕上我没有看到 iqm 模型..所有其他的东西都画得很好,但没有出现 iqm 模型。
重要发现:
最近发现问题出现在Opengl Context为3.2+的时候。如果我切换到 3.1 版的 opengl 上下文,它可以与我修改后的函数完美配合。
我没有找到问题所在...我将其与已弃用的函数相关联,但我找不到。拜托,你能帮帮我吗?非常感谢。
问题是没有 vao 的 vbo 初始化,我修复了它,现在模型可以正确渲染。