Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.example.myapplication
- import android.content.Context
- import android.graphics.Bitmap
- import android.graphics.BitmapFactory
- import android.opengl.GLES20
- import android.opengl.GLUtils
- import android.opengl.GLSurfaceView
- import android.os.Bundle
- import androidx.appcompat.app.AppCompatActivity
- import java.nio.ByteBuffer
- import java.nio.ByteOrder
- import java.nio.FloatBuffer
- import javax.microedition.khronos.egl.EGLConfig
- import javax.microedition.khronos.opengles.GL10
- import android.opengl.Matrix
- import android.view.MotionEvent
- import kotlin.math.cos
- import kotlin.math.sin
- class MainActivity : AppCompatActivity() {
- private lateinit var glSurfaceView: MyGLSurfaceView
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- glSurfaceView = MyGLSurfaceView(this)
- setContentView(glSurfaceView)
- }
- }
- private const val TOUCH_SCALE_FACTOR: Float = 180.0f / 320f
- class MyGLSurfaceView(context: Context) : GLSurfaceView(context) {
- private val renderer: MyGLRenderer
- private var previousX: Float = 0f
- private var previousY: Float = 0f
- override fun onTouchEvent(e: MotionEvent): Boolean {
- // MotionEvent reports input details from the touch screen
- // and other input controls. In this case, you are only
- // interested in events where the touch position changed.
- val x: Float = e.x
- val y: Float = e.y
- when (e.action) {
- MotionEvent.ACTION_MOVE -> {
- var dx: Float = x - previousX
- var dy: Float = y - previousY
- // reverse direction of rotation above the mid-line
- if (y > height / 2) {
- dx *= -1
- }
- // reverse direction of rotation to left of the mid-line
- if (x < width / 2) {
- dy *= -1
- }
- renderer.angle += (dx + dy) * TOUCH_SCALE_FACTOR
- requestRender()
- }
- }
- previousX = x
- previousY = y
- return true
- }
- init {
- setEGLContextClientVersion(2)
- renderer = MyGLRenderer(context)
- setRenderer(renderer)
- }
- }
- class MyGLRenderer(private val context: Context) : GLSurfaceView.Renderer {
- private lateinit var square: Square
- private lateinit var triangle: Triangle
- private val vPMatrix = FloatArray(16)
- private val projectionMatrix = FloatArray(16)
- private val viewMatrix = FloatArray(16)
- private val rotationMatrix = FloatArray(16)
- @Volatile
- var angle: Float = 0f
- private var textureHandle: Int = 0
- override fun onSurfaceCreated(unused: GL10?, config: EGLConfig?) {
- GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
- square = Square()
- triangle = Triangle()
- val resourceId = context.resources.getIdentifier("wooden", "drawable", context.packageName)
- val bitmap: Bitmap = BitmapFactory.decodeResource(context.resources, resourceId)
- textureHandle = loadTexture(bitmap)
- bitmap.recycle()
- }
- override fun onDrawFrame(gl: GL10) {
- val scratch = FloatArray(16)
- // Set the camera position (View matrix)
- Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, 3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
- // Calculate the projection and view transformation
- Matrix.multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0)
- // Create a rotation transformation for the triangle
- //val time = SystemClock.uptimeMillis() % 4000L
- //val angle = 0.090f * time.toInt()
- Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1.0f)
- // Combine the rotation matrix with the projection and camera view
- Matrix.multiplyMM(scratch, 0, vPMatrix, 0, rotationMatrix, 0)
- GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
- square.draw(scratch, textureHandle)
- triangle.draw(scratch, textureHandle)
- }
- override fun onSurfaceChanged(unused: GL10?, width: Int, height: Int) {
- GLES20.glViewport(0, 0, width, height)
- val ratio: Float = width.toFloat() / height.toFloat()
- // this projection matrix is applied to object coordinates
- // in the onDrawFrame() method
- Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
- }
- private fun loadTexture(bitmap: Bitmap): Int {
- val textureHandle = IntArray(1)
- GLES20.glGenTextures(1, textureHandle, 0)
- if (textureHandle[0] != 0) {
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0])
- 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, bitmap, 0)
- bitmap.recycle()
- }
- if (textureHandle[0] == 0) {
- throw RuntimeException("Error loading texture.")
- }
- return textureHandle[0]
- }
- }
- class Square {
- private val squareCoords = floatArrayOf(
- -0.4f, 0.0f, 0.0f, // Верхний левый угол
- -0.4f, -0.8f, 0.0f, // Нижний левый угол
- 0.4f, -0.8f, 0.0f, // Нижний правый угол
- 0.4f, 0.0f, 0.0f // Верхний правый угол
- )
- private val textureCoords = floatArrayOf(
- 0.0f, 1.0f, // Верхний левый угол текстуры
- 0.0f, 0.0f, // Нижний левый угол текстуры
- 1.0f, 0.0f, // Нижний правый угол текстуры
- 1.0f, 1.0f // Верхний правый угол текстуры
- )
- private val vertexShaderCode =
- "uniform mat4 uMVPMatrix;" +
- "attribute vec4 vPosition;" +
- "attribute vec2 aTexCoordinate;" +
- "varying vec2 vTexCoordinate;" +
- "void main() {" +
- " gl_Position = uMVPMatrix * vPosition;" +
- " vTexCoordinate = aTexCoordinate;" +
- "}"
- private val fragmentShaderCode =
- "precision mediump float;" +
- "uniform sampler2D uTexture;" +
- "varying vec2 vTexCoordinate;" +
- "void main() {" +
- " gl_FragColor = texture2D(uTexture, vTexCoordinate);" +
- "}"
- private var mProgram: Int = 0
- private val vertexBuffer: FloatBuffer = ByteBuffer.allocateDirect(squareCoords.size * 4)
- .order(ByteOrder.nativeOrder())
- .asFloatBuffer()
- .put(squareCoords)
- .apply { position(0) }
- private val textureBuffer: FloatBuffer = ByteBuffer.allocateDirect(textureCoords.size * 4)
- .order(ByteOrder.nativeOrder())
- .asFloatBuffer()
- .put(textureCoords)
- .apply { 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 draw(mvpMatrix: FloatArray, textureHandle: Int) {
- GLES20.glUseProgram(mProgram)
- val positionHandle: Int = GLES20.glGetAttribLocation(mProgram, "vPosition")
- GLES20.glEnableVertexAttribArray(positionHandle)
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer)
- val mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix")
- GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
- val textureCoordinateHandle: Int = GLES20.glGetAttribLocation(mProgram, "aTexCoordinate")
- GLES20.glEnableVertexAttribArray(textureCoordinateHandle)
- GLES20.glVertexAttribPointer(textureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer)
- val textureUniformHandle: Int = GLES20.glGetUniformLocation(mProgram, "uTexture")
- GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle)
- GLES20.glUniform1i(textureUniformHandle, 0)
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4)
- GLES20.glDisableVertexAttribArray(positionHandle)
- GLES20.glDisableVertexAttribArray(textureCoordinateHandle)
- }
- }
- class Triangle {
- private val triangleCoords = floatArrayOf(
- 0.0f, 0.9f, 0.0f, // Верхняя точка
- -0.5f, 0.1f, 0.0f, // Левая нижняя точка
- 0.5f, 0.1f, 0.0f // Правая нижняя точка
- )
- private val textureCoords = floatArrayOf(
- 0.5f, 0.0f, // Верхняя точка текстуры
- 0.0f, 1.0f, // Левая нижняя точка текстуры
- 1.0f, 1.0f // Правая нижняя точка текстуры
- )
- private val vertexShaderCode =
- "uniform mat4 uMVPMatrix;" +
- "attribute vec4 vPosition;" +
- "attribute vec2 aTexCoordinate;" +
- "varying vec2 vTexCoordinate;" +
- "void main() {" +
- " gl_Position = uMVPMatrix * vPosition;" +
- " vTexCoordinate = aTexCoordinate;" +
- "}"
- private val fragmentShaderCode =
- "precision mediump float;" +
- "uniform sampler2D uTexture;" +
- "varying vec2 vTexCoordinate;" +
- "void main() {" +
- " gl_FragColor = texture2D(uTexture, vTexCoordinate);" +
- "}"
- private var mProgram: Int = 0
- private val vertexBuffer: FloatBuffer = ByteBuffer.allocateDirect(triangleCoords.size * 4)
- .order(ByteOrder.nativeOrder())
- .asFloatBuffer()
- .put(triangleCoords)
- .apply { position(0) }
- private val textureBuffer: FloatBuffer = ByteBuffer.allocateDirect(textureCoords.size * 4)
- .order(ByteOrder.nativeOrder())
- .asFloatBuffer()
- .put(textureCoords)
- .apply { 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 draw(mvpMatrix: FloatArray, textureHandle: Int) {
- GLES20.glUseProgram(mProgram)
- val positionHandle: Int = GLES20.glGetAttribLocation(mProgram, "vPosition")
- GLES20.glEnableVertexAttribArray(positionHandle)
- GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer)
- val mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix")
- GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
- val textureCoordinateHandle: Int = GLES20.glGetAttribLocation(mProgram, "aTexCoordinate")
- GLES20.glEnableVertexAttribArray(textureCoordinateHandle)
- GLES20.glVertexAttribPointer(textureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer)
- val textureUniformHandle: Int = GLES20.glGetUniformLocation(mProgram, "uTexture")
- GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle)
- GLES20.glUniform1i(textureUniformHandle, 0)
- GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3)
- GLES20.glDisableVertexAttribArray(positionHandle)
- GLES20.glDisableVertexAttribArray(textureCoordinateHandle)
- }
- }
- fun loadShader(type: Int, shaderCode: String): Int {
- return GLES20.glCreateShader(type).also { shader ->
- GLES20.glShaderSource(shader, shaderCode)
- GLES20.glCompileShader(shader)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement