【libGDX】Mesh立方体贴图(6张图)

news2024/12/24 4:05:12

1 前言

        本文通过一个立方体贴图的例子,讲解三维纹理贴图的应用,案例中使用 6 张不同的图片给立方体贴图,图片如下。

        读者如果对 libGDX 不太熟悉,请回顾以下内容。

  • 使用Mesh绘制三角形
  • 使用Mesh绘制矩形
  • 使用Mesh绘制圆形
  • 使用Mesh绘制立方体
  • Mesh纹理贴图

2 立方体贴图

        本节将使用 Mesh、ShaderProgram、Shader 实现立方体贴图,OpenGL ES 的实现见博客 → 立方体贴图(6张图)。

        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("CubeChartlet");
		new Lwjgl3Application(new CubeChartlet(), config);
	}
}

        CubeChartlet.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.PerspectiveCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;

public class CubeChartlet extends ApplicationAdapter {
	private PerspectiveCamera mCamera;
	private ShaderProgram mShaderProgram;
	private Mesh mMesh;
	private Texture[] mTextures;
	private Vector3 mRotateAxis; // 旋转轴
	private int mRotateAgree = 0; // 旋转角度
	Matrix4 mModelMatrix; // 模型变换矩阵

	@Override
	public void create() {
		initCamera();
		initShader();
		initMesh();
		initTextures();
		mRotateAxis = new Vector3(0.5f, 1f, 1f);
		mModelMatrix = new Matrix4();
	}

	@Override
	public void render() {
		Gdx.gl.glClearColor(0.455f, 0.725f, 1.0f, 1.0f);
		Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT | GL30.GL_DEPTH_BUFFER_BIT);
		Gdx.gl.glEnable(GL30.GL_DEPTH_TEST);
		mShaderProgram.bind();
		transform();
		renderCube();
	}

	@Override
	public void dispose() {
		mShaderProgram.dispose();
		mMesh.dispose();
	}

	private void renderCube() {
		for (int i = 0; i < mTextures.length; i++) { // 给每个面都贴图
			// mShaderProgram.setUniformi("u_texture", 0); // 设置纹理单元
			mTextures[i].bind(0);
			mMesh.render(mShaderProgram, GL30.GL_TRIANGLE_FAN, i * 4, 4);
		}
	}

	private void initCamera() { // 初始化相机
		mCamera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
		mCamera.near = 0.3f;
		mCamera.far = 1000f;
		mCamera.position.set(0f, 0f, 4f);
		mCamera.lookAt(0, 0, 0);
		mCamera.update();
	}

	private void initShader() { // 初始化着色器程序
		String vertex = Gdx.files.internal("shaders/square_chartlet_vertex.glsl").readString();
		String fragment = Gdx.files.internal("shaders/square_chartlet_fragment.glsl").readString();
		mShaderProgram = new ShaderProgram(vertex, fragment);
	}

	private void initMesh() { // 初始化网格
		float[] vertices = Model.vertices;
		short[] indices = Model.indices;
		VertexAttribute vertexPosition = new VertexAttribute(Usage.Position, 3, "a_position");
		VertexAttribute texCoords = new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoord0");
		mMesh = new Mesh(true, vertices.length / 5, indices.length, vertexPosition, texCoords);
		mMesh.setVertices(vertices);
		mMesh.setIndices(indices);
	}

	private void initTextures() {
		mTextures = new Texture[Model.texturePaths.length];
		for (int i = 0; i < mTextures.length; i++) {
			mTextures[i] = new Texture(Gdx.files.internal(Model.texturePaths[i]));
		}
	}

	private void transform() { // MVP矩阵变换
		mRotateAgree = (mRotateAgree + 2) % 360;
		mRotateAxis.x = mRotateAgree / 180f - 1;
		mRotateAxis.y = (float) Math.sin(mRotateAgree / 180f * Math.PI * 0.7f);
		mRotateAxis.z = (float) Math.cos(mRotateAgree / 180f * Math.PI * 0.5f);
		mModelMatrix.idt(); // 模型变换矩阵单位化
		mModelMatrix.rotate(mRotateAxis, mRotateAgree);
		Matrix4 mvpMatrix = mModelMatrix.mulLeft(mCamera.combined);
		mShaderProgram.setUniformMatrix("u_mvpTrans", mvpMatrix);
	}
}

        Model.java

package com.zhyan8.game;

public class Model {
    private static float r = 1.0f;

    public static String[] texturePaths = new String[] {
            "textures/a1.png", "textures/a2.png", "textures/a3.png",
            "textures/a4.png", "textures/a5.png", "textures/a6.png"
    };

