首页 > 其他分享 >【libGDX】使用Mesh绘制三角形

【libGDX】使用Mesh绘制三角形

时间:2024-02-22 21:45:23浏览次数:27  
标签:String int com void public gdx Mesh 绘制 libGDX

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,根据图元类型,组装成的线段如下:

img

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

img

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】目录下面。

​ 运行效果如下。

img

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;
}

​ 运行效果如下。

img

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。

img

​ 声明:本文转自【libGDX】使用Mesh绘制三角形

标签:String,int,com,void,public,gdx,Mesh,绘制,libGDX
From: https://www.cnblogs.com/zhyan8/p/18024334

相关文章

  • 【libGDX】使用Mesh绘制矩形
    1前言​使用Mesh绘制三角形中介绍了绘制三角形的方法,本文将介绍绘制正方形的方法。​libGDX以点、线段、三角形为图元,没有提供绘制矩形内部的接口。要绘制矩形内部,必须通过三角形拼接而成,如下图,是通过GL_TRIANGLE_FAN模式绘制矩形。​绘制的坐标点如下,屏幕中......
  • 【libGDX】使用ShapeRenderer绘制几何图形
    1ShapeRenderer简介​ShapeRenderer是libGDX中用于绘制基本形状的工具之一。它可以绘制点、线、矩形、多边形、圆形、椭圆形、扇形、立方体、圆锥体等几何图形。这对于在游戏或图形应用程序中绘制简单的形状是很有用的。​ShapeRenderer的主要方法如下:​1)开......
  • 【libGDX】初识libGDX
    1前言​libGDX是一个开源且跨平台的Java游戏开发框架,于2010年3月11日推出0.1版本,它通过OpenGLES2.0/3.0渲染图像,支持Windows、Linux、macOS、Android、iOS、Web等平台,提供了统一的API,用户只需要写一套代码就可以在多个平台上运行,官方介绍见→Features。......
  • 【libGDX】ApplicationAdapter生命周期
    1前言​libGDX中,用户自定义的渲染窗口需要继承ApplicationAdapter类,ApplicationAdapter实现了ApplicationListener接口,但实现的方法都是空方法,方法释义如下。publicinterfaceApplicationListener{ //应用首次创建时调用一次 publicvoidcreate(); //窗口尺......
  • Unreadable-Mesh内存占用翻倍问题
    1)Unreadable-Mesh内存占用翻倍问题2)在TMP中计算书名号《》高度的问题3)Mipmap如何限定层级4)FMOD设置中关于VirtualChannelCount&RealChannelCount的参数疑问这是第374篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面地掌......
  • echarts绘制世界地图的时候显示南海诸岛的局部放大图
    ehcarts在绘制中国地图的时候,判断geo的map为china的时候会自动加上南海诸岛的局部放大图。产品想在绘制世界地图的时候也加上南海诸岛,搞了半天没搞定,请教的同事搞定了。同事在此:简书ID:昊桐_260c。解决办法就是把南海诸岛的地图数据直接放在注册的JSON里面。{     ......
  • 绘制折线图、柱状图以及将生成的图片汇总生成大图片
    绘制柱状图importmatplotlib.pyplotdef订购时间绘图():global订购时间'''每一天的,X轴24个点位;以铃音为单位,每个日期为x轴'''color_list=["red","orange","yellow","green","blue","......
  • python turtle 递归绘制树
    运行效果代码importturtleastimportrandomasrc=["pink","green","lightgreen","orange","red","purple"]defdrawStar(l):t.begin_fill()foriinrange(5):t.forward(l)......
  • Leaflet 实现自定义瓦片实现xyz信息和边框绘制到瓦片上
    Leaflet实现自定义瓦片的渲染,将一些信息和边框绘制到瓦片上。主要作用是创建一个Canvas元素作为Leaflet的瓦片,并在Canvas上绘制一些文本信息和边框。实现步骤:创建一个Canvas元素作为Leaflet的瓦片,并获取其2D绘图上下文。设置Canvas的大小为当前瓦片的大小。......
  • 使用IDL进行氚羽流监测(五)——绘制污染物扩散带等值线图
    此项部分研究内容是确定氚污染带的当前范围和预测其未来范围。文件"MonitoringWells.csv"包含了氚浓度的当前数值(T0)以及使用算法模拟的未来不同时间点的氚浓度数据。在本示例中,使用对应于2030年的污染带范围的T3列数据。使用文件"MonitoringWells.csv"和"TankTerrainData.......