GLES20.glUniform4fv 和 fragshader
GLES20.glUniform4fv and fragshader
好吧,我正在尝试在一个对象中循环并使用多种颜色,但似乎无法弄清楚并打算老老实实地扯掉我的头发,但这段代码来自 Androids 指南,我有现在已经玩了一分钟,尝试了很多不同的东西,但最终总是回到这个问题,“它是片段着色器,还是我只是在使用函数 GLES20.glUniform4fv(colorHandle, 2, color, 0 ) 错了吗?如果它不能接受颜色数组参数,为什么它会有一个 'count' 值和一个数组参数?
class Triangle {
private var mProgram: Int
private var vPMatrixHandle: Int = 0
private var positionHandle: Int = 0
private var mColorHandle: Int = 0
private val fragmentShaderCode: String =
"precision mediump float;\n" +
"uniform vec4 vColor[];\n" +
"void main() {\n" +
"\tgl_FragColor = vColor;\n" +
"}"
private val vertexShaderCode: String =
"uniform mat4 uMVPMatrix;\n" +
"attribute vec4 vPosition;\n" +
"void main() {\n" +
"\tgl_Position = uMVPMatrix * vPosition;\n" +
"}"
private val COORDS_PER_VERTEX: Int = 3
private var triangleCoords: FloatArray = floatArrayOf(
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f
)
private val color: FloatArray = floatArrayOf(
0.63671875f, 0.76953125f, 0.22265625f, 1.0f,
0.63671875f, 0.22953125f, 0.78265625f, 1.0f
)
private val indiceCoords: ByteArray = byteArrayOf(
0, 4, 5, 0, 5, 1,
1, 5, 6, 1, 6, 2,
2, 6, 7, 2, 7, 3,
3, 7, 4, 3, 4, 0,
4, 7, 6, 4, 6, 5,
3, 0, 1, 3, 1, 2
)
private val vertexCount: Int = triangleCoords.size / COORDS_PER_VERTEX
private val vertexStride: Int = COORDS_PER_VERTEX * 4
private var vertexBuffer: FloatBuffer =
ByteBuffer.allocateDirect(triangleCoords.size * 4).run {
order(ByteOrder.nativeOrder())
asFloatBuffer().apply {
put(triangleCoords)
position(0)
}
}
private var indiceBuffer: ByteBuffer =
ByteBuffer.allocateDirect(indiceCoords.size * 4).run {
order(ByteOrder.nativeOrder()).apply {
put(indiceCoords)
position(0)
}
}
init {
val vertexShader: Int = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
val fragmentShader: Int = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)
mProgram = GLES20.glCreateProgram().also {
GLES20.glAttachShader(it, vertexShader)
GLES20.glAttachShader(it, fragmentShader)
GLES20.glLinkProgram(it)
}
}
fun loadShader(type: Int, shaderCode: String): Int {
return GLES20.glCreateShader(type).also { shader ->
GLES20.glShaderSource(shader, shaderCode)
GLES20.glCompileShader(shader)
}
}
fun draw(mvpMatrix: FloatArray) {
GLES20.glUseProgram(mProgram)
positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition").also {
GLES20.glEnableVertexAttribArray(it)
GLES20.glVertexAttribPointer(
it,
COORDS_PER_VERTEX,
GLES20.GL_FLOAT,
false,
vertexStride,
vertexBuffer
)
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor").also { colorHandle ->
GLES20.glUniform4fv(colorHandle, 2, color, 0)
}
vPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix")
GLES20.glUniformMatrix4fv(vPMatrixHandle, 1, false, mvpMatrix, 0)
GLES20.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, indiceBuffer)
GLES20.glDisableVertexAttribArray(it)
}
}
}
如果您想将颜色关联到顶点,则必须添加一个附加属性。颜色数必须与顶点数相同。
向顶点着色器添加颜色属性 (attribute vec4 vColor;
)。将属性从顶点着色器传递到片段着色器 (varying vec4 color;
):
private val fragmentShaderCode: String =
"precision mediump float;\n" +
"varying vec4 color;\n" +
"void main() {\n" +
"\tgl_FragColor = color;\n" +
"}"
private val vertexShaderCode: String =
"uniform mat4 uMVPMatrix;\n" +
"attribute vec4 vPosition;\n" +
"attribute vec4 vColor;\n" +
"varying vec4 color;\n" +
"void main() {\n" +
"\tcolor = vColor;\n" +
"\tgl_Position = uMVPMatrix * vPosition;\n" +
"}"
定义一个有8种颜色的数组。例如:
private val COORDS_PER_COLOR: Int = 4
private val color: FloatArray = floatArrayOf(
0.63671875f, 0.76953125f, 0.22265625f, 1.0f,
0.63671875f, 0.22953125f, 0.78265625f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f
)
private val colorCount: Int = color.size / COORDS_PER_COLOR
private val colorStride: Int = COORDS_PER_COLOR * 4
为颜色属性创建缓冲区:
private var colorBuffer: FloatBuffer =
ByteBuffer.allocateDirect(color.size * 4).run {
order(ByteOrder.nativeOrder())
asFloatBuffer().apply {
put(color)
position(0)
}
}
指定颜色属性数组:
mColorHandle = GLES20.glGetAttribLocation(mProgram, "vColor").also { colorHandle ->
GLES20.glEnableVertexAttribArray(colorHandle)
GLES20.glVertexAttribPointer(
colorHandle,
COORDS_PER_COLOR,
GLES20.GL_FLOAT,
false,
colorStride,
colorBuffer
)
}
如果您想使用“统一”数组 (vColor[]),请在声明中明确指定 array-size。
private val fragmentShaderCode: String =
"precision mediump float;\n" +
"uniform vec4 vColor[2];\n" +
"varying vec4 vParam;" +
"void main() {\n" +
"\tgl_FragColor = vColor[int(step(vParam.x * vParam.y * vParam.z, 0.0))];\n" +
"}"
private val vertexShaderCode: String =
"uniform mat4 uMVPMatrix;\n" +
"attribute vec4 vPosition;\n" +
"varying vec4 vParam;" +
"void main() {\n" +
"\tgl_Position = uMVPMatrix * vPosition;\n" +
"\tvParam = vPosition;" +
"}"
好吧,我正在尝试在一个对象中循环并使用多种颜色,但似乎无法弄清楚并打算老老实实地扯掉我的头发,但这段代码来自 Androids 指南,我有现在已经玩了一分钟,尝试了很多不同的东西,但最终总是回到这个问题,“它是片段着色器,还是我只是在使用函数 GLES20.glUniform4fv(colorHandle, 2, color, 0 ) 错了吗?如果它不能接受颜色数组参数,为什么它会有一个 'count' 值和一个数组参数?
class Triangle {
private var mProgram: Int
private var vPMatrixHandle: Int = 0
private var positionHandle: Int = 0
private var mColorHandle: Int = 0
private val fragmentShaderCode: String =
"precision mediump float;\n" +
"uniform vec4 vColor[];\n" +
"void main() {\n" +
"\tgl_FragColor = vColor;\n" +
"}"
private val vertexShaderCode: String =
"uniform mat4 uMVPMatrix;\n" +
"attribute vec4 vPosition;\n" +
"void main() {\n" +
"\tgl_Position = uMVPMatrix * vPosition;\n" +
"}"
private val COORDS_PER_VERTEX: Int = 3
private var triangleCoords: FloatArray = floatArrayOf(
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f
)
private val color: FloatArray = floatArrayOf(
0.63671875f, 0.76953125f, 0.22265625f, 1.0f,
0.63671875f, 0.22953125f, 0.78265625f, 1.0f
)
private val indiceCoords: ByteArray = byteArrayOf(
0, 4, 5, 0, 5, 1,
1, 5, 6, 1, 6, 2,
2, 6, 7, 2, 7, 3,
3, 7, 4, 3, 4, 0,
4, 7, 6, 4, 6, 5,
3, 0, 1, 3, 1, 2
)
private val vertexCount: Int = triangleCoords.size / COORDS_PER_VERTEX
private val vertexStride: Int = COORDS_PER_VERTEX * 4
private var vertexBuffer: FloatBuffer =
ByteBuffer.allocateDirect(triangleCoords.size * 4).run {
order(ByteOrder.nativeOrder())
asFloatBuffer().apply {
put(triangleCoords)
position(0)
}
}
private var indiceBuffer: ByteBuffer =
ByteBuffer.allocateDirect(indiceCoords.size * 4).run {
order(ByteOrder.nativeOrder()).apply {
put(indiceCoords)
position(0)
}
}
init {
val vertexShader: Int = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
val fragmentShader: Int = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)
mProgram = GLES20.glCreateProgram().also {
GLES20.glAttachShader(it, vertexShader)
GLES20.glAttachShader(it, fragmentShader)
GLES20.glLinkProgram(it)
}
}
fun loadShader(type: Int, shaderCode: String): Int {
return GLES20.glCreateShader(type).also { shader ->
GLES20.glShaderSource(shader, shaderCode)
GLES20.glCompileShader(shader)
}
}
fun draw(mvpMatrix: FloatArray) {
GLES20.glUseProgram(mProgram)
positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition").also {
GLES20.glEnableVertexAttribArray(it)
GLES20.glVertexAttribPointer(
it,
COORDS_PER_VERTEX,
GLES20.GL_FLOAT,
false,
vertexStride,
vertexBuffer
)
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor").also { colorHandle ->
GLES20.glUniform4fv(colorHandle, 2, color, 0)
}
vPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix")
GLES20.glUniformMatrix4fv(vPMatrixHandle, 1, false, mvpMatrix, 0)
GLES20.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, indiceBuffer)
GLES20.glDisableVertexAttribArray(it)
}
}
}
如果您想将颜色关联到顶点,则必须添加一个附加属性。颜色数必须与顶点数相同。
向顶点着色器添加颜色属性 (attribute vec4 vColor;
)。将属性从顶点着色器传递到片段着色器 (varying vec4 color;
):
private val fragmentShaderCode: String =
"precision mediump float;\n" +
"varying vec4 color;\n" +
"void main() {\n" +
"\tgl_FragColor = color;\n" +
"}"
private val vertexShaderCode: String =
"uniform mat4 uMVPMatrix;\n" +
"attribute vec4 vPosition;\n" +
"attribute vec4 vColor;\n" +
"varying vec4 color;\n" +
"void main() {\n" +
"\tcolor = vColor;\n" +
"\tgl_Position = uMVPMatrix * vPosition;\n" +
"}"
定义一个有8种颜色的数组。例如:
private val COORDS_PER_COLOR: Int = 4
private val color: FloatArray = floatArrayOf(
0.63671875f, 0.76953125f, 0.22265625f, 1.0f,
0.63671875f, 0.22953125f, 0.78265625f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f
)
private val colorCount: Int = color.size / COORDS_PER_COLOR
private val colorStride: Int = COORDS_PER_COLOR * 4
为颜色属性创建缓冲区:
private var colorBuffer: FloatBuffer =
ByteBuffer.allocateDirect(color.size * 4).run {
order(ByteOrder.nativeOrder())
asFloatBuffer().apply {
put(color)
position(0)
}
}
指定颜色属性数组:
mColorHandle = GLES20.glGetAttribLocation(mProgram, "vColor").also { colorHandle ->
GLES20.glEnableVertexAttribArray(colorHandle)
GLES20.glVertexAttribPointer(
colorHandle,
COORDS_PER_COLOR,
GLES20.GL_FLOAT,
false,
colorStride,
colorBuffer
)
}
如果您想使用“统一”数组 (vColor[]),请在声明中明确指定 array-size。
private val fragmentShaderCode: String =
"precision mediump float;\n" +
"uniform vec4 vColor[2];\n" +
"varying vec4 vParam;" +
"void main() {\n" +
"\tgl_FragColor = vColor[int(step(vParam.x * vParam.y * vParam.z, 0.0))];\n" +
"}"
private val vertexShaderCode: String =
"uniform mat4 uMVPMatrix;\n" +
"attribute vec4 vPosition;\n" +
"varying vec4 vParam;" +
"void main() {\n" +
"\tgl_Position = uMVPMatrix * vPosition;\n" +
"\tvParam = vPosition;" +
"}"