    public static float[] vertices = new float[] {
            // 前面
            r, r, r, 0f, 0f, // 0
            -r, r, r, 1f, 0f, // 1
            -r, -r, r, 1f, 1f, // 2
            r, -r, r, 0f, 1f, // 3
            // 后面
            r, r, -r, 0f, 0f, // 4
            -r, r, -r, 1f, 0f, // 5
            -r, -r, -r, 1f, 1f, // 6
            r, -r, -r, 0f, 1f, // 7
            // 上面
            r, r, r, 0f, 0f, // 8
            r, r, -r, 1f, 0f, // 9
            -r, r, -r, 1f, 1f, // 10
            -r, r, r, 0f, 1f, // 11
            // 下面
            r, -r, r, 0f, 0f, // 12
            r, -r, -r, 1f, 0f, // 13
            -r, -r, -r, 1f, 1f, // 14
            -r, -r, r, 0f, 1f, // 15
            // 右面
            r, r, r, 0f, 0f, // 16
            r, r, -r, 1f, 0f, // 17
            r, -r, -r, 1f, 1f, // 18
            r, -r, r, 0f, 1f, // 19
            // 左面
            -r, r, r, 0f, 0f, // 20
            -r, r, -r, 1f, 0f, // 21
            -r, -r, -r, 1f, 1f, // 22
            -r, -r, r, 0f, 1f // 23
    };

    public static short[] indices = new short[] {
            0, 1, 2, 3, // 前面
            4, 5, 6, 7, // 上面
            8, 9, 10, 11, // 右面
            12, 13, 14, 15, // 后面
            16, 17, 18, 19, // 下面
            20, 21, 22, 23 // 左面
    };
}

        square_chartlet_vertex.glsl

#version 300 es

in vec3 a_position;
in vec2 a_texCoord0;

uniform mat4 u_mvpTrans; // MVP矩阵变换

out vec2 v_texCoord0;

void main() {
    gl_Position = u_mvpTrans * vec4(a_position, 1.0);
    v_texCoord0 = a_texCoord0;
}

        square_chartlet_fragment.glsl

#version 300 es
precision mediump float; // 声明float型变量的精度为mediump

in vec2 v_texCoord0;

uniform sampler2D u_texture;

out vec4 fragColor;

void main() {
    fragColor = texture(u_texture, v_texCoord0);
}

        运行效果如下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1251657.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

台球厅计时软件收费怎么设置时间,佳易王桌球计时计费灯控系统

台球厅计时软件收费怎么设置时间&#xff0c;佳易王桌球计时计费灯控系统 软件可以连接配套的灯控设备&#xff0c;点击计时开灯&#xff0c;则灯打开&#xff0c;结账后关灯。 一、佳易王桌球棋牌计时计费软件部分功能简介&#xff1a; 1、计时计费功能 &#xff1a;开台时间…

基于STM32的电子钟万年历LCD1602显示设计

STM32电子钟万年历时钟闹钟 &#x1f6a9;基本功能&#xff1a;&#x1f6a9;仿真图&#xff1a;&#x1f6a9;原理图&#xff1a;PCB&#xff1a;&#x1f6a9;程序&#xff1a;&#x1f6a9;资料清单&&下载链接&#xff1a;&#x1f6a9;[资料文件下载链接](https://…

英文文献阅读工具和经验分享

在搞学术的时候需要阅读大量的英文论文或者是英文原著&#xff0c;我也一直在摸索如何方便高效的阅读。本篇仅为个人经验之谈&#xff0c;大家还是要找到合适自己的方式。 方法一&#xff1a;deepLGoodNotes 优点&#xff1a; 可以各种划线标注、手写笔记&#xff0c;加入图片…

某瓜数据app Sign

文章目录 声明目标加密参数定位算法还原声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请私信我立即删除! 目标 之前也有写过pc端的飞瓜数据解密:JS逆向系列之某瓜数据解密 这次看一下某瓜数据app的达…

印刷基板开孔机上的直线导轨怎么安装?

直线导轨是属于高精度的传动元件&#xff0c;作为印刷基板开孔机重要的传动元件&#xff0c;倘若安装不当&#xff0c;严重则无法正常作业&#xff0c;轻则影响直线导轨的精度和寿命。那么&#xff0c;印刷基板开孔机的直线导轨是如何安装的呢&#xff1f; 在安装前&#xff0c…

2024年天津天狮学院专升本计算机科学与技术《数据结构》考试大纲

2024年天津天狮学院计算机科学与技术专业高职升本入学考试《数据结构》考试大纲 一、考试性质 《数据结构》专业课程考试是天津天狮学院计算机科学与技术专业高职升本入学考 试的必考科目之一&#xff0c;其性质是考核学生是否达到了升入本科继续学习的要求而进行的选拔性考试…

Javascript每天一道算法题(十八)——矩阵置零-中等

文章目录 1、问题2、示例3、解决方法&#xff08;1&#xff09;方法1——标记数组 1、问题 给定一个 y x x 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 2、示例 示例 1&#xff1a; 输入&#xff1a;matrix [[…

googleplay应用提审

