OpenGL 忽略四边形并将它们变成三角形
Posted
技术标签:
【中文标题】OpenGL 忽略四边形并将它们变成三角形【英文标题】:OpenGL ignores Quads and makes them Triangles 【发布时间】:2018-11-09 02:18:52 【问题描述】:这是我第二次制作游戏引擎,但我现在有点卡住了,因为我无法弄清楚为什么会发生这种情况,无论我发送什么对象,OpenGL 只会在上面绘制一个白色三角形屏幕中心,like this.
我什至从渲染器和相机对象上的上一个引擎中复制了我的旧代码,但行为仍然相同,所以我猜它与渲染脚本有关。
渲染器:
Renderer2D::Renderer2D(const Shader& shader)
this->shader = shader;
this->Init();
Renderer2D::~Renderer2D()
glDeleteVertexArrays(1, &this->QuadVAO);
void Renderer2D::Render(Texture & texture, iVec2 position, iVec2 size, float rotation, iVec3 color)
this->shader.Use();
iMat4 model;
using namespace glm;
model = translate(model, iVec3(position.x, position.y, 0.0f));
/*
model = translate(model, iVec3(size.x * 0.5f, size.y * 0.5f, 0.0f));
model = rotate(model, rotation, iVec3(0.0f, 0.0f, 1.0f));
model = translate(model, iVec3(size.x * -0.5f, size.y * -0.5f, 0.0f));
*/
model = glm::scale(model, iVec3(size.x, size.y, 1.0f));
this->shader.SetMatrix4("model2D", model);
this->shader.SetVector3f("color2D", color);
glActiveTexture(GL_TEXTURE0);
texture.Bind();
glBindVertexArray(this->QuadVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
void Renderer2D::Init()
U16 VBO;
float vertices[] =
// Pos // Tex
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 0.0f
;
glGenVertexArrays(1, &this->QuadVAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindVertexArray(this->QuadVAO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
顶点着色器:
#version 330 core
layout (location = 0) in vec4 vertex; // <vec2 position, vec2 texCoords>
out vec2 TexCoords;
uniform mat4 view2D;
uniform mat4 model2D;
uniform mat4 projection2D;
void main()
TexCoords = vertex.zw;
gl_Position = projection2D * view2D * mode2Dl * vec4(vertex.xy, 0.0, 1.0);
编辑:
顶点着色器:
#version 330 core
layout (location = 0) in vec4 vertex; // <vec2 position, vec2 texCoords>
out vec2 TexCoords;
uniform mat4 view2D;
uniform mat4 model2D;
uniform mat4 projection2D;
void main()
TexCoords = vertex.zw;
gl_Position = projection2D * view2D * model2D * vec4(vertex.xy, 0.0, 1.0);
片段着色器:
#version 330 core
in vec2 TexCoords;
out vec4 color2D; //Fixed the error!
uniform sampler2D image2D;
uniform vec3 color2D;
void main()
color2D = vec4(color2D, 1.0) * texture(image2D, TexCoords);
资源.cpp
Shader Resources::LoadShaderFromFile(const char * vertexSource, const char * fragmentSource)
using namespace std;
string vertexCode;
string fragmentCode;
try
ifstream vertexShaderFile(vertexSource);
ifstream fragmentShaderFile(fragmentSource);
stringstream vShaderStream, fShaderStream;
vShaderStream << vertexShaderFile.rdbuf();
fShaderStream << fragmentShaderFile.rdbuf();
vertexShaderFile.close();
fragmentShaderFile.close();
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
catch (exception e)
cout << "ERROR::SHADER: Failed to read shader files" << std::endl;
const char *vShaderCode = vertexCode.c_str();
const char *fShaderCode = fragmentCode.c_str();
Shader shader;
shader.Compile(vShaderCode, fShaderCode);
return shader;
【问题讨论】:
您运行的是什么版本的 OpenGL?您是否知道自 OpenGL 3+ 起已弃用四边形? @Patrick 我刚刚在标题上添加了四边形,因为我正在尝试绘制四边形,但实际上我正在绘制两个相邻的三角形,只是用该代码更新了问题。 您可以尝试将三角形的 z 坐标更改为 -1.0f 而不是 0.0f。我相信三角形正在剪裁,因为正 z 超出了屏幕范围。 @Patrickmodel = translate(model, iVec3(position.x, position.y, -1.0f));
换了这条线,是这个意思吗?
@Patrick 我开始认为是视口错误之类的,因为无论我输入什么坐标,三角形都将始终处于相同位置且没有纹理。
【参考方案1】:
你的着色器甚至没有编译。当您声明矩阵制服时,您使用名称model2D
、view2D
和projection2D
:
uniform mat4 view2D;
uniform mat4 model2D;
uniform mat4 projection2D;
但是当您使用矩阵时,您会使用名称view
、model
和projection
:
gl_Position = projection * view * model * vec4(vertex.xy, 0.0, 1.0);
我建议检查着色器对象是否编译成功以及程序对象链接是否成功。
可以通过glGetShaderiv
和参数GL_COMPILE_STATUS
检查着色器是否编译成功。
例如
GLuint shaderObj = .... ;
glCompileShader( shaderObj );
GLint status = GL_TRUE;
glGetShaderiv( shaderObj, GL_COMPILE_STATUS, &status );
if ( status == GL_FALSE )
GLint logLen;
glGetShaderiv( shaderObj, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetShaderInfoLog( shaderObj, logLen, &written, log.data() );
std::cout << "compile error:" << std::endl << log.data() << std::endl;
可以通过glGetProgramiv
和参数GL_LINK_STATUS
来检查程序是否链接成功。
例如
GLuint progObj = ....;
glLinkProgram( progObj );
GLint status = GL_TRUE;
glGetProgramiv( progObj, GL_LINK_STATUS, &status );
if ( status == GL_FALSE )
GLint logLen;
glGetProgramiv( progObj, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetProgramInfoLog( progObj, logLen, &written, log.data() );
std::cout << "link error:" << std::endl << log.data() << std::endl;
【讨论】:
得到以下错误,链接错误:顶点信息-----------(0):错误C5145:必须写入gl_Position。 刚刚用 Resources.cpp 更新了代码,但我认为加载着色器时没有错误。 @MarceloColonia 您的代码中有错字:mode2Dl
而不是 model2D
抱歉打错了是因为我手动写了更新而不是复制它,原来的代码是正确的。
@MarceloColonia 你得到一个链接错误,可能你交换了顶点和片段着色器,或者你没有从文件中正确加载着色器并且源代码字符串是空的。以上是关于OpenGL 忽略四边形并将它们变成三角形的主要内容,如果未能解决你的问题,请参考以下文章
opengl绘图,画一个旋转的四边形和一个旋转的三角形,平滑着色和单一着色