想几个问题:绘制三角形,需要三个顶点,顶点我们使用属性指定,属性的指定我们使用数组结构还是结构数组,那么需不需要放入到顶点缓存区。我们创建的片元和片段着色器精度是float还是其他,需要做矩阵变换。
问题一:
需要三个顶点,那么我们绘制如下位置的三角形
0.5f, 0.5f, 0.0f, // top
- 0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f // bottom right
想象一下图形,想完了……。
需要将数据变为本地格式,这里有个概念大头和小头,主要是java和本地的差距。需要做以下操作:
ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(triangleCoords);
vertexBuffer.position(0);
问题二:我们放不放顶点缓存区。
不放,好,那没事 。
问题三:数组结构还是结构数组
数组结构了,只有一个属性,等需要变色的时候在加吧。
问题四:精度?
片元我们使用默认,片段使用float,可以着色器写了?没有,写着色器。
private final String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" + //顶点位置
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"void main() {" +
" gl_FragColor = vec4(1,1,1,1);" + //输出白色
"}";
问题5:需不需要做矩阵变换?
不需要,那就这样了。
绘制
绘制的时候就拿出基本套路。
1.创建着色器
2.加载程序
3.编译
4.创建程序
5.附着程序
6.链接使用
7.找出属性位置
8.设置值
9.绘制。
public class Triangle extends BaseGameScreen {
private final String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
static final int COORDS_PER_VERTEX = 3;
private FloatBuffer vertexBuffer;
static float triangleCoords[] = {
0.5f, 0.5f, 0.0f, // top
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f // bottom right
};
//顶点个数
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
//顶点之间的偏移量
private final int vertexStride = COORDS_PER_VERTEX * 4; // 每个顶点四个字节
//设置颜色,依次为红绿蓝和透明通道
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
private int mPositionHandle;
private int mColorHandle;
float d = 0.01F;
public Triangle(){
}
public void create(){
ByteBuffer bb = ByteBuffer.allocateDirect(
triangleCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(triangleCoords);
vertexBuffer.position(0);
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderCode);
mProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mProgram,vertexShader);
GLES20.glAttachShader(mProgram,fragmentShader);
GLES20.glLinkProgram(mProgram);
//程序加入到环境里面
GLES20.glUseProgram(mProgram);
// 检查是否有效
GLES20.glValidateProgram(mProgram);
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
}
@Override
public void surfaceChange(int width, int height) {
GLES20.glViewport(0,0,width,height);
}
@Override
public void dispose() {
}
@Override
public void render() {
//获取位置句柄 属性句柄
GLES20.glEnableVertexAttribArray(mPositionHandle);
//准备三角形的坐标数据
GLES20.glVertexAttribPointer(
mPositionHandle,
COORDS_PER_VERTEX,
GLES20.GL_FLOAT,
false,
vertexStride,
vertexBuffer);
//获取片元着色器的vColor成员的句柄
color[1] = color[1]-d;
if (color[1]<=0||color[1]>=1){
d=-d;
}
//设置绘制三角形的颜色
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
//绘制三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
//禁止顶点数组的句柄
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
绘制基本都是这个套路。
网友评论