经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
【libGDX】使用Mesh绘制三角形
来源:cnblogs  作者:little_fat_sheep  时间:2024/2/23 8:57:00  对本文有异议

1 Mesh 和 ShaderProgram 简介

1.1 创建 Mesh

? 1)Mesh 的构造方法

  1. public Mesh(boolean isStatic, int maxVertices, int maxIndices, VertexAttribute... attributes)
  2. public Mesh(boolean isStatic, int maxVertices, int maxIndices, VertexAttributes attributes)
  • isStatic:网格是否是静态的,如果网格数据不经常改动,设置为静态的可以优化性能;
  • maxVertices:顶点最大个数;
  • maxIndices:三角形顶点索引最大个数;
  • attributes:顶点属性,主要包含:位置、颜色、法线、纹理坐标等。

? 2)VertexAttribute 的构造方法

  1. public VertexAttribute(int usage, int numComponents, String alias)
  • usage:顶点属性编号;
  • numComponents:该属性的维度;
  • alias:属性别名,在 Shader 中会用到该别名,建议以 “a_” 开头,如:a_position。

? 3)网格创建实例

  1. private void initMesh() { // 初始化网格
  2. float[] vertices = {...}; // 顶点序列
  3. short[] indices = {...}; // 三角形顶点索引
  4. VertexAttribute vertexAttr = new VertexAttribute(Usage.Position, 3, "a_position");
  5. mMesh = new Mesh(true, vertices.length / 3, indices.length, vertexAttr);
  6. mMesh.setVertices(vertices);
  7. mMesh.setIndices(indices);
  8. }

1.2 绘制 Mesh

? 1)Mesh 的 render 方法

  1. public void render(ShaderProgram shader, int primitiveType)
  2. 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)绑定和释放着色器程序

  1. // 开始渲染(已过时, 内部直接调用bind, 因此可以使用bind方法替换begin方法)
  2. public void begin()
  3. // 绑定着色器程序, 内部调用: gl.glUseProgram(program)
  4. public void bind()
  5. // 结束渲染(已过时, 内部是空实现, 因此可以不调用end方法)
  6. public void end()
  7. // 释放资源
  8. public void dispose()

? 2)设置着色器程序参数

  1. // 设置整型Uniform变量
  2. public void setUniformi(String name, int value)
  3. // 设置二维整型Uniform向量
  4. public void setUniformi(String name, int value1, int value2)
  5. // 设置三维整型Uniform向量
  6. public void setUniformi(String name, int value1, int value2, int value3)
  7. // 设置四维整型Uniform向量
  8. public void setUniformi(String name, int value1, int value2, int value3, int value4)
  9. // 设置浮点型Uniform变量
  10. public void setUniformf(String name, float value)
  11. public void setUniform1fv(String name, float[] values, int offset, int length)
  12. // 设置vec2型Uniform变量
  13. public void setUniform2fv(String name, float[] values, int offset, int length)
  14. public void setUniformf(String name, float value1, float value2)
  15. public void setUniformf(String name, Vector2 values)
  16. // 设置vec3型Uniform变量
  17. public void setUniform3fv(String name, float[] values, int offset, int length)
  18. public void setUniformf(String name, float value1, float value2, float value3)
  19. public void setUniformf(String name, Vector3 values)
  20. // 设置vec4型Uniform变量
  21. public void setUniform4fv(String name, float[] values, int offset, int length)
  22. public void setUniformf(String name, float value1, float value2, float value3, float value4)
  23. public void setUniformf(String name, Color values)
  24. // 设置三维Uniform矩阵
  25. public void setUniformMatrix(String name, Matrix3 matrix)
  26. // 设置四维Uniform矩阵
  27. public void setUniformMatrix(String name, Matrix4 matrix)

? 说明:name 可以使用 int 型的 location 变量替换,在 VertexAttributes.Usage 中有定义,如下。

  1. public static final class Usage {
  2. public static final int Position = 1;
  3. public static final int ColorUnpacked = 2;
  4. public static final int ColorPacked = 4;
  5. public static final int Normal = 8;
  6. public static final int TextureCoordinates = 16;
  7. public static final int Generic = 32;
  8. public static final int BoneWeight = 64;
  9. public static final int Tangent = 128;
  10. public static final int BiNormal = 256;
  11. }

2 绘制三角形

? 本节将使用 Mesh、ShaderProgram、Shader 绘制三角形,OpenGL ES 的实现见博客 → 绘制三角形绘制彩色三角形,本节完整代码资源见 → 使用Mesh绘制三角形

2.1 绘制纯色三角形

? DesktopLauncher.java

  1. package com.zhyan8.game;
  2. import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
  3. import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
  4. public class DesktopLauncher {
  5. public static void main (String[] arg) {
  6. Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
  7. config.setForegroundFPS(60);
  8. config.setTitle("Triangle");
  9. new Lwjgl3Application(new Triangle(), config);
  10. }
  11. }