前置内容&#xff1a; 如果你的googleplay后台不是中文的&#xff0c;去你的google账号里设置一下&#xff1a; 如何修改谷歌账号的默认语言&#xff1f; https://baijiahao.baidu.com/s?id1758765859536278761&wfrspider&forpc 很多网友在登录到谷歌账户后&#x…

【程序员的自我修养01】编译流程概述

绪论 大家好&#xff0c;欢迎来到【程序员的自我修养】专栏。正如其专栏名&#xff0c;本专栏主要分享学习《程序员的自我修养——链接、装载与库》的知识点以及结合自己的工作经验以及思考。编译原理相关知识本身就比较有难度&#xff0c;我会尽自己最大的努力&#xff0c;争取…

抖音生态融合:开发与抖音平台对接的票务小程序

为了更好地服务用户需求&#xff0c;将票务服务与抖音平台结合&#xff0c;成为了一个创新的方向。通过开发票务小程序&#xff0c;用户可以在抖音平台上直接获取相关活动的票务信息&#xff0c;完成购票、预订等操作&#xff0c;实现了线上线下的有机连接。 一、开发过程 1…

平衡树 - splay

相比于之前的普通平衡树进行左旋右旋来比&#xff0c;splay的适用性更高&#xff0c;使用更广泛。 核心函数rotate、splay函数&#xff0c;其它的根据需要进行修改。 int n, m; struct Node {int s[2], p, v, cnt; // 左右儿子、父节点、值、出现数量int size, flag; // 子树大…

Another app is currently holding the yum lock; waiting for it to exit...

今天使用yum进行下载的时候报错 解决办法&#xff1a; 执行 rm -f /var/run/yum.pid 然后重新运行yum指令即可&#xff0c;发现已经可以正常下载啦&#xff01;

死磕Nacos系列:Nacos事件发布订阅模型

前言 在Nacos源码中&#xff0c;你是否也经常看到NotifyCenter.publishEvent这样的代码块&#xff1f; 这个事件发布出去后&#xff0c;有哪些类接收到通知并进行了逻辑处理呢&#xff1f; 这里面的实现逻辑是什么呢&#xff1f; 如果你不太清楚&#xff0c;那我们一起来梳理…

企业计算机中了locked勒索病毒怎么解锁,locked勒索病毒解密,数据恢复

科技的进步为企业的生产生活提供了极大便利&#xff0c;但随之而来的网络安全威胁也不断增加&#xff0c;近期云天数据恢复中心陆续接到很多企业的求助&#xff0c;企业的计算机服务器遭到了locked勒索病毒攻击&#xff0c;导致企业的所有业务无法正常开展&#xff0c;所有计算…

Python武器库开发-前端篇之CSS盒模型(三十一)

前端篇之CSS盒模型(三十一) CSS盒模型是指网页中的每个元素可以看做是一个矩形盒子&#xff0c;该盒子有四个主要部分组成&#xff1a;content、padding、border和margin。其中&#xff1a; content&#xff1a;指盒子中的内容区域&#xff0c;可以包含文本、图像、视频、其他…

安装最新版WebStorm来开发JavaScript应用程序

安装最新版WebStorm来开发JavaScript应用程序 Install the Latest Version of JetBrains WebStorm to Develop JavaScript Applications By JacksonML 2023-11-25 1. 系统要求 WebStorm是个跨平台集成开发环境&#xff08;IDE&#xff09;。按照JetBrains官网对WebStorm软件…

Elasticsearch集群部署,配置head监控插件

Elasticsearch是一个开源搜索引擎&#xff0c;基于Lucene搜索库构建&#xff0c;被广泛应用于全文搜索、地理位置搜索、日志处理、商业分析等领域。它采用分布式架构&#xff0c;可以处理大规模数据集和支持高并发访问。Elasticsearch提供了一个简单而强大的API&#xff0c;可以…

【JavaEE初阶】线程安全问题及解决方法

目录 一、多线程带来的风险-线程安全 1、观察线程不安全 2、线程安全的概念 3、线程不安全的原因 4、解决之前的线程不安全问题 5、synchronized 关键字 - 监视器锁 monitor lock 5.1 synchronized 的特性 5.2 synchronized 使用示例 5.3 Java 标准库中的线程安全类…

修改YOLOv5的模型结构第三弹

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制&#x1f680; 文章来源&#xff1a;K同学的学习圈子 文章目录 任务任务拆解 开始修改C2模块修改yolo.py修改模型配置文件 模型训练 上次已…

rfc4301- IP 安全架构

1. 引言 1.1. 文档内容摘要 本文档规定了符合IPsec标准的系统的基本架构。它描述了如何为IP层的流量提供一组安全服务&#xff0c;同时适用于IPv4 [Pos81a] 和 IPv6 [DH98] 环境。本文档描述了实现IPsec的系统的要求&#xff0c;这些系统的基本元素以及如何将这些元素结合起来…