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) 之后,我之前绘制的三角形消失了。

我已经看了两次视频,以确保我没有犯任何拼写错误或类似的错误。

相关部分代码如下:

ma​​in.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相乘后三角形消失的主要内容,如果未能解决你的问题,请参考以下文章

全屏模糊 GLSL 显示对角线(OpenGL 核心)

GLSL 计算着色器闪烁块/正方形伪影

Python之OpenGL笔记(5):OpenGL着色器语言(GLSL)应用画三角形

C#开发的OpenRA的GLSL介绍

C#开发的OpenRA的GLSL介绍

更快的全屏渲染(OpenGL/glsl)?