Текстура перекашивается при вращении вдоль оси Z в Android OpenGL ES 2.0Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Текстура перекашивается при вращении вдоль оси Z в Android OpenGL ES 2.0

Сообщение Anonymous »

Я пытаюсь визуализировать растровое изображение, повернутое в GlSurfaceView, преобразовав его в текстуру и применив матрицы преобразований. но текстура отображается перекошенной.
вот код GlSurfaceView.Renderer

Код: Выделить всё

package com.example.animationrenderer

import android.content.Context
import android.graphics.Bitmap
import android.opengl.GLES20
import android.opengl.GLSurfaceView
import android.opengl.GLUtils
import android.opengl.Matrix
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

class ImageRenderer(private val context: Context, private val imageBitmap: Bitmap, val glView: GLSurfaceView, private val executor: ScheduledExecutorService) : GLSurfaceView.Renderer {

private var textureId: Int = 0
private var program: Int = 0

//Matrix
private val mvpMatrix = FloatArray(16)
private val projectionMatrix = FloatArray(16)
private val viewMatrix = FloatArray(16)
private val rotationMatrix = FloatArray(16)

//Handle
private var aPositionHandle = -1
private var uTextureHandle = -1
private var aTextureCoordinateHandle = -1
private var uMvpMatrixHandle = -1

private val vertexShaderCode = """
attribute vec4 a_Position;
attribute vec2 a_TexCoordinate;
varying vec2 v_TexCoordinate;
uniform mat4 u_MVPMatrix;
void main() {
gl_Position = u_MVPMatrix * a_Position;
v_TexCoordinate = a_TexCoordinate;
}
""".trimIndent()

private val fragmentShaderCode = """
precision mediump float;
varying vec2 v_TexCoordinate;
uniform sampler2D u_Texture;
void main() {
vec4 color = texture2D(u_Texture, v_TexCoordinate);
gl_FragColor = color;
}
""".trimIndent()

private val vertexData = floatArrayOf(
-1.0f, 1.0f,  // Top left
-1.0f, -1.0f,  // Bottom left
1.0f, 1.0f,  // Top right
1.0f, -1.0f // Bottom right
)

private val textureData = floatArrayOf(
0.0f, 0.0f,  // Top left (flipped)
0.0f, 1.0f,  // Bottom left
1.0f, 0.0f,  // Top right (flipped)
1.0f, 1.0f   // Bottom right
)

private val vertexBuffer: FloatBuffer = ByteBuffer.allocateDirect(8 * 4).run {
order(ByteOrder.nativeOrder())
asFloatBuffer().apply {
put(vertexData)
position(0)
}
}

private val texCoordBuffer: FloatBuffer = ByteBuffer.allocateDirect(8 * 4).run {
order(ByteOrder.nativeOrder())
asFloatBuffer().apply {
put(textureData)
position(0)
}
}

override fun onSurfaceCreated(gl: GL10?, config:  EGLConfig?) {

val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)

program = GLES20.glCreateProgram().also {
GLES20.glAttachShader(it, vertexShader)
GLES20.glAttachShader(it, fragmentShader)
GLES20.glLinkProgram(it)
}

val textureHandle = IntArray(1)
GLES20.glGenTextures(1, textureHandle, 0)
textureId = textureHandle[0]

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId)

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)

GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, imageBitmap, 0)

imageBitmap.recycle()

//Handles
aPositionHandle = GLES20.glGetAttribLocation(program, "a_Position")
uTextureHandle = GLES20.glGetUniformLocation(program, "u_Texture")
aTextureCoordinateHandle = GLES20.glGetAttribLocation(program, "a_TexCoordinate")
uMvpMatrixHandle = GLES20.glGetUniformLocation(program, "u_MVPMatrix")

GLES20.glEnable(GLES20.GL_BLEND)
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA)
Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, 3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
executor.scheduleAtFixedRate(::mRequestRender, 0, 33, TimeUnit.MILLISECONDS)
}

override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
"surface changed called".rlog()
GLES20.glViewport(0, 0, width, height)
val aspectRatio = width.toFloat() / height.toFloat()

val bitmapAspectRatio = imageBitmap.width.toFloat() / imageBitmap.height.toFloat()
val projectionWidth: Float
val projectionHeight: Float
if (aspectRatio > bitmapAspectRatio) {
// Width is larger, adjust height
projectionWidth = aspectRatio / bitmapAspectRatio
projectionHeight = 1.0f
} else {
// Height is larger or equal, adjust width
projectionWidth = 1.0f
projectionHeight = bitmapAspectRatio / aspectRatio
}
Matrix.orthoM(projectionMatrix, 0, -projectionWidth, projectionWidth, -projectionHeight, projectionHeight, 3f, 7f)
}
fun mRequestRender(){
glView.requestRender()
}

var rotate = 45f

override fun onDrawFrame(gl: GL10?) {
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)

GLES20.glUseProgram(program)
Matrix.setRotateM(rotationMatrix, 0, rotate, 0f, 0f, 1.0f)

val temp = FloatArray(16)
Matrix.multiplyMM(temp, 0, projectionMatrix, 0, viewMatrix, 0)
Matrix.multiplyMM(mvpMatrix, 0, temp, 0, rotationMatrix, 0)
GLES20.glUniformMatrix4fv(uMvpMatrixHandle, 1, false, mvpMatrix, 0)

GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId)
GLES20.glUniform1i(uTextureHandle, 0)
GLES20.glVertexAttribPointer(aPositionHandle, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer)
GLES20.glEnableVertexAttribArray(aPositionHandle)

GLES20.glVertexAttribPointer(aTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 0, texCoordBuffer)
GLES20.glEnableVertexAttribArray(aTextureCoordinateHandle)
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4)
}

private fun loadShader(type: Int, shaderCode: String): Int {
return GLES20.glCreateShader(type).also { shader ->
GLES20.glShaderSource(shader, shaderCode)
GLES20.glCompileShader(shader)
}
}
}

введите здесь описание изображения
Я попробовал изменить порядок умножения матриц и изменить значения матрицы проекции. Я ожидаю, что текстура будет отображаться повернутой без каких-либо искажений или растяжений. не могли бы вы сказать мне, почему это перекошено?

Подробнее здесь: https://stackoverflow.com/questions/784 ... ngl-es-2-0
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»