当前位置: 首页 > news >正文

opengl从画三角形到画一个立方体(五)

前面的章节中,讲到了如何画一个立方体,本节的内容是画多个立方体,并让其旋转起来,不旋转,很难看到立体的效果。
首先,如何画多个立方体,我们知道MVP矩阵的作用,然后我们只要对local的坐标进行平移,旋转操作就可以画多个立方体了。

glm::vec3 cubePosition[] = {
        glm::vec3(0.0f, 0.0f, 0.0f),
        glm::vec3(0.01f, 0.0f, 0.0f),
        glm::vec3(0.0f, 0.01f, 0.0f),
        glm::vec3(-0.01f, 0.0f, 0.0f),
    };

然后就是将矩阵作用到顶点上去,一个立方体的12个三角形(每个面两个三角形,6个面,共计12个三角形,36个顶点)的顶点数据为:

float vertices[] = {
        -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
        0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
        0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,

        -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
        0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
        -0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
        -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,

        -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
        -0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
        -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
        -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,

        0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
        0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
        0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
        0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 0.0f,

        -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
        0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
        0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
        0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
        -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,

        -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
        0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
        -0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
        -0.5f, 0.5f, -0.5f, 0.0f, 1.0f
    };

然后需要在主循环中,用单位矩阵做位移操作,即:

glm::mat4 model;
model = glm::translate(model, cubePosition[i]);

这里就得到平移的矩阵。

然后就是V矩阵和P矩阵的定义:

glm::mat4 view;
glm::mat4 projection;
projection = glm::perspective(glm::radians(45.0f), (float)800 / (float)600, 0.1f, 100.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));

这个两个矩阵的定义,我们之后再做讲解,最后就是改写vertex shader的内容,让其接收程序中的数据。

const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec2 inTexcoord;\n"
"out vec2 outTexcoord;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{\n"
"   gl_Position = projection * view * model * vec4(aPos/200.0,1.0);\n"
"   outTexcoord = vec2(inTexcoord.x, inTexcoord.y);\n"
"}\0";

下面给出整体的代码:

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

using namespace std;

const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec2 inTexcoord;\n"
"out vec2 outTexcoord;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{\n"
"   gl_Position = projection * view * model * vec4(aPos/200.0,1.0);\n"
"   outTexcoord = vec2(inTexcoord.x, inTexcoord.y);\n"
"}\0";

const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"in vec2 outTexcoord;\n"
"uniform sampler2D texture1;\n"
"void main()\n"
"{\n"
"   FragColor = texture(texture1, outTexcoord);\n"
"}\n\0";


int main()
{
    //初始化和创建窗口
    glfwInit();
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);

    //设置
    glfwMakeContextCurrent(window);
    gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);


    //三角形的三个顶点数据
    float vertices[] = {
        -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
        0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
        0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,

        -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
        0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
        -0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
        -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,

        -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
        -0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
        -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
        -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,

        0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
        0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
        0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
        0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 0.0f,

        -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
        0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
        0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
        0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
        -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,

        -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
        0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
        -0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
        -0.5f, 0.5f, -0.5f, 0.0f, 1.0f
    };

    glm::vec3 cubePosition[] = {
        glm::vec3(0.0f, 0.0f, 0.0f),
        glm::vec3(0.01f, 0.0f, 0.0f),
        glm::vec3(0.0f, 0.01f, 0.0f),
        glm::vec3(-0.01f, 0.0f, 0.0f),
    };

    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);

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

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

    int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);


    unsigned int texture1;
    glGenTextures(1, &texture1);
    glBindTexture(GL_TEXTURE_2D, texture1);

    stbi_set_flip_vertically_on_load(true);
    int width, height, nrChannels;
    unsigned char *data = stbi_load("timg.jpg", &width, &height, &nrChannels, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else
    {
        std::cout << "Failed to load texture" << std::endl;
    }
    glUseProgram(shaderProgram);
    glUniform1i(glGetUniformLocation(shaderProgram, "texture1"), 0);
    glEnable(GL_DEPTH_TEST);

    while (!glfwWindowShouldClose(window))
    {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture1);
        glUseProgram(shaderProgram);

        glm::mat4 view;
        glm::mat4 projection;
        projection = glm::perspective(glm::radians(45.0f), (float)800 / (float)600, 0.1f, 100.0f);
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));

        unsigned int transformLoc1 = glGetUniformLocation(shaderProgram, "projection");
        glUniformMatrix4fv(transformLoc1, 1, GL_FALSE, glm::value_ptr(projection));

        unsigned int transformLoc2 = glGetUniformLocation(shaderProgram, "view");
        glUniformMatrix4fv(transformLoc2, 1, GL_FALSE, glm::value_ptr(view));

        glBindVertexArray(VAO);

        for (int i = 0; i < 4; ++i)
        {
            glm::mat4 model;
            model = glm::translate(model, cubePosition[i]);
            model = glm::rotate(model, 20*(float)glfwGetTime()*glm::radians(50.0f), glm::vec3(1.0f, 0.3f, 0.5f));
            unsigned int transformLoc3 = glGetUniformLocation(shaderProgram, "model");
            glUniformMatrix4fv(transformLoc3, 1, GL_FALSE, glm::value_ptr(model));
            glDrawArrays(GL_TRIANGLES, 0, 36);
        }

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    return 0;
}

运行的结果为:
这里写图片描述

接下来,我们似乎失去了学习的方向,我们不在去写一个相机了,而是迫不及待的学习光照以及shader相关的知识,所以画一个立方体的知识,暂时告一段落,接下来学习光照知识,敬请期待。。。。

相关文章:

  • ZYNQ. GPIO
  • bzoj 3027 [Ceoi2004]Sweet——生成函数
  • 将光源信息应用到立方体(一)
  • unity包内的内容读取
  • 栈和局部变量操作 将常量压入栈的指令
  • 将光源信息应用到立方体(二)
  • c++总结
  • DNS劫持
  • reflect vector
  • 113007
  • parallax mapping
  • 京东JData算法大赛高潜用户购买意向预测——复现(并没有),提供数据集
  • java 规范
  • 判定你的java应用是否正常(是否内存、线程泄漏)的一个简单方法
  • Java集合(本篇主要介绍List接口)
  • 【Leetcode】101. 对称二叉树
  • Java到底能干嘛?
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • 编写符合Python风格的对象
  • 从0到1:PostCSS 插件开发最佳实践
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 简单易用的leetcode开发测试工具(npm)
  • 排序算法之--选择排序
  • 手写一个CommonJS打包工具(一)
  • 一起参Ember.js讨论、问答社区。
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • mysql面试题分组并合并列
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • #stm32整理(一)flash读写
  • $.ajax()
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (搬运以学习)flask 上下文的实现
  • (二)springcloud实战之config配置中心
  • (四)汇编语言——简单程序
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (转)人的集合论——移山之道
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • @transaction 提交事务_【读源码】剖析TCCTransaction事务提交实现细节
  • [04]Web前端进阶—JS伪数组
  • [Android View] 可绘制形状 (Shape Xml)
  • [C#]手把手教你打造Socket的TCP通讯连接(一)
  • [C/C++] -- 二叉树
  • [ChromeApp]指南!让你的谷歌浏览器好用十倍!
  • [Gamma]阶段测试报告
  • [ios] IOS文件操作的两种方式:NSFileManager操作和流操作【转】
  • [java进阶]——方法引用改写Lambda表达式
  • [LeetCode][面试算法]逻辑闭环的二分查找代码思路
  • [lintcode easy]Maximum Subarray
  • [MZ test.16]P1 评测