1)Mesh 的构造方法
public Mesh(boolean isStatic, int maxVertices, int maxIndices, VertexAttribute... attributes)
public Mesh(boolean isStatic, int maxVertices, int maxIndices, VertexAttributes attributes)
2)VertexAttribute 的构造方法
public VertexAttribute(int usage, int numComponents, String alias)
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)Mesh 的 render 方法
public void render(ShaderProgram shader, int primitiveType)
public void render(ShaderProgram shader, int primitiveType, int offset, int count)
2)图元类型(primitiveType)
对于线段类型图元,输入顶点序列 abcdef,根据图元类型,组装成的线段如下:
对于三角形类型图元,输入顶点序列 abcdef,根据图元类型,组装成的三角形如下:
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;
}
DesktopLauncher.java
package com.zhyan8.game;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
import com.zhyan8.game.Plane;
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】目录下面。
运行效果如下。
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;
}
运行效果如下。
本节通过引入相机,使得绘制后的三角形宽高比与三角形模型的宽高比一致。
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。