4

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

 6 months ago
source link: https://www.cnblogs.com/zhyan8/p/18024339
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

img

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

2 立方体贴图

​ 本节将使用 Mesh、ShaderProgram、Shader 实现立方体贴图,OpenGL ES 的实现见博客 → 立方体贴图(6张图),本节完整代码资源见 → libGDX Mesh立方体贴图(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);
}

​ 运行效果如下。

img

​ 声明:本文转自【libGDX】Mesh立方体贴图(6张图)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK