c++ - 可视化向量范数的问题(OpenGL C++)
问题描述
我正在用 C++ 制作模型查看器,并尝试使用顶点、片段和几何着色器在模型上可视化我的向量规范,但是它只在屏幕上显示几行而不是每个向量一个,这是我的着色器代码:
//Create vertex shader for visNorm
const GLchar* vertexShaderVN =
"#version 410\n " \
"attribute vec3 a_Position; " \
"attribute vec3 in_Normal; " \
" " \
"out VS_OUT { " \
"vec3 normal; " \
"} vs_out; " \
"uniform mat4 u_View; " \
"uniform mat4 u_Model; " \
"void main() " \
"{ " \
"gl_Position = u_View * u_Model * vec4(a_Position, 1.0); " \
"mat3 normalMatrix = mat3(transpose(inverse(u_View * u_Model))); " \
"vs_out.normal = normalize(vec3(vec4(normalMatrix * in_Normal, 0.0))); " \
"} " \
" ";
//Create geometry shader for visNorm
const GLchar* geometryShaderVN =
"#version 410\n " \
"layout (triangles) in;" \
"layout (line_strip, max_vertices = 6) out;" \
"in VS_OUT {" \
"vec3 normal;" \
"} gs_in[];" \
"const float MAGNITUDE = 1.0; " \
"uniform mat4 u_Projection; " \
"void GenerateLine(int index)" \
"{" \
"gl_Position = u_Projection * gl_in[index].gl_Position;" \
"EmitVertex();" \
"gl_Position = u_Projection * (gl_in[index].gl_Position + vec4(gs_in[index].normal, 0.0) * MAGNITUDE); " \
"EmitVertex();" \
"EndPrimitive();" \
"}" \
"void main()" \
"{" \
"GenerateLine(0);" \
"GenerateLine(1);" \
"GenerateLine(2);" \
"}" \
"";
//Create fragment shader for no visNorm
const GLchar* fragmentShaderSrcVN =
"#version 410\n " \
"out vec4 FragColor;" \
"void main()" \
"{ " \
"FragColor = vec4(1.0, 1.0, 0.0, 1.0);" \
"} " \
" ";
GLuint programIdVN = LoadShader(vertexShaderVN, geometryShaderVN, fragmentShaderSrcVN);
我的加载着色器的代码:
GLuint LoadShader(const GLchar* vert, const GLchar* geo, const GLchar* frag)
{
//Create a new vertex shader, attach source code, compile it and check for errors
GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderId, 1, &vert, NULL);
glCompileShader(vertexShaderId);
GLint success = 0;
glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &success);
//Display any errors that occur in the vertex shader
if (!success)
{
GLint maxLength = 0;
glGetShaderiv(vertexShaderId, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(vertexShaderId, maxLength, &maxLength, &errorLog.at(0));
std::cout << &errorLog.at(0) << std::endl;
throw std::exception();
}
//Create a new geometry shader, attach source code, compile it and check for errors
GLuint geometryShaderId = glCreateShader(GL_GEOMETRY_SHADER);
glShaderSource(geometryShaderId, 1, &geo, NULL);
glCompileShader(geometryShaderId);
glGetShaderiv(geometryShaderId, GL_COMPILE_STATUS, &success);
//Display any errors that occur in the vertex shader
if (!success)
{
GLint maxLength = 0;
glGetShaderiv(geometryShaderId, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(geometryShaderId, maxLength, &maxLength, &errorLog.at(0));
std::cout << &errorLog.at(0) << std::endl;
//throw std::exception();
}
//Create a new fragment shader, attach source code, compile it and check for errors
GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderId, 1, &frag, NULL);
glCompileShader(fragmentShaderId);
glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &success);
//Display any errors that occur in the fragment shader
if (!success)
{
GLint maxLength = 0;
glGetShaderiv(fragmentShaderId, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(fragmentShaderId, maxLength, &maxLength, &errorLog.at(0));
std::cout << &errorLog.at(0) << std::endl;
throw std::exception();
}
//Create new shader program and attach our shader objects
GLuint programId = glCreateProgram();
glAttachShader(programId, vertexShaderId);
glAttachShader(programId, geometryShaderId);
glAttachShader(programId, fragmentShaderId);
//Ensure the VAO "position" attribute stream gets set as the first position during the link.
glBindAttribLocation(programId, 0, "a_Position");
glBindAttribLocation(programId, 1, "a_Texcord");
glBindAttribLocation(programId, 2, "in_Normal");
//Perform the link and check for failure
glLinkProgram(programId);
glGetProgramiv(programId, GL_LINK_STATUS, &success);
if (!success)
{
GLint maxLength = 0;
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errorLog(maxLength);
glGetProgramInfoLog(programId, maxLength, &maxLength, &errorLog.at(0));
std::cout << &errorLog.at(0) << std::endl;
//throw std::exception();
}
//Detach and destroy the shader objects. These are no longer needed because we now have a complete shader program
glDetachShader(programId, vertexShaderId);
glDeleteShader(vertexShaderId);
glDetachShader(programId, geometryShaderId);
glDeleteShader(geometryShaderId);
glDetachShader(programId, fragmentShaderId);
glDeleteShader(fragmentShaderId);
//Find uniform locations
GLint colorloc = glGetUniformLocation(programId, "u_Texcord");
GLint modelLoc = glGetUniformLocation(programId, "u_Model");
GLint viewLoc = glGetUniformLocation(programId, "u_View");
GLint projectionLoc = glGetUniformLocation(programId, "u_Projection");
if (modelLoc == -1)
{
throw std::exception();
}
if (projectionLoc == -1)
{
throw std::exception();
}
return programId;
}
如果有人对为什么这不能按预期工作有任何想法,那将非常感谢!
解决方案
推荐阅读
- python - Expokit 在 Python 上的实现
- excel - 使用 Excel VBA 在 Word 文档标题中写入
- java - DynamoDB 查询和分区键,简单问题
- r - 当表名称中没有“_”时,问题写入非默认模式
- java - 如何使用 Xpath 在谷歌搜索中找到自动建议
- python-3.x - 如何在 python 中播放实时音频,同时不断录制?
- android - 在 Jenkins 的 Docker 容器中编译 Android 项目
- matlab - 具有 theta、phi 和半径的 Polar(3D) 图
- javascript - 除大数时,有没有办法获得更精确的结果?
- excel - 是否有像 IsNumeric 这样的 VBA 函数,但用于文本?当涉及范围时,IsText 和 IsEmpty 的工作方式不同