? Triangle.java

  1. package com.zhyan8.game;
  2. import com.badlogic.gdx.ApplicationAdapter;
  3. import com.badlogic.gdx.Gdx;
  4. import com.badlogic.gdx.graphics.GL30;
  5. import com.badlogic.gdx.graphics.Mesh;
  6. import com.badlogic.gdx.graphics.VertexAttribute;
  7. import com.badlogic.gdx.graphics.VertexAttributes.Usage;
  8. import com.badlogic.gdx.graphics.glutils.ShaderProgram;
  9. public class Triangle extends ApplicationAdapter {
  10. private ShaderProgram mShaderProgram;
  11. private Mesh mMesh;
  12. @Override
  13. public void create() {
  14. initShader();
  15. initMesh();
  16. }
  17. @Override
  18. public void render() {
  19. Gdx.gl.glClearColor(0.455f, 0.725f, 1.0f, 1.0f);
  20. Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
  21. // mShaderProgram.begin(); // 已过时, 请使用bind方法替换
  22. mShaderProgram.bind();
  23. mMesh.render(mShaderProgram, GL30.GL_TRIANGLES);
  24. // mShaderProgram.end(); // 已过时, 可以去掉
  25. }
  26. @Override
  27. public void dispose() {
  28. mShaderProgram.dispose();
  29. mMesh.dispose();
  30. }
  31. private void initShader() { // 初始化着色器程序
  32. String vertex = Gdx.files.internal("shaders/triangle_vertex.glsl").readString();
  33. String fragment = Gdx.files.internal("shaders/triangle_fragment.glsl").readString();
  34. mShaderProgram = new ShaderProgram(vertex, fragment);
  35. }
  36. private void initMesh() { // 初始化网格
  37. float[] vertices = {
  38. -0.5f, -0.5f, 0.0f,
  39. 0.5f, -0.5f, 0.0f,
  40. 0.0f, 0.5f, 0.0f
  41. };
  42. short[] indices = {0, 1, 2};
  43. VertexAttribute vertexAttr = new VertexAttribute(Usage.Position, 3, "a_position");
  44. mMesh = new Mesh(true, vertices.length / 3, indices.length, vertexAttr);
  45. mMesh.setVertices(vertices);
  46. mMesh.setIndices(indices);
  47. }
  48. }

? triangle_vertex.glsl

  1. #version 300 es
  2. in vec3 a_position;
  3. void main() {
  4. gl_Position = vec4(a_position, 1.0);
  5. }

? 说明:triangle_vertex.glsl 文件放在【assets / shaders】目录下面。

? triangle_fragment.glsl

  1. #version 300 es
  2. precision mediump float; // 声明float型变量的精度为mediump
  3. out vec4 fragColor;
  4. void main() {
  5. fragColor = vec4(1, 0, 0, 1);
  6. }

? 说明:triangle_fragment.glsl 文件放在【assets / shaders】目录下面。

? 运行效果如下。

img

2.2 绘制彩色三角形

? Triangle.java

  1. package com.zhyan8.game;
  2. import com.badlogic.gdx.ApplicationAdapter;
  3. import com.badlogic.gdx.Gdx;
  4. import com.badlogic.gdx.graphics.GL30;
  5. import com.badlogic.gdx.graphics.Mesh;
  6. import com.badlogic.gdx.graphics.VertexAttribute;
  7. import com.badlogic.gdx.graphics.VertexAttributes.Usage;
  8. import com.badlogic.gdx.graphics.glutils.ShaderProgram;
  9. public class Triangle extends ApplicationAdapter {
  10. private ShaderProgram mShaderProgram;
  11. private Mesh mMesh;
  12. @Override
  13. public void create() {
  14. initShader();
  15. initMesh();
  16. }
  17. @Override
  18. public void render() {
  19. Gdx.gl.glClearColor(0.455f, 0.725f, 1.0f, 1.0f);
  20. Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
  21. // mShaderProgram.begin(); // 已过时, 请使用bind方法替换
  22. mShaderProgram.bind();
  23. mMesh.render(mShaderProgram, GL30.GL_TRIANGLES);
  24. // mShaderProgram.end(); // 已过时, 可以去掉
  25. }
  26. @Override
  27. public void dispose() {
  28. mShaderProgram.dispose();
  29. mMesh.dispose();
  30. }
  31. private void initShader() { // 初始化着色器程序
  32. String vertex = Gdx.files.internal("shaders/triangle_vertex.glsl").readString();
  33. String fragment = Gdx.files.internal("shaders/triangle_fragment.glsl").readString();
  34. mShaderProgram = new ShaderProgram(vertex, fragment);
  35. }
  36. private void initMesh() { // 初始化网格
  37. float[] vertices = {
  38. // 前3位是顶点位置数据, 后4位是顶点颜色数据
  39. -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
  40. 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
  41. 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f
  42. };
  43. short[] indices = {0, 1, 2};
  44. VertexAttribute vertexPosition = new VertexAttribute(Usage.Position, 3, "a_position");
  45. VertexAttribute vertexColor = new VertexAttribute(Usage.ColorUnpacked, 4, "a_color");
  46. mMesh = new Mesh(true, vertices.length / 7, indices.length, vertexPosition, vertexColor);
  47. mMesh.setVertices(vertices);
  48. mMesh.setIndices(indices);
  49. }
  50. }

