OpenGL学习之矩阵变换实例

开发环境:

xcode

第三方库:

glfw、glew、glm、SOIL

代码:

1. ShaderAdmin.hpp
//
//  ShaderAdmin.hpp
//  GL_Program
//
//

#ifndef ShaderAdmin_hpp
#define ShaderAdmin_hpp

#include <stdio.h>
#include <fstream>
#include <sstream>
#include <iostream>
#include <GL/glew.h>

using namespace std;
class ShaderAdmin
{
public:
    //着色器ID;
    GLuint m_program;
    //构造器读取并构建着色器
    ShaderAdmin(const GLchar *vertexPath,const GLchar *fragmentPath);
    ~ShaderAdmin();
    //加载纹理资源
    void Use();
private:
    void compileShader(const GLchar *vShaderCode,const GLchar *fShaderCode);
    void getCompileShaderErrorLog(GLuint shader);
    void getLinkShaderProgramErrorLog(GLuint shaderProgram);
};

#endif /* ShaderAdmin_hpp */
2. ShaderAdmin.cpp
//
//  ShaderAdmin.cpp
//  GL_Program
//
//  Created by LiYong on 2018/3/12.
//  Copyright © 2018年 feiyu. All rights reserved.
//

#include "ShaderAdmin.hpp"

ShaderAdmin::ShaderAdmin(const GLchar *vertexPath,const GLchar *fragmentPath)
{
    // 1. 从文件路径中获取顶点/片段着色器
    string vertexCode;
    string fragmentCode;
    ifstream vShaderFile;
    ifstream fShaderFile;
    //保证ifstream对象可以抛出异常
    vShaderFile.exceptions(ifstream::badbit);
    fShaderFile.exceptions(ifstream::badbit);
    try
    {
        //打开文件
        vShaderFile.open(vertexPath);
        fShaderFile.open(fragmentPath);
        if (!vShaderFile.is_open()||!fShaderFile.is_open())
        {
            cout << "无法打开文件!" << endl;
            return;
        }
        stringstream vShaderStream,fShaderStream;
        //读取文件的缓冲内容到流中
        vShaderStream << vShaderFile.rdbuf();
        fShaderStream << fShaderFile.rdbuf();
        //关闭文件
        vShaderFile.close();
        fShaderFile.close();
        //转换流至字符串
        vertexCode = vShaderStream.str();
        fragmentCode = fShaderStream.str();
    }
    catch (ifstream::failure e)
    {
        cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << endl;
    }

    const GLchar *vShaderCode = vertexCode.c_str();
    const GLchar *fShaderCode = fragmentCode.c_str();
    compileShader(vShaderCode, fShaderCode);
}
ShaderAdmin::~ShaderAdmin()
{

}
void ShaderAdmin::Use()
{
    glUseProgram(this->m_program);
}
void ShaderAdmin::compileShader(const GLchar *vShaderCode, const GLchar *fShaderCode)
{
    GLuint vShader,fShader;

    vShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vShader,1,&vShaderCode,NULL);
    glCompileShader(vShader);
    getCompileShaderErrorLog(vShader);

    fShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fShader,1,&fShaderCode,NULL);
    glCompileShader(fShader);
    getCompileShaderErrorLog(fShader);

    m_program = glCreateProgram();
    glAttachShader(m_program,vShader);
    glAttachShader(m_program,fShader);
    glLinkProgram(m_program);
    getLinkShaderProgramErrorLog(m_program);

    glDeleteShader(vShader);
    glDeleteShader(fShader);
}
void ShaderAdmin::getCompileShaderErrorLog(GLuint shader)
{
    GLint sucess;
    GLchar infoLog[512];
    glGetShaderiv(shader,GL_COMPILE_STATUS,&sucess);
    if (!sucess)
    {
        glGetShaderInfoLog(shader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
}
void ShaderAdmin::getLinkShaderProgramErrorLog(GLuint shaderProgram)
{
    GLint success;
    GLchar infoLog[512];
    glGetProgramiv(shaderProgram,GL_LINK_STATUS,&success);
    if (!success)
    {
        glGetShaderInfoLog(shaderProgram,512,NULL,infoLog);
    }
}
3. TextureAdmin.hpp
//
//  texture.hpp
//  GL_Program


#ifndef TextureAdmin_hpp
#define TextureAdmin_hpp

#include <stdio.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <SOIL/SOIL.h>
#include <iostream>

using namespace std;

class TextureAdmin
{
public:
    TextureAdmin(const string imagePath);
    ~TextureAdmin();

    //绑定纹理单元
    void BindTexture();


public:
    //纹理ID
    GLuint m_pTexture;
};

#endif /* texture_hpp */
4. TextureAdmin.cpp
//
//  texture.cpp
//  GL_Program
//
//  Created by LiYong on 2018/3/13.
//  Copyright © 2018年 feiyu. All rights reserved.
//

#include "TextureAdmin.hpp"
TextureAdmin::TextureAdmin(const string imagePath)
{
    glGenTextures(1, &m_pTexture);
    glBindTexture(GL_TEXTURE_2D, m_pTexture);

    //设置纹理的采样方式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    //设置纹理的过滤方式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    //加载纹理图片
    int width , height;
    unsigned char *image = SOIL_load_image(imagePath.data(), &width, &height, 0, SOIL_LOAD_RGB);
    glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height,0, GL_RGB, GL_UNSIGNED_BYTE, image);
    glGenerateMipmap(GL_TEXTURE_2D);
    SOIL_free_image_data(image);
    glBindTexture(GL_TEXTURE_2D, 0);
}

TextureAdmin::~TextureAdmin()
{

}

void TextureAdmin::BindTexture()
{
    glBindTexture(GL_TEXTURE_2D, m_pTexture);
}
4. main.cpp

#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "ShaderAdmin.hpp"
#include "TextureAdmin.hpp"

#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>


#define WIDTH 800
#define HEIGHT 600
#define TITLE "OpenGL"
#define NUM 2

using namespace std;


GLuint VAO,VBO,EBO;
GLuint VAOs[NUM],VBOs[NUM],EBOs[NUM];
void initGL();
void initGLForOSX();
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);

