需要制作一个Slam地图的3d显示,捣鼓了两个星期终于弄出来了,虽然效果没有达到预期,记录一下(图片随便找的)
首先是顶点着色器
#version 300 es
layout (location = 0) in vec4 vPosition;
layout (location = 1) in vec2 aTextureCord;
uniform mat4 u_Matrix;
//输出纹理坐标(s,t)
out vec2 vTexCord;
void main() {
gl_Position = u_Matrix*vPosition;
gl_PointSize = 10.0;
vTexCord = aTextureCord;
}
?片段着色器
#version 300 es
precision mediump float;
uniform sampler2D uTextureUnit;
//接收刚才顶点着色器传入的纹理坐标(s,t)
in vec2 vTexCord;
out vec4 vFragColor;
void main() {
vFragColor = texture(uTextureUnit,vTexCord);
}
?编译链接程序片段
//编译
final int vertexShaderId = ShaderUtils.compileVertexShader(ResReadUtils.readResource(R.raw.vertex_plane_shader));
final int fragmentShaderId = ShaderUtils.compileFragmentShader(ResReadUtils.readResource(R.raw.fragment_plane_shader));
//链接程序片段
mProgram = ShaderUtils.linkProgram(vertexShaderId, fragmentShaderId);
//获取属性位置
uMatrixLocation = GLES30.glGetUniformLocation(mProgram, "u_Matrix");
aPositionLocation = GLES30.glGetAttribLocation(mProgram, "vPosition");
aTextureLocation = GLES30.glGetAttribLocation(mProgram, "aTextureCord");
设置一块地板的矩阵分为几乘几,现在设置的200就是将图片分割为200*200
//图片生成的位图
private float bitSize = 1f;
private float matrixSize = 200;
随机生成坐标数据,并计算顶点坐标和绘制顶点顺序
public void setMapData() {
//随机生成坐标数据
List<Point> points = new ArrayList<>();
for (int i = -200; i < 200; i++) {
for (int j = -200; j < 200; j++) {
if ((int) (Math.random() * 2) == 0)
points.add(new Point(i, j));
}
}
POSITION_VERTEX = new float[points.size() * 12];
VERTEX_INDEX = new int[points.size() * 6];
TEX_VERTEX = new float[points.size() * 8];
for (int i = 0; i < points.size(); i++) {
int x = points.get(i).x;
int y = points.get(i).y;
TEX_VERTEX[i * 8 + 0] = x % matrixSize / matrixSize;
TEX_VERTEX[i * 8 + 1] = 1 - (y % matrixSize / matrixSize);
TEX_VERTEX[i * 8 + 2] = (x % matrixSize - 1) / matrixSize;
TEX_VERTEX[i * 8 + 3] = 1 - (y % matrixSize / matrixSize);
TEX_VERTEX[i * 8 + 4] = (x % matrixSize - 1) / matrixSize;
TEX_VERTEX[i * 8 + 5] = 1 - (y % matrixSize - 1) / matrixSize;
TEX_VERTEX[i * 8 + 6] = x % matrixSize / matrixSize;
TEX_VERTEX[i * 8 + 7] = 1 - (y % matrixSize - 1) / matrixSize;
VERTEX_INDEX[i * 6] = (i * 4);
VERTEX_INDEX[i * 6 + 1] = (i * 4 + 1);
VERTEX_INDEX[i * 6 + 2] = (i * 4 + 2);
VERTEX_INDEX[i * 6 + 3] = (i * 4);
VERTEX_INDEX[i * 6 + 4] = (i * 4 + 2);
VERTEX_INDEX[i * 6 + 5] = (i * 4 + 3);
POSITION_VERTEX[i * 12] = x * 2 + bitSize;
POSITION_VERTEX[i * 12 + 1] = y * 2 + bitSize;
POSITION_VERTEX[i * 12 + 2] = 0;
POSITION_VERTEX[i * 12 + 3] = x * 2 - bitSize;
POSITION_VERTEX[i * 12 + 4] = y * 2 + bitSize;
POSITION_VERTEX[i * 12 + 5] = 0;
POSITION_VERTEX[i * 12 + 6] = x * 2 - bitSize;
POSITION_VERTEX[i * 12 + 7] = y * 2 - bitSize;
POSITION_VERTEX[i * 12 + 8] = 0;
POSITION_VERTEX[i * 12 + 9] = x * 2 + bitSize;
POSITION_VERTEX[i * 12 + 10] = y * 2 - bitSize;
POSITION_VERTEX[i * 12 + 11] = 0;
}
vertexBuffer = ByteBuffer.allocateDirect(POSITION_VERTEX.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
vertexBuffer.put(POSITION_VERTEX);
vertexBuffer.position(0);
mTexVertexBuffer = ByteBuffer.allocateDirect(TEX_VERTEX.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(TEX_VERTEX);
mTexVertexBuffer.position(0);
mVertexIndexBuffer = ByteBuffer.allocateDirect(VERTEX_INDEX.length * 4)
.order(ByteOrder.nativeOrder())
.asIntBuffer()
.put(VERTEX_INDEX);
mVertexIndexBuffer.position(0);
开始绘制
public void draw(float[] mMVPMatrix, int textureId) {
GLES30.glUseProgram(mProgram);
//将变换矩阵传入顶点渲染器
GLES30.glUniformMatrix4fv(uMatrixLocation, 1, false, mMVPMatrix, 0);
//启用顶点坐标属性
GLES30.glEnableVertexAttribArray(aPositionLocation);
GLES30.glVertexAttribPointer(aPositionLocation, 3, GLES30.GL_FLOAT, false, 0, vertexBuffer);
//启用纹理坐标属性
GLES30.glEnableVertexAttribArray(aTextureLocation);
GLES30.glVertexAttribPointer(aTextureLocation, 2, GLES30.GL_FLOAT, false, 0, mTexVertexBuffer);
//激活纹理
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
//绑定纹理
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textureId);
// 绘制
GLES30.glDrawElements(GLES20.GL_TRIANGLES, VERTEX_INDEX.length, GLES20.GL_UNSIGNED_INT, mVertexIndexBuffer);
//禁止顶点数组的句柄
GLES30.glDisableVertexAttribArray(aPositionLocation);
GLES30.glDisableVertexAttribArray(aTextureLocation);
}
绘制结果
所有坐标填满的结果
|