? triangle_vertex.glsl

  1. #version 300 es
  2. in vec3 a_position;
  3. in vec4 a_color;
  4. out vec4 v_color;
  5. void main() {
  6. gl_Position = vec4(a_position, 1.0);
  7. v_color = a_color;
  8. }

? triangle_fragment.glsl

  1. #version 300 es
  2. precision mediump float; // 声明float型变量的精度为mediump
  3. in vec4 v_color;
  4. out vec4 fragColor;
  5. void main() {
  6. fragColor = v_color;
  7. }

? 运行效果如下。

img

2.3 三角形宽高比适配

? 本节通过引入相机,使得绘制后的三角形宽高比与三角形模型的宽高比一致。

? Triangle.java

  1. package com.zhyan8.game;
  2. import com.badlogic.gdx.ApplicationAdapter;
  3. import com.badlogic.gdx.Gdx;
  4. import com.badlogic.gdx.graphics.GL30;
  5. import com.badlogic.gdx.graphics.Mesh;
  6. import com.badlogic.gdx.graphics.OrthographicCamera;
  7. import com.badlogic.gdx.graphics.VertexAttribute;
  8. import com.badlogic.gdx.graphics.VertexAttributes.Usage;
  9. import com.badlogic.gdx.graphics.glutils.ShaderProgram;
  10. public class Triangle extends ApplicationAdapter {
  11. private OrthographicCamera mCamera;
  12. private ShaderProgram mShaderProgram;
  13. private Mesh mMesh;
  14. @Override
  15. public void create() {
  16. initCamera();
  17. initShader();
  18. initMesh();
  19. }
  20. @Override
  21. public void render() {
  22. Gdx.gl.glClearColor(0.455f, 0.725f, 1.0f, 1.0f);
  23. Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
  24. // mShaderProgram.begin(); // 已过时, 请使用bind方法替换
  25. mShaderProgram.bind();
  26. mShaderProgram.setUniformMatrix("u_projectionViewMatrix", mCamera.combined);
  27. mMesh.render(mShaderProgram, GL30.GL_TRIANGLES);
  28. // mShaderProgram.end(); // 已过时, 可以去掉
  29. }
  30. @Override
  31. public void dispose() {
  32. mShaderProgram.dispose();
  33. mMesh.dispose();
  34. }
  35. private void initCamera() {
  36. mCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
  37. mCamera.near = 0.3f;
  38. mCamera.far = 1000f;
  39. mCamera.zoom = 0.005f; // 相机缩放级别, 值越大观察范围越大, 看到的图形越小
  40. mCamera.position.set(0f, 0f, -5f);
  41. mCamera.lookAt(0, 0, 0);
  42. mCamera.update();
  43. }
  44. private void initShader() { // 初始化着色器程序
  45. String vertex = Gdx.files.internal("shaders/triangle_vertex.glsl").readString();
  46. String fragment = Gdx.files.internal("shaders/triangle_fragment.glsl").readString();
  47. mShaderProgram = new ShaderProgram(vertex, fragment);
  48. }
  49. private void initMesh() { // 初始化网格
  50. float[] vertices = {
  51. -0.5f, -0.5f, 0.0f,
  52. 0.5f, -0.5f, 0.0f,
  53. 0.0f, 0.5f, 0.0f,
  54. };
  55. short[] indices = {0, 1, 2};
  56. VertexAttribute vertexPosition = new VertexAttribute(Usage.Position, 3, "a_position");
  57. mMesh = new Mesh(true, vertices.length / 3, indices.length, vertexPosition);
  58. mMesh.setVertices(vertices);
  59. mMesh.setIndices(indices);
  60. }
  61. }

? 说明:这里设置的三角形底边和高都为 1,即宽高比为 1: 1,我们期望绘制后的三角形宽高比也是 1 : 1,这时就需要通过相机进行变换。

? triangle_vertex.glsl

  1. #version 300 es
  2. in vec3 a_position;
  3. uniform mat4 u_projectionViewMatrix;
  4. void main() {
  5. gl_Position = u_projectionViewMatrix * vec4(a_position, 1.0);
  6. }

? 说明:这里通过正交相机的观察矩阵和投影矩阵变换,实现模型宽高比的适配,也可以对输入坐标的 y 值乘以屏幕宽高比,作为 gl_Position.y 的值。

? triangle_fragment.glsl

  1. #version 300 es
  2. precision mediump float; // 声明float型变量的精度为mediump
  3. out vec4 fragColor;
  4. void main() {
  5. fragColor = vec4(0, 1, 0, 0);
  6. }

? 运行效果如下,可以看到,绘制后的三角形宽高比也是 1 : 1。

img

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

原文链接:https://www.cnblogs.com/zhyan8/p/18024334

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号