shsshs 2019-12-27
学习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); }