【libGDX】使用Mesh绘制三角形
1 Mesh 和 ShaderProgram 简介
1.1 创建 Mesh
1)Mesh 的构造方法
public Mesh(boolean isStatic, int maxVertices, int maxIndices, VertexAttribute... attributes)
public Mesh(boolean isStatic, int maxVertices, int maxIndices, VertexAttributes attributes)
- isStatic:网格是否是静态的,如果网格数据不经常改动,设置为静态的可以优化性能;
- maxVertices:顶点最大个数;
- maxIndices:三角形顶点索引最大个数;
- attributes:顶点属性,主要包含:位置、颜色、法线、纹理坐标等。
2)VertexAttribute 的构造方法
public VertexAttribute(int usage, int numComponents, String alias)
- usage:顶点属性编号;
- numComponents:该属性的维度;
- alias:属性别名,在 Shader 中会用到该别名,建议以 “a_” 开头,如:a_position。
3)网格创建实例
private void initMesh() { // 初始化网格
float[] vertices = {...}; // 顶点序列
short[] indices = {...}; // 三角形顶点索引
VertexAttribute vertexAttr = new VertexAttribute(Usage.Position, 3, "a_position");
mMesh = new Mesh(true, vertices.length / 3, indices.length, vertexAttr);
mMesh.setVertices(vertices);
mMesh.setIndices(indices);
}
1.2 绘制 Mesh
1)Mesh 的 render 方法
public void render(ShaderProgram shader, int primitiveType)
public void render(ShaderProgram shader, int primitiveType, int offset, int count)
- shader:着色器程序;
- primitiveType:图元类型,即:点(GL_POINTS)、线(GL_LINES、GL_LINE_LOOP、GL_LINE_STRIP)、面(GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN);
- offset:顶点数据偏移,通常取 0.
- count:顶点个数。
2)图元类型(primitiveType)
对于线段类型图元,输入顶点序列 abcdef,根据图元类型,组装成的线段如下:

对于三角形类型图元,输入顶点序列 abcdef,根据图元类型,组装成的三角形如下:

1.3 ShaderProgram 简介
1)绑定和释放着色器程序
// 开始渲染(已过时, 内部直接调用bind, 因此可以使用bind方法替换begin方法)
public void begin()
// 绑定着色器程序, 内部调用: gl.glUseProgram(program)
public void bind()
// 结束渲染(已过时, 内部是空实现, 因此可以不调用end方法)
public void end()
// 释放资源
public void dispose()
2)设置着色器程序参数
// 设置整型Uniform变量
public void setUniformi(String name, int value)
// 设置二维整型Uniform向量
public void setUniformi(String name, int value1, int value2)
// 设置三维整型Uniform向量
public void setUniformi(String name, int value1, int value2, int value3)
// 设置四维整型Uniform向量
public void setUniformi(String name, int value1, int value2, int value3, int value4)
// 设置浮点型Uniform变量
public void setUniformf(String name, float value)
public void setUniform1fv(String name, float[] values, int offset, int length)
// 设置vec2型Uniform变量
public void setUniform2fv(String name, float[] values, int offset, int length)
public void setUniformf(String name, float value1, float value2)
public void setUniformf(String name, Vector2 values)
// 设置vec3型Uniform变量
public void setUniform3fv(String name, float[] values, int offset, int length)
public void setUniformf(String name, float value1, float value2, float value3)
public void setUniformf(String name, Vector3 values)
// 设置vec4型Uniform变量
public void setUniform4fv(String name, float[] values, int offset, int length)
public void setUniformf(String name, float value1, float value2, float value3, float value4)
public void setUniformf(String name, Color values)
// 设置三维Uniform矩阵
public void setUniformMatrix(String name, Matrix3 matrix)
// 设置四维Uniform矩阵
public void setUniformMatrix(String name, Matrix4 matrix)
说明:name 可以使用 int 型的 location 变量替换,在 VertexAttributes.Usage 中有定义,如下。
public static final class Usage {
public static final int Position = 1;
public static final int ColorUnpacked = 2;
public static final int ColorPacked = 4;
public static final int Normal = 8;
public static final int TextureCoordinates = 16;
public static final int Generic = 32;
public static final int BoneWeight = 64;
public static final int Tangent = 128;
public static final int BiNormal = 256;
}
2 绘制三角形
本节将使用 Mesh、ShaderProgram、Shader 绘制三角形,OpenGL ES 的实现见博客 → 绘制三角形、绘制彩色三角形,本节完整代码资源见 → 使用Mesh绘制三角形。
2.1 绘制纯色三角形
DesktopLauncher.java
package com.zhyan8.game;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
public class DesktopLauncher {
public static void main (String[] arg) {
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
config.setForegroundFPS(60);
config.setTitle("Triangle");
new Lwjgl3Application(new Triangle(), config);
}
}
Triangle.java
package com.zhyan8.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL30;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
public class Triangle extends ApplicationAdapter {
private ShaderProgram mShaderProgram;
private Mesh mMesh;
@Override
public void create() {
initShader();
initMesh();
}
@Override
public void render() {
Gdx.gl.glClearColor(0.455f, 0.725f, 1.0f, 1.0f);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
// mShaderProgram.begin(); // 已过时, 请使用bind方法替换
mShaderProgram.bind();
mMesh.render(mShaderProgram, GL30.GL_TRIANGLES);
// mShaderProgram.end(); // 已过时, 可以去掉
}
@Override
public void dispose() {
mShaderProgram.dispose();
mMesh.dispose();
}
private void initShader() { // 初始化着色器程序
String vertex = Gdx.files.internal("shaders/triangle_vertex.glsl").readString();
String fragment = Gdx.files.internal("shaders/triangle_fragment.glsl").readString();
mShaderProgram = new ShaderProgram(vertex, fragment);
}
private void initMesh() { // 初始化网格
float[] vertices = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
short[] indices = {0, 1, 2};
VertexAttribute vertexAttr = new VertexAttribute(Usage.Position, 3, "a_position");
mMesh = new Mesh(true, vertices.length / 3, indices.length, vertexAttr);
mMesh.setVertices(vertices);
mMesh.setIndices(indices);
}
}
triangle_vertex.glsl
#version 300 es
in vec3 a_position;
void main() {
gl_Position = vec4(a_position, 1.0);
}
说明:triangle_vertex.glsl 文件放在【assets / shaders】目录下面。
triangle_fragment.glsl
#version 300 es
precision mediump float; // 声明float型变量的精度为mediump
out vec4 fragColor;
void main() {
fragColor = vec4(1, 0, 0, 1);
}
说明:triangle_fragment.glsl 文件放在【assets / shaders】目录下面。
运行效果如下。

2.2 绘制彩色三角形
Triangle.java
package com.zhyan8.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL30;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
public class Triangle extends ApplicationAdapter {
private ShaderProgram mShaderProgram;
private Mesh mMesh;
@Override
public void create() {
initShader();
initMesh();
}
@Override
public void render() {
Gdx.gl.glClearColor(0.455f, 0.725f, 1.0f, 1.0f);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
// mShaderProgram.begin(); // 已过时, 请使用bind方法替换
mShaderProgram.bind();
mMesh.render(mShaderProgram, GL30.GL_TRIANGLES);
// mShaderProgram.end(); // 已过时, 可以去掉
}
@Override
public void dispose() {
mShaderProgram.dispose();
mMesh.dispose();
}
private void initShader() { // 初始化着色器程序
String vertex = Gdx.files.internal("shaders/triangle_vertex.glsl").readString();
String fragment = Gdx.files.internal("shaders/triangle_fragment.glsl").readString();
mShaderProgram = new ShaderProgram(vertex, fragment);
}
private void initMesh() { // 初始化网格
float[] vertices = {
// 前3位是顶点位置数据, 后4位是顶点颜色数据
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f
};
short[] indices = {0, 1, 2};
VertexAttribute vertexPosition = new VertexAttribute(Usage.Position, 3, "a_position");
VertexAttribute vertexColor = new VertexAttribute(Usage.ColorUnpacked, 4, "a_color");
mMesh = new Mesh(true, vertices.length / 7, indices.length, vertexPosition, vertexColor);
mMesh.setVertices(vertices);
mMesh.setIndices(indices);
}
}
triangle_vertex.glsl
#version 300 es
in vec3 a_position;
in vec4 a_color;
out vec4 v_color;
void main() {
gl_Position = vec4(a_position, 1.0);
v_color = a_color;
}
triangle_fragment.glsl
#version 300 es
precision mediump float; // 声明float型变量的精度为mediump
in vec4 v_color;
out vec4 fragColor;
void main() {
fragColor = v_color;
}
运行效果如下。

