Я хотел бы отобразить очень простую текстуру в GLSurfaceView, которая охватывает весь видовой экран.У меня отлично работает версия в WebGL, но по какой-то причине мой код Android не отображает мою текстуру (вообще).
Пытался жестко закодировать цвет во фрагментном шейдере, игнорировать текстуру, но ничегоизменилось ... может быть, шейдеры вообще не применяются?
private fun loadShader(shaderType: Int, source: String): Int {
var shader = GLES20.glCreateShader(shaderType)
if (shader != 0) {
GLES20.glShaderSource(shader, source)
GLES20.glCompileShader(shader)
val compiled = IntArray(1)
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0)
if (compiled[0] == 0) {
Log.e(TAG, "Could not compile shader $shaderType:")
Log.e(TAG, GLES20.glGetShaderInfoLog(shader))
GLES20.glDeleteShader(shader)
shader = 0
} else{
Log.e(TAG, "Shader $shaderType compiled!")
Log.e(TAG, GLES20.glGetShaderInfoLog(shader))
}
}
return shader
}
private fun createProgram(vertexSource: String, fragmentSource: String): Int {
val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource)
if (vertexShader == 0) {
return 0
}
val pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource)
if (pixelShader == 0) {
return 0
}
var program = GLES20.glCreateProgram()
if (program != 0) {
GLES20.glAttachShader(program, vertexShader)
checkGlError("glAttachShader")
GLES20.glAttachShader(program, pixelShader)
checkGlError("glAttachShader")
GLES20.glLinkProgram(program)
val linkStatus = IntArray(1)
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0)
if (linkStatus[0] != GLES20.GL_TRUE) {
Log.e(TAG, "Could not link program: ")
Log.e(TAG, GLES20.glGetProgramInfoLog(program))
GLES20.glDeleteProgram(program)
program = 0
} else {
Log.e(TAG, "Shader Program Linked!")
}
}
return program
}
private fun checkGlError(op: String) {
val error: Int = GLES20.glGetError()
while (error != GLES20.GL_NO_ERROR) {
Log.e(TAG, "$op: glError $error")
throw RuntimeException("$op: glError $error")
}
}
private fun initGL (side:Int) {
/*======== Defining and storing the geometry ===========*/
val verticesData = floatArrayOf(
-1.0f,1.0f,0.0f,
-1.0f,-1.0f,0.0f,
1.0f,-1.0f,0.0f,
1.0f,1.0f,0.0f
)
val indicesData = shortArrayOf(0,1,2,0,3,2)
val vertexBuffer : FloatBuffer = ByteBuffer.allocateDirect(verticesData.size * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer()
vertexBuffer.put(verticesData).position(0)
val indexBuffer : ShortBuffer = ByteBuffer.allocateDirect(indicesData.size * 2).order(ByteOrder.nativeOrder())
.asShortBuffer()
indexBuffer.put(indicesData).position(0)
val buffers = IntArray(2)
GLES20.glGenBuffers(2, buffers, 0)
val vbo = buffers[0]
val ibo = buffers[1]
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo)
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,
vertexBuffer.capacity() * 4, // 4 = bytes per float
vertexBuffer,
GLES20.GL_STATIC_DRAW)
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0)
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo)
GLES20.glBufferData(
GLES20.GL_ELEMENT_ARRAY_BUFFER,
indexBuffer.capacity() * 2, // 2 = bytes per short
indexBuffer,
GLES20.GL_STATIC_DRAW)
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0)
/*================ Shaders ====================*/
// Vertex shader source code
val vertCode =
"""
attribute vec3 coordinates;
void main(void) {
gl_Position = vec4(coordinates, 1.0);
}
"""
//fragment shader source code
val fragCode =
"""
precision mediump float;
// The texture.
uniform sampler2D u_tex;
void main(void) {
vec4 color = texture2D(u_tex, vec2(gl_FragCoord.x/$side.0, gl_FragCoord.y/$side.0));
gl_FragColor = color;
}
"""
// Create a shader program object to store
// the combined shader program
val shaderProgram = createProgram(vertCode, fragCode)
// Use the combined shader program object
GLES20.glUseProgram(shaderProgram)
/*======= Associating shaders to buffer objects =======*/
// Bind vertex buffer object
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo)
// Bind index buffer object
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo)
// Get the attribute location
val coord = GLES20.glGetAttribLocation(shaderProgram, "coordinates")
// Point an attribute to the currently bound VBO
GLES20.glVertexAttribPointer(coord, 3, GLES20.GL_FLOAT, false, 0,0)
// Enable the attribute
GLES20.glEnableVertexAttribArray(coord)
}
private fun updateGLCanvas (matrix : ByteArray, side : Int) {
val textureImage = floatArrayOf(
0f,0f,0f,
1f,0f,0f,
0f,0f,1f,
1f,1f,0f
)
val textureImageBuffer : FloatBuffer = ByteBuffer.allocateDirect(textureImage.size * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer()
textureImageBuffer.put(textureImage).position(0)
val texArray = IntArray(1)
GLES20.glGenTextures(1,texArray,0)
val textureId = texArray[0]
if (texArray[0]==0) Log.e(TAG, "Error with Texture!")
else Log.e(TAG, "Texture id $textureId created!")
GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId)
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE)
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE)
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST)
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST)
//TODO: Flip Y axis!!!
//gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT,1)
//gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, side, side, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array(matrix));
//TODO: change 2 to parameter 'side'
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0,GLES20.GL_RGB, 2, 2, 0, GLES20.GL_RGB, GLES20.GL_FLOAT, textureImageBuffer)
// Clear the canvas
GLES20.glClearColor(1f,0.5f,0.5f,0.9f)
// Enable the depth test
GLES20.glEnable(GLES20.GL_DEPTH_TEST)
// Clear the color buffer bit
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
// Set the view port
//TODO: set proper canvas dimensions
GLES20.glViewport(0,0,500,500)
// Draw the triangle
GLES20.glDrawElements(GLES20.GL_TRIANGLES,6, GLES20.GL_UNSIGNED_SHORT,0)
}
Шейдеры компилируются и связываются без ошибок.Код работает без проблем, но единственное, что показывает, это мой довольно розовый фон.Тестовый код должен отображать текстуру моего пикселя [2x2] ... но по какой-то причине он отказывается делать что-либо значимое.