OpenGL学习——变换——绕x轴来回旋转的木板

Posted xingchong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL学习——变换——绕x轴来回旋转的木板相关的知识,希望对你有一定的参考价值。

学习OpenGL的变换。

Local Space => World Space => View Space => Clip Space => Screen Space

ModelMatrix

ViewMatrix

ProjectionMatrix   :   Orthographic   Perspective

GLM: OpenGL Mathematics

变换效果:

 

技术图片

 

 

初始化与渲染代码:

 

RectFall.h

 

 

#ifndef RectFall_h
#define RectFall_h

#include "RectBox.h"

class RectFall : public RectBox
{
public:
    RectFall();

    ~RectFall();

protected:
    virtual void init();

    virtual void draw();

private:
    GLuint _textureOne;
    GLuint _textureTwo;

};



#endif // !RectFall_h

 

 

RectFall.cpp

#include "RectFall.h"

RectFall::RectFall(){
}

RectFall::~RectFall(){
}

void RectFall::init(){
    // x,y,z  opengl coordinates, the vertex data, three 3d point in normalized device coordinates
    GLfloat vertexs[] = {
        //position            color                texture coordinates
        0.3f, -0.2f, 0.0f,    1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // right up 
        0.3f, -0.9f, 0.0f,    0.0f, 0.0f, 1.0f,   1.0f, 0.0f, // right down

        -0.3f, -0.2f, 0.0f,    0.0f, 1.0f, 0.0f,   0.0f, 1.0f, // left up
        -0.3f, -0.9f, 0.0f,    1.0f, 0.0f, 0.0f,   0.0f, 0.0f, // left down 
    };
    // vertex draw index array
    GLuint indexs[] = {
        0, 1, 2,
        1, 2, 3,
    };
    //define VAO, vertex array object
    glGenVertexArrays(1, &_VAO);
    glBindVertexArray(_VAO); // bind vertex array object
        //define VBO, vertex buffer object
        GLuint VBO;
        glGenBuffers(1, &VBO);                                                   // gen buffer object
        glBindBuffer(GL_ARRAY_BUFFER, VBO);                                      // bind buffer to the target
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertexs), vertexs, GL_STATIC_DRAW); // copy vertex data to VBO
        //define EBO, element buffer object
        GLuint EBO;
        glGenBuffers(1, &EBO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexs), indexs, GL_STATIC_DRAW);
        //set vertex attribute point
        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);
    glBindVertexArray(0);//unbind vertex array object

    //create shader program
    const GLchar* vsPath = "res/rectfall.vs";
    const GLchar* fragPath = "res/rectfall.frag";
    this->_shader = new Shader(vsPath, fragPath);

    //gen texture about
    this->genTexture(_textureOne, "res/container.jpg");
    this->genTexture(_textureTwo, "res/awesomeface.png");
}

void RectFall::draw(){
    //use shader programs
    this->_shader->useProgram();

    //set uniform value
    GLfloat curTime = glfwGetTime();                          // current time
    GLfloat uniMixRate = (cos(2 * curTime) + 1.0f) / 2.0f;
    glUniform1f(_shader->getUniformLocation("uniMixRate"), uniMixRate);

    //set uniform, the transform
    glm::float32 curRotate = glm::radians(-64.0f * curTime);
    curRotate = uniMixRate * glm::radians(360.0f);
    glm::mat4 modelMatrix(1.0f);
    modelMatrix = glm::translate(modelMatrix, glm::vec3(0.0f, -0.55f, 0.0f));
    modelMatrix = glm::rotate(modelMatrix, curRotate, glm::vec3(1.0f, 0.0f, 0.0f));
    modelMatrix = glm::translate(modelMatrix, glm::vec3(0.0f, 0.55f, 0.0f));

    glm::mat4 viewMatrix(1.0f);
    viewMatrix = glm::translate(viewMatrix, glm::vec3(0.0f, 0.0f, -2.5f));

    glm::mat4 projectionMatrix(1.0f);
    projectionMatrix = glm::perspective(glm::radians(45.0f), 16.0f/9.0f, 0.1f, 100.0f);

    glUniformMatrix4fv(_shader->getUniformLocation("modelMatrix"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
    glUniformMatrix4fv(_shader->getUniformLocation("viewMatrix"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
    glUniformMatrix4fv(_shader->getUniformLocation("projectionMatrix"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));


    //bind texture
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, _textureOne);
    glUniform1i(_shader->getUniformLocation("textureOne"), 0);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, _textureTwo);
    glUniform1i(_shader->getUniformLocation("textureTwo"), 1);

    //draw the Rectangles
    glBindVertexArray(_VAO);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // GL_LINE  GL_FILL   set the wireframe mode
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

 


加载纹理方法:

void RectBox::genTexture(GLuint &texture, const char *filename){
    std::cout << "filename = " << filename << std::endl;
    //gen texture
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    //set wrapping
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
    //set filter
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    //load image
    int width, height;
    unsigned char* image = SOIL_load_image(filename, &width, &height, 0, SOIL_LOAD_RGBA);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
    glGenerateMipmap(GL_TEXTURE_2D);
    //free image
    SOIL_free_image_data(image);
    glBindTexture(GL_TEXTURE_2D, 0);
}

 

 

 

 

着色器代码:

rectfall.vs

#version 330 core
layout (location = 0) in vec3 v_pos;
layout (location = 1) in vec3 v_color;
layout (location = 2) in vec2 v_textureCoord;

out vec4 f_vertexColor;
out vec2 f_textureCoord;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

void main () {
  gl_Position    =  projectionMatrix * viewMatrix * modelMatrix * vec4(v_pos, 1.0);
  f_vertexColor  = vec4(v_color, 1.0f);
  f_textureCoord = v_textureCoord;
}

 

rectfall.frag

#version 330 core
in vec4 f_vertexColor;
in vec2 f_textureCoord;

out vec4 color;

uniform  float uniMixRate;
uniform  sampler2D textureOne;
uniform  sampler2D textureTwo;

void main () {
  vec4 boxColor  = texture(textureOne, f_textureCoord);
  vec4 faceColor = texture(textureTwo, vec2(f_textureCoord.x, 1.0f - f_textureCoord.y));
  float mixRate = uniMixRate;
  if(mixRate > 0.3f){
    mixRate = 0.3f;
  }
  color = mix(boxColor, faceColor, mixRate);

}

以上是关于OpenGL学习——变换——绕x轴来回旋转的木板的主要内容,如果未能解决你的问题,请参考以下文章

three.js 中的矩阵变换及两种旋转表达方式

使用OpenGL如何实现物体绕体外任意轴旋转?

图形学OpenGL基本光照

three.js中的矩阵变换(模型视图投影变换)

在 OpenGL 中绘制一个绕 Y 轴旋转的 Cog

Three.jsthree.js 中的矩阵变换及两种旋转表达方式