OpenGLES:绘制一个混色旋转的3D立方体

效果展示

混色旋转的3D立方体

一.概述

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

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

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

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

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

二.GLRender:变量定义

2.1 常规变量定义

//shader程序/渲染器
private int shaderProgram;

private int vPosition;
private int aColor;
private int mvpMatrix;

//suface宽高比
private float ratio;

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

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

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

java 复制代码
    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.3 定义MVP矩阵

java 复制代码
    //MVP矩阵
    private float[] mMVPMatrix = new float[16];

三.GLRender:着色器、内存分配等

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

3.2 着色器属性获取、赋值

3.3 三个缓冲内存分配

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

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

不再重复展示代码

四.GLRender:绘制

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

4.1 MVP矩阵赋值

java 复制代码
//填充MVP矩阵
mMVPMatrix = TransformUtils.getCubeMVPMatrix(ratio);
//设置MVP变换矩阵到着色器程序/渲染器
glUniformMatrix4fv(mvpMatrix, 1, false, mMVPMatrix, 0);
java 复制代码
//计算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 绘制索引缓冲

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

五.着色器代码

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

再展示一遍以示关键点

如下:

(1).cube_vertex_shader.glsl

java 复制代码
#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

java 复制代码
#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;

in vec4 vColor;

out vec4 outColor;

void main(){
    outColor = vColor;
}

六.结束语

混色旋转3D立方体的实现过程到此讲解结束

最终实现效果如博文开始的效果展示

相关推荐
ChinaDragonDreamer几秒前
Kotlin:2.0.20 的新特性
android·开发语言·kotlin
春末的南方城市44 分钟前
FLUX的ID保持项目也来了! 字节开源PuLID-FLUX-v0.9.0,开启一致性风格写真新纪元!
人工智能·计算机视觉·stable diffusion·aigc·图像生成
Kalika0-01 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
sp_fyf_20242 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02
人工智能·神经网络·算法·计算机视觉·语言模型·自然语言处理·数据挖掘
网络研究院3 小时前
Android 安卓内存安全漏洞数量大幅下降的原因
android·安全·编程·安卓·内存·漏洞·技术
凉亭下3 小时前
android navigation 用法详细使用
android
我是哈哈hh3 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
Tisfy3 小时前
LeetCode 2187.完成旅途的最少时间:二分查找
算法·leetcode·二分查找·题解·二分
Mephisto.java4 小时前
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
sql·算法·leetcode
robin_suli4 小时前
滑动窗口->dd爱框框
算法