2.3 三角形宽高比适配
本节通过引入相机,使得绘制后的三角形宽高比与三角形模型的宽高比一致。
Triangle.java
package com.zhyan8.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL30;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
public class Triangle extends ApplicationAdapter {
private OrthographicCamera mCamera;
private ShaderProgram mShaderProgram;
private Mesh mMesh;
@Override
public void create() {
initCamera();
initShader();
initMesh();
}
@Override
public void render() {
Gdx.gl.glClearColor(0.455f, 0.725f, 1.0f, 1.0f);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
// mShaderProgram.begin(); // 已过时, 请使用bind方法替换
mShaderProgram.bind();
mShaderProgram.setUniformMatrix("u_projectionViewMatrix", mCamera.combined);
mMesh.render(mShaderProgram, GL30.GL_TRIANGLES);
// mShaderProgram.end(); // 已过时, 可以去掉
}
@Override
public void dispose() {
mShaderProgram.dispose();
mMesh.dispose();
}
private void initCamera() {
mCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
mCamera.near = 0.3f;
mCamera.far = 1000f;
mCamera.zoom = 0.005f; // 相机缩放级别, 值越大观察范围越大, 看到的图形越小
mCamera.position.set(0f, 0f, -5f);
mCamera.lookAt(0, 0, 0);
mCamera.update();
}
private void initShader() { // 初始化着色器程序
String vertex = Gdx.files.internal("shaders/triangle_vertex.glsl").readString();
String fragment = Gdx.files.internal("shaders/triangle_fragment.glsl").readString();
mShaderProgram = new ShaderProgram(vertex, fragment);
}
private void initMesh() { // 初始化网格
float[] vertices = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
};
short[] indices = {0, 1, 2};
VertexAttribute vertexPosition = new VertexAttribute(Usage.Position, 3, "a_position");
mMesh = new Mesh(true, vertices.length / 3, indices.length, vertexPosition);
mMesh.setVertices(vertices);
mMesh.setIndices(indices);
}
}
说明:这里设置的三角形底边和高都为 1,即宽高比为 1: 1,我们期望绘制后的三角形宽高比也是 1 : 1,这时就需要通过相机进行变换。
triangle_vertex.glsl
#version 300 es
in vec3 a_position;
uniform mat4 u_projectionViewMatrix;
void main() {
gl_Position = u_projectionViewMatrix * vec4(a_position, 1.0);
}
说明:这里通过正交相机的观察矩阵和投影矩阵变换,实现模型宽高比的适配,也可以对输入坐标的 y 值乘以屏幕宽高比,作为 gl_Position.y 的值。
triangle_fragment.glsl
#version 300 es
precision mediump float; // 声明float型变量的精度为mediump
out vec4 fragColor;
void main() {
fragColor = vec4(0, 1, 0, 0);
}
运行效果如下,可以看到,绘制后的三角形宽高比也是 1 : 1。