void renderRectangle();

int main(int argc, const char * argv[]) {

//    initGL();
    initGLForOSX();

    GLFWwindow *win = glfwCreateWindow(WIDTH, HEIGHT, TITLE, nullptr, nullptr);
    if (!win)
    {
        printf("Failed to create GLFW window!\n");
        glfwTerminate();
        return NULL;
    }

    glfwMakeContextCurrent(win);
    glfwSetKeyCallback(win, key_callback);

    glewExperimental = GL_TRUE;
    if(glewInit() != GLEW_OK)
    {
        printf("Failed to initialize GLEW !\n");
    }

    int nWidth,nHeight;
    glfwGetFramebufferSize(win, &nWidth, &nHeight);
    glViewport(0, 0, nWidth, nHeight);

    ShaderAdmin shader("Shaders/vShader.vsh","Shaders/fShader.fsh");
    renderRectangle();

    TextureAdmin texture("Image/container.jpg");
    TextureAdmin texture2("Image/awesomeface.png");

    while (!glfwWindowShouldClose(win))
    {
        glfwPollEvents();
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        //激活纹理单元0
        glActiveTexture(GL_TEXTURE0);
        texture.BindTexture();
        glUniform1i(glGetUniformLocation(shader.m_program,"ourTexture"),0);

        //激活纹理单元1
        glActiveTexture(GL_TEXTURE1);
        texture2.BindTexture();
        glUniform1i(glGetUniformLocation(shader.m_program,"ourTexture2"),1);

        shader.Use();
        glBindVertexArray(VAO);

        //创建变换矩阵
        //1.第一个纹理
        glm::mat4 trans;

        trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
        trans = glm::rotate(trans,(GLfloat)sin(glfwGetTime()) * 10.0f, glm::vec3(0.0f, 1.0f, 0.0f));

        GLuint transform = glGetUniformLocation(shader.m_program,"transform");
        glUniformMatrix4fv(transform,1,GL_FALSE,glm::value_ptr(trans));

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        //2.第二个纹理
        glm::mat4 trans1;

        trans1 = glm::translate(trans1, glm::vec3(-0.5f, 0.5f, 0.0f));
        GLfloat scale = sin(glfwGetTime());
        trans1 = glm::scale(trans1, glm::vec3(scale,scale,scale));
        GLuint transform1 = glGetUniformLocation(shader.m_program,"transform");
        glUniformMatrix4fv(transform1,1,GL_FALSE,glm::value_ptr(trans1));

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);

        glfwSwapBuffers(win);
    }

    return 0;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
    // 当用户按下ESC键,我们设置window窗口的WindowShouldClose属性为true
    // 关闭应用程序
    if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}
void renderRectangle()
{
    GLfloat vertices[] = {
        //    ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -
        0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // 右上
        0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // 右下
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // 左下
        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // 左上
    };
    GLuint indices[] = {
        0,1,2,
        2,3,0
    };

    glGenVertexArrays(1,&VAO);
    glGenBuffers(1,&VBO);
    glGenBuffers(1,&EBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);
    //位置属性
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,8 * sizeof(GLfloat),(GLvoid *)0);
    glEnableVertexAttribArray(0);

    //颜色属性
    glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,8 * sizeof(GLfloat),(GLvoid *)(3*sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    //纹理坐标
    glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,8 * sizeof(GLfloat),(GLvoid *)(6*sizeof(GLfloat)));
    glEnableVertexAttribArray(2);

    glBindBuffer(GL_ARRAY_BUFFER,0);
    glBindVertexArray(0);

}
void initGL()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
}
void initGLForOSX()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    //Mac环境必须添加下面这行才能生效
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
}
4. 顶点着色器
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoord;

out vec3 ourColor;
out vec2 TexCoord;

uniform mat4 transform;

void main()
{
    gl_Position = transform * vec4(position, 1.0f);
    ourolor = color;
    TexCoord = texCoord;
}
5. 片段着色器
#version 330 core
in vec3 ourColor;
in vec2 TexCoord;

out vec4 color;

uniform sampler2D ourTexture;
uniform sampler2D ourTexture2;

void main()
{
    color = mix(texture(ourTexture, TexCoord),texture(ourTexture2,TexCoord),0.2);
    color = color*vec4(ourColor,1.0);
}

实现demo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值