GLSL:与mat4相乘后三角形消失
Posted
技术标签:
【中文标题】GLSL:与mat4相乘后三角形消失【英文标题】:GLSL: Triangle disappears after multiplying with mat4 【发布时间】:2017-05-27 11:30:20 【问题描述】:我正在尝试使用this tutorial series 学习 OpenGL。在教程 4(纹理)之前一切正常,但在教程 5 (3D Motion) 之后,我之前绘制的三角形消失了。
我已经看了两次视频,以确保我没有犯任何拼写错误或类似的错误。
相关部分代码如下:
main.cpp
#include <iostream>
#include <GL/glew.h>
#include <glm/glm.hpp>
#include "display.h"
#include "shader.h"
#include "mesh.h"
#include "texture.h"
#include "transform.h"
using namespace std;
int main()
Display display(800, 600, "Hello World!");
Vertex vertices[] =
Vertex(glm::vec3(-0.5, -0.5, 0), glm::vec2(0.0, 0.0)),
Vertex(glm::vec3(0.5, -0.5, 0), glm::vec2(1.0, 0.0)),
Vertex(glm::vec3(0, 0.5, 0), glm::vec2(0.5, 1.0)),
;
Mesh mesh(vertices, sizeof(vertices) / sizeof(vertices[0]));
Shader shader("./res/basicShader");
Texture texture("./res/bricks.jpg");
Transform transform;
while(!display.IsClosed())
display.Clear(0.0f, 0.1f, 0.3f, 1.0f);
shader.Bind();
texture.Bind(0);
shader.Update(transform);
mesh.Draw();
display.Update();
return 0;
shader.h
#ifndef SHADER_H
#define SHADER_H
#include "transform.h"
#include <string>
#include <GL/glew.h>
class Shader
public:
Shader(const std::string& fileName);
void Bind();
void Update(const Transform& transform);
virtual ~Shader();
protected:
private:
static const unsigned int NUM_SHADERS = 2;
Shader(const Shader& other)
//Shader& operator=(const Shader& other);
void operator=(const Shader& other)
enum
TRANSFORM_U,
NUM_UNIFORMS
;
GLuint m_program;
GLuint m_shaders[NUM_SHADERS];
GLuint m_uniforms[NUM_UNIFORMS];
;
#endif // SHADER_H
shader.cpp
#include "shader.h"
#include <iostream>
#include <fstream>
#include <string>
static void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage);
static std::string LoadShader(const std::string& fileName);
static GLuint CreateShader(const std::string& text, GLenum shaderType);
Shader::Shader(const std::string& fileName)
//ctor
m_program = glCreateProgram();
m_shaders[0] = CreateShader(LoadShader(fileName + ".vs"), GL_VERTEX_SHADER);
m_shaders[1] = CreateShader(LoadShader(fileName + ".fs"), GL_FRAGMENT_SHADER);
for(unsigned int i = 0; i<NUM_SHADERS; ++i)
glAttachShader(m_program, m_shaders[i]);
glBindAttribLocation(m_program, 0, "position");
glBindAttribLocation(m_program, 1, "texCoord");
glLinkProgram(m_program);
CheckShaderError(m_program, GL_LINK_STATUS, true, "Error: Program linking failed: ");
glValidateProgram(m_program);
CheckShaderError(m_program, GL_VALIDATE_STATUS, true, "Error: Program is invalid: ");
m_uniforms[TRANSFORM_U] = glGetUniformLocation(m_program, "transform");
Shader::~Shader()
//dtor
for(unsigned int i = 0; i<NUM_SHADERS; ++i)
glDetachShader(m_program, m_shaders[i]);
glDeleteShader(m_shaders[i]);
glDeleteProgram(m_program);
static GLuint CreateShader(const std::string& text, GLenum shaderType)
GLuint shader = glCreateShader(shaderType);
if(shader == 0)
std::cerr<<"Error: Shader creation failed!"<<std::endl;
const GLchar* sourceShaderStrings[1];
GLint sourceShaderStringLengths[1];
sourceShaderStrings[0] = text.c_str();
sourceShaderStringLengths[0] = text.length();
glShaderSource(shader, 1, sourceShaderStrings, sourceShaderStringLengths);
glCompileShader(shader);
CheckShaderError(shader, GL_COMPILE_STATUS, false, "Error: Shader compilation failed: ");
return shader;
static std::string LoadShader(const std::string& fileName)
std::ifstream file;
file.open(fileName.c_str());
std::string output;
std::string line;
if(file.is_open())
while(file.good())
getline(file, line);
output.append(line + "\n");
else
std::cerr<<"Unable to load shader: "<<fileName<<std::endl;
return output;
static void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage)
GLint success = 0;
GLchar error[1024] = 0;
if(isProgram)
glGetProgramiv(shader, flag, &success);
else
glGetShaderiv(shader, flag, &success);
if(success == GL_FALSE)
if(isProgram)
glGetProgramInfoLog(shader, sizeof(error), NULL, error);
else
glGetShaderInfoLog(shader, sizeof(error), NULL, error);
std::cerr<<errorMessage<<": '"<<error<<"' "<<std::endl;
void Shader::Bind()
glUseProgram(m_program);
void Shader::Update(const Transform& transform)
glm::mat4 model = transform.GetModel();
glUniformMatrix4fv(m_uniforms[TRANSFORM_U], 1, GL_FALSE, &model[0][0]);
transform.h
#ifndef TRANSFORM_H
#define TRANSFORM_H
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>
class Transform
public:
Transform(const glm::vec3& pos = glm::vec3(), const glm::vec3& rot = glm::vec3(), const glm::vec3& scale = glm::vec3(1.0f, 1.0f, 1.0f)):
m_pos(pos),
m_rot(rot),
m_scale(scale)
inline glm::mat4 GetModel() const
glm::mat4 posMatrix = glm::translate(m_pos);
glm::mat4 rotXMatrix = glm::rotate(m_rot.x, glm::vec3(1, 0, 0));
glm::mat4 rotYMatrix = glm::rotate(m_rot.y, glm::vec3(0, 1, 0));
glm::mat4 rotZMatrix = glm::rotate(m_rot.z, glm::vec3(0, 0, 1));
glm::mat4 scaleMatrix = glm::scale(m_rot);
glm::mat4 rotMatrix = rotZMatrix * rotYMatrix * rotXMatrix;
return posMatrix * rotMatrix * scaleMatrix;
inline glm::vec3& GetPos()return m_pos;
inline glm::vec3& GetRot()return m_rot;
inline glm::vec3& GetScale()return m_scale;
inline void SetPos(const glm::vec3& pos)m_pos = pos;
inline void SetRot(const glm::vec3& rot)m_rot = rot;
inline void SetScale(const glm::vec3& scale)m_scale = scale;
virtual ~Transform();
protected:
private:
Transform(const Transform& other)
void operator=(const Transform& other)
glm::vec3 m_pos;
glm::vec3 m_rot;
glm::vec3 m_scale;
;
#endif // TRANSFORM_H
顶点着色器 文件名:basicShader.vs
#version 120
attribute vec3 position;
attribute vec2 texCoord;
varying vec2 texCoord0;
uniform mat4 transform;
void main()
//gl_Position = vec4(position, 1.0); // #1
gl_Position = transform * vec4(position, 1.0); // #2
// if I uncomment Statement #1 and put comment on #2, it works obviously I can not move the triangle.
texCoord0 = texCoord;
片段着色器 文件名:basicShader.fs
#version 120
uniform sampler2D diffuse;
varying vec2 texCoord0;
void main()
gl_FragColor = texture2D(diffuse, texCoord0); //vec2(0.2, 0.2)); //vec4(1.0, 0.0, 0.0, 1.0);
【问题讨论】:
【参考方案1】:你使用你的 rot 向量来定义你的比例矩阵。
glm::mat4 scaleMatrix = glm::scale(m_rot);
你应该使用你的比例向量
glm::mat4 scaleMatrix = glm::scale(m_scale);
您正在按 0 进行缩放,这会将您的所有点设置为 (0,0,0) 位置,它们会发生碰撞并且您的脸会消失
【讨论】:
非常感谢@draykoon-d。我不知道我怎么连看了两遍视频都想不通。很抱歉因为我犯了这么愚蠢的错误而耽误您的时间。以上是关于GLSL:与mat4相乘后三角形消失的主要内容,如果未能解决你的问题,请参考以下文章