OpenGLES:绘制一个颜色渐变、旋转的3D立方体

news/2024/7/21 6:00:39 标签: 3d, 图像处理, 着色器, 计算机视觉, 算法, android

一.概述

之前关于OpenGLES实战开发的博文,不论是实现相机滤镜还是绘制图形,都是在2D纬度

这篇博文开始,将会使用OpenGLES进入3D世界

本篇博文会实现一个颜色渐变、旋转的3D立方体

动态3D图形的绘制,需要具备一些基础的线性代数(向量、矩阵)空间坐标系转换相关知识,这里就不再做理论科普,需要自己先行学习,具体可以参考OpenGL官网的如下三章,讲解得十分详细:

  1. 《变换》
  2. 《坐标系统》
  3. 《摄像机》

二.Render

2.1 定义顶点、颜色、索引数组和缓冲

本次立方体的绘制,先定义顶点、颜色和索引数组,然后通过直接绘制索引缓冲来绘制立方体

三个数组及缓冲定义如下:

    private FloatBuffer vertexBuffer;
    private FloatBuffer colorBuffer;
    private ShortBuffer indexBuffer;

    private float vertexData[] = {
            -1.0f, 1.0f, 1.0f,    //正面左上0
            -1.0f, -1.0f, 1.0f,   //正面左下1
            1.0f, -1.0f, 1.0f,    //正面右下2
            1.0f, 1.0f, 1.0f,     //正面右上3
            -1.0f, 1.0f, -1.0f,   //反面左上4
            -1.0f, -1.0f, -1.0f,  //反面左下5
            1.0f, -1.0f, -1.0f,   //反面右下6
            1.0f, 1.0f, -1.0f,    //反面右上7
    };

    //八个顶点的颜色,与顶点坐标一一对应
    private float colorData[] = {
            1.0f, 1.0f, 0.0f,  // v0 Yellow
            1.0f, 0.0f, 1.0f,  // v1 Magenta 粉红
            1.0f, 0.0f, 0.0f,  // v2 Red
            1.0f, 1.0f, 1.0f,  // v3 White
            0.0f, 0.0f, 1.0f,  // v4 Blue
            0.0f, 1.0f, 1.0f,  // v5 Cyan 蓝绿
            0.0f, 1.0f, 0.0f,  // v6 Green
            0.0f, 0.0f, 0.0f,   // v7 Black
    };

    private short indexData[] = {
            6, 7, 4, 6, 4, 5,    //后面
            6, 3, 7, 6, 2, 3,    //右面
            6, 5, 1, 6, 1, 2,    //下面
            0, 3, 2, 0, 2, 1,    //正面
            0, 1, 5, 0, 5, 4,    //左面
            0, 7, 3, 0, 4, 7,    //上面
    };

2.2 定义MVP矩阵

    //MVP矩阵
    private float[] mMVPMatrix = new float[16];

三.着色器

3.1 着色器创建、链接、使用

3.2 着色器属性获取、赋值

3.3 三个缓冲内存分配

这几个部分的代码实现与上一篇2D圆绘制基本一致

可以参考上一篇博文:《OpenGLES:绘制一个颜色渐变的圆》

不再重复展示代码

3.4 着色器代码

着色器代码与上一篇2D圆绘制其实也是相同的

再展示一遍以示关键点

如下:

(1).cube_vertex_shader.glsl

#version 300 es

layout (location = 0) in vec4 vPosition;
layout (location = 1) in vec4 aColor;

uniform mat4 mvpMatrix;

out vec4 vColor;

void main() {
    gl_Position = mvpMatrix * vPosition;
    vColor = aColor;
}

(2).cube_fragtment_shader.glsl

#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;

in vec4 vColor;

out vec4 outColor;

void main(){
    outColor = vColor;
}

四.绘制

绘制流程与之前2D的基本一致,有两点不太一样要注意

4.1 MVP矩阵

mMVPMatrix = TransformUtils.getCubeMVPMatrix(ratio);
//计算MVP变换矩阵
public static float[] getCubeMVPMatrix(float ratio) {
	//初始化modelMatrix, viewMatrix, projectionMatrix
	float[] modelMatrix = getIdentityMatrix(16, 0); //模型变换矩阵
	float[] viewMatrix = getIdentityMatrix(16, 0); //观测变换矩阵/相机矩阵
	float[] projectionMatrix = getIdentityMatrix(16, 0); //投影变换矩阵

	//获取modelMatrix, viewMatrix, projectionMatrix
	mCubeRotateAgree = (mCubeRotateAgree + 1) % 360;
	Matrix.rotateM(modelMatrix, 0, mCubeRotateAgree, -1, -1, 1); //获取模型旋转变换矩阵
	Matrix.setLookAtM(viewMatrix, 0, 0, 5, 10, 0, 0, 0, 0, 1, 0); //获取观测变换矩阵,设置相机位置
	Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1, 1, 3, 20); //获取透视投影变换矩阵,正交投影:Matrix.orthoM(...)

	//计算MVP变换矩阵: mvpMatrix = projectionMatrix * viewMatrix * modelMatrix
	float[] tempMatrix = new float[16];
	float[] mvpMatrix = new float[16];
	Matrix.multiplyMM(tempMatrix, 0, viewMatrix, 0, modelMatrix, 0);
	Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, tempMatrix, 0);

	return mvpMatrix;
}

4.2 绘制索引缓冲

//索引法绘制正方体
glDrawElements(GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, indexBuffer);

五.效果展示

 


http://www.niftyadmin.cn/n/5063837.html

相关文章

【Python编程练习】字符串操作

题目描述 1、编写程序,给出一个英文句子,统计单词个数。(不考虑句子中有标点的情况) 参考答案 s input("输入一串字符串:") x s.count(" ") print("单词个数:{}".forma…

python二次开发CATIA:新建Part文档

在使用 Application 对象前,需要通过连接他的COM 接口的方式进行初始化。Python 中连接 COM 接口,需要用到 win32com 包中的 client.Dispatch()方法。因此,我们要先安装 win32com 这个包。安装它有三种方式: 1、 直接搜索下载离线…

【LeetCode算法系列题解】第76~80题

CONTENTS LeetCode 76. 最小覆盖子串(困难)LeetCode 77. 组合(中等)LeetCode 78. 子集(中等)LeetCode 79. 单词搜索(中等) LeetCode 76. 最小覆盖子串(困难) …

基于ssm的互联网废品回收/基于web的废品资源利用系统

摘 要 本毕业设计的内容是设计并且实现一个基于SSM框架的互联网废品回收。它是在Windows下,以MYSQL为数据库开发平台,Tomcat网络信息服务作为应用服务器。互联网废品回收的功能已基本实现,主要包括用户、回收员、物品分类、回收物品、用户下单…

网络参考资料汇总(1)

将这段时间参考的各路大佬的资料加以汇总分类: (1)FFmpeg: 基于FFmpeg进行rtsp推流及拉流(详细教程) Linux 编译安装 FFmpeg 步骤(带ffplay) Jetson 环境安装(三):jetson nano配置ffmpeg和ngin…

axios配置代理ip

axios配置代理ip 对于在nodejs中使用axios作为请求库时,有需要配置代理ip的需求(比如爬虫等等) 最离谱的是,在网上搜了一圈,全是关于axios配置proxy跨域的解决办法,没有配置代理ip的方法。 const axios …

ipaguard界面概览

ipaguard界面分左右2块:左边菜单导航栏,右边的功能区 左侧菜单:按模块分成启动界面,代码模块,文件模块,重签名与测试模块 右侧主功能区会随着功能变化,但是整体分3块,顶部显示过滤区…

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石④

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石④ 第十九章 驱动程序基石④19.7 工作队列19.7.1 内核函数19.7.1.1 定义 work19.7.1.2 使用 work:schedule_work19.7.1.3 其他函数 19.7.2 编程、上机19.7.3 内部机制19.7.3.1 Linux 2.x的工作队列创建过程19.7.3…