声明:本文转自【libGDX】使用Mesh绘制三角形。
【libGDX】使用Mesh绘制三角形的更多相关文章
- [Unity]利用Mesh绘制简单的可被遮挡,可以探测的攻击指示器
最近做一个小游戏的Demo,最终的效果是这样的 主要是利用Mesh绘制三角形作为显示,然后使用后处理来制作探灯,注意,性能一般,仅仅适合小游戏 分为3步 1:利用mesh绘制三角形,原理很简单,利用三 ...
- Unity3D之Mesh(一)绘制三角形
前言: Unity自带几种简单的模型,如cube等:一般情况下,其余模型有3D建模软件生成,以合适的文件格式导入unity中:而mesh(以我目前很粗浅的了解)的一般用途就是:对现有的模型进行变形,以 ...
- unity 绘制三角形
哎 该学的还是要学 参考:http://www.narkii.com/club/thread-369573-1.html unity 顶点绘制三角形 脚本绘制; 其实filter和render就是进行 ...
- 纯CCS绘制三角形箭头图案
用CSS绘制三角形箭头.使用纯CSS,你只需要很少的代码就可以创作出各种浏览器都兼容的三角形箭头! CSS代码: /* create an arrow that points up */ div.ar ...
- CSS 魔法系列:纯 CSS 绘制三角形(各种角度)
我们的网页因为 CSS 而呈现千变万化的风格.这一看似简单的样式语言在使用中非常灵活,只要你发挥创意就能实现很多比人想象不到的效果.特别是随着 CSS3 的广泛使用,更多新奇的 CSS 作品涌现出来. ...
- css绘制三角形原理
1.新建一个元素,将它的宽高都设置为0:然后通过设置border属性来实现三角形效果,下面是css绘制三角形的原理: <!DOCTYPE html> <html> <he ...
- 【转载】理解GL_TRIANGLE_STRIP等绘制三角形序列的三种方式
GL_TRIANGLE_STRIP绘制三角形方式很多时候令人疑惑,在这里对其运作机理进行解释. 一般情况下有三种绘制一系列三角形的方式,分别是GL_TRIANGLES.GL_TRIANGLE_STRI ...
- CSS - Tooltip-arrow 绘制三角形
问题:纯CSS实现bubble的三角形部分 方法:使用border来绘制三角形:例如 .trangle { ; border-color: transparent; border-style: sol ...
- CSS用border绘制三角形
使用border绘制三角形的思路,就是border尺寸设置一个较大的值,元素自身的宽高设置为0,全部由边线占据,这样每边就会显示为四分之一块的三角形.这样不借助图片,可以直接绘制出三角形了. 一个栗子 ...
- Android OpenGL ES(十)绘制三角形Triangle .
三角形为OpenGL ES支持的面,同样创建一个DrawTriangle Activity,定义6个顶点使用三种不同模式来绘制三角形: float vertexArray[] = { -0.8f, - ...
随机推荐
- [转帖]Oracle 如何列出正在运行的定时任务
https://geek-docs.com/oracle/oracle-questions/569_oracle_how_can_i_list_the_scheduled_jobs_running_i ...
- [转帖]【教程】如何在不同架构打包Docker镜像
https://docs.qsnctf.com/qsnctf/37674.html 前言 大家在使用Docker的时候经常会遇到一个问题,就是受用机和本级不是同一架构.就比如小编使用的就是新版本的Ma ...
- zabbix基于容器化在UOS1050E上面的安装与使用
前言 想着能够监控一下操作系统的日志. 因为国产化的需求, 所以我这边使用了UOS1050E 安装zabbix时多次提示缺少php-json 或者是缺少一些libevent等组件. 自己尝试进行解决发 ...
- CentOS确认网口是否插入网线的办法
最近公司的机器存在网络问题, 部分网络总是不通, 比较奇怪. 最近一直想处理好. 第一步: 先查看网口的设备信息 可以使用 ip link show 可以讲网口信息都展示出来. 一般情况下 NO-C ...
- 在web中,用户输入的文字过多 和页面排版一行显示不下 怎么办
在写管理系统中, 如果用户在input中,表单输入过多,应该如何去处理 常用的解决办法是: 1==>用户只能够输入一定范围内的字数 2==>超出几个字后(宽度)使用省略号显示. 3==&g ...
- 【scikit-learn基础】--『回归模型评估』之可视化评估
在scikit-learn中,回归模型的可视化评估是一个重要环节.它帮助我们理解模型的性能,分析模型的预测能力,以及检查模型是否存在潜在的问题.通过可视化评估,我们可以更直观地了解回归模型的效果,而不 ...
- Windows 堆管理机制 [2] Windows 2000 – Windows XP SP1版本
2.Windows 2000 – Windows XP SP1 2.1 环境准备 环境 环境准备 虚拟机 32位Windows 2000 SP4 调试器 OllyDbg.WinDbg 编译器 VC6. ...
- 关于git的几点疑问
git rename后查看之前的记录 对于某个文件进行rename之后,使用show log命令查看之前的修改记录都会丢失,通过命令行方式进行mv之后,在tortoisegit中查看记录还是丢失的 g ...
- ElasticSearch安装、插件介绍及Kibana的安装与使用详解
ElasticSearch安装.插件介绍及Kibana的安装与使用详解 1.安装 ElasticSearch 1.1 安装 JDK 环境 因为 ElasticSearch 是用 Java 语言编写的, ...
- 验证码识别服务2Captcha框架
2Captcha是一个自动验证码识别服务,主要用于解决各种互联网服务中的验证码问题.在许多网站注册账户或进行敏感操作时,为了验证用户是真实的而不是自动化程序,会出现验证码.用户必须正确输入验证码,才能 ...