Advertisement
Veretelnikov_VO

Veretelnikov_lab5

Apr 19th, 2024
436
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 12.11 KB | None | 0 0
  1. package com.example.myapplication
  2.  
  3. import android.content.Context
  4. import android.graphics.Bitmap
  5. import android.graphics.BitmapFactory
  6. import android.opengl.GLES20
  7. import android.opengl.GLUtils
  8. import android.opengl.GLSurfaceView
  9. import android.os.Bundle
  10. import androidx.appcompat.app.AppCompatActivity
  11. import java.nio.ByteBuffer
  12. import java.nio.ByteOrder
  13. import java.nio.FloatBuffer
  14. import javax.microedition.khronos.egl.EGLConfig
  15. import javax.microedition.khronos.opengles.GL10
  16. import android.opengl.Matrix
  17. import android.view.MotionEvent
  18. import kotlin.math.cos
  19. import kotlin.math.sin
  20.  
  21. class MainActivity : AppCompatActivity() {
  22.     private lateinit var glSurfaceView: MyGLSurfaceView
  23.  
  24.     override fun onCreate(savedInstanceState: Bundle?) {
  25.         super.onCreate(savedInstanceState)
  26.         glSurfaceView = MyGLSurfaceView(this)
  27.         setContentView(glSurfaceView)
  28.     }
  29. }
  30.  
  31. private const val TOUCH_SCALE_FACTOR: Float = 180.0f / 320f
  32.  
  33. class MyGLSurfaceView(context: Context) : GLSurfaceView(context) {
  34.  
  35.     private val renderer: MyGLRenderer
  36.     private var previousX: Float = 0f
  37.     private var previousY: Float = 0f
  38.  
  39.     override fun onTouchEvent(e: MotionEvent): Boolean {
  40.         // MotionEvent reports input details from the touch screen
  41.         // and other input controls. In this case, you are only
  42.         // interested in events where the touch position changed.
  43.  
  44.         val x: Float = e.x
  45.         val y: Float = e.y
  46.  
  47.         when (e.action) {
  48.             MotionEvent.ACTION_MOVE -> {
  49.  
  50.                 var dx: Float = x - previousX
  51.                 var dy: Float = y - previousY
  52.  
  53.                 // reverse direction of rotation above the mid-line
  54.                 if (y > height / 2) {
  55.                     dx *= -1
  56.                 }
  57.  
  58.                 // reverse direction of rotation to left of the mid-line
  59.                 if (x < width / 2) {
  60.                     dy *= -1
  61.                 }
  62.  
  63.                 renderer.angle += (dx + dy) * TOUCH_SCALE_FACTOR
  64.                 requestRender()
  65.             }
  66.         }
  67.  
  68.         previousX = x
  69.         previousY = y
  70.         return true
  71.     }
  72.  
  73.     init {
  74.         setEGLContextClientVersion(2)
  75.         renderer = MyGLRenderer(context)
  76.         setRenderer(renderer)
  77.     }
  78. }
  79.  
  80. class MyGLRenderer(private val context: Context) : GLSurfaceView.Renderer {
  81.     private lateinit var square: Square
  82.     private lateinit var triangle: Triangle
  83.     private val vPMatrix = FloatArray(16)
  84.     private val projectionMatrix = FloatArray(16)
  85.     private val viewMatrix = FloatArray(16)
  86.     private val rotationMatrix = FloatArray(16)
  87.  
  88.     @Volatile
  89.     var angle: Float = 0f
  90.  
  91.     private var textureHandle: Int = 0
  92.  
  93.     override fun onSurfaceCreated(unused: GL10?, config: EGLConfig?) {
  94.         GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
  95.         square = Square()
  96.         triangle = Triangle()
  97.  
  98.         val resourceId = context.resources.getIdentifier("wooden", "drawable", context.packageName)
  99.         val bitmap: Bitmap = BitmapFactory.decodeResource(context.resources, resourceId)
  100.         textureHandle = loadTexture(bitmap)
  101.         bitmap.recycle()
  102.     }
  103.  
  104.     override fun onDrawFrame(gl: GL10) {
  105.         val scratch = FloatArray(16)
  106.  
  107.         // Set the camera position (View matrix)
  108.         Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, 3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
  109.         // Calculate the projection and view transformation
  110.         Matrix.multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0)
  111.  
  112.         // Create a rotation transformation for the triangle
  113.         //val time = SystemClock.uptimeMillis() % 4000L
  114.         //val angle = 0.090f * time.toInt()
  115.         Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1.0f)
  116.  
  117.         // Combine the rotation matrix with the projection and camera view
  118.         Matrix.multiplyMM(scratch, 0, vPMatrix, 0, rotationMatrix, 0)
  119.  
  120.         GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
  121.  
  122.         square.draw(scratch, textureHandle)
  123.         triangle.draw(scratch, textureHandle)
  124.  
  125.     }
  126.  
  127.     override fun onSurfaceChanged(unused: GL10?, width: Int, height: Int) {
  128.         GLES20.glViewport(0, 0, width, height)
  129.         val ratio: Float = width.toFloat() / height.toFloat()
  130.  
  131.         // this projection matrix is applied to object coordinates
  132.         // in the onDrawFrame() method
  133.         Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
  134.     }
  135.  
  136.     private fun loadTexture(bitmap: Bitmap): Int {
  137.         val textureHandle = IntArray(1)
  138.         GLES20.glGenTextures(1, textureHandle, 0)
  139.  
  140.         if (textureHandle[0] != 0) {
  141.             GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0])
  142.  
  143.             GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST)
  144.             GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST)
  145.  
  146.             GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0)
  147.  
  148.             bitmap.recycle()
  149.         }
  150.  
  151.         if (textureHandle[0] == 0) {
  152.             throw RuntimeException("Error loading texture.")
  153.         }
  154.  
  155.         return textureHandle[0]
  156.     }
  157. }
  158.  
  159. class Square {
  160.     private val squareCoords = floatArrayOf(
  161.         -0.4f,  0.0f, 0.0f,   // Верхний левый угол
  162.         -0.4f, -0.8f, 0.0f,   // Нижний левый угол
  163.         0.4f, -0.8f, 0.0f,   // Нижний правый угол
  164.         0.4f,  0.0f, 0.0f    // Верхний правый угол
  165.     )
  166.  
  167.     private val textureCoords = floatArrayOf(
  168.         0.0f, 1.0f,  // Верхний левый угол текстуры
  169.         0.0f, 0.0f,  // Нижний левый угол текстуры
  170.         1.0f, 0.0f,  // Нижний правый угол текстуры
  171.         1.0f, 1.0f   // Верхний правый угол текстуры
  172.     )
  173.  
  174.     private val vertexShaderCode =
  175.         "uniform mat4 uMVPMatrix;" +
  176.                 "attribute vec4 vPosition;" +
  177.                 "attribute vec2 aTexCoordinate;" +
  178.                 "varying vec2 vTexCoordinate;" +
  179.                 "void main() {" +
  180.                 "  gl_Position = uMVPMatrix * vPosition;" +
  181.                 "  vTexCoordinate = aTexCoordinate;" +
  182.                 "}"
  183.  
  184.     private val fragmentShaderCode =
  185.         "precision mediump float;" +
  186.                 "uniform sampler2D uTexture;" +
  187.                 "varying vec2 vTexCoordinate;" +
  188.                 "void main() {" +
  189.                 "  gl_FragColor = texture2D(uTexture, vTexCoordinate);" +
  190.                 "}"
  191.  
  192.     private var mProgram: Int = 0
  193.  
  194.     private val vertexBuffer: FloatBuffer = ByteBuffer.allocateDirect(squareCoords.size * 4)
  195.         .order(ByteOrder.nativeOrder())
  196.         .asFloatBuffer()
  197.         .put(squareCoords)
  198.         .apply { position(0) }
  199.  
  200.     private val textureBuffer: FloatBuffer = ByteBuffer.allocateDirect(textureCoords.size * 4)
  201.         .order(ByteOrder.nativeOrder())
  202.         .asFloatBuffer()
  203.         .put(textureCoords)
  204.         .apply { position(0) }
  205.  
  206.     init {
  207.         val vertexShader: Int = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
  208.         val fragmentShader: Int = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)
  209.  
  210.         mProgram = GLES20.glCreateProgram().also {
  211.             GLES20.glAttachShader(it, vertexShader)
  212.             GLES20.glAttachShader(it, fragmentShader)
  213.             GLES20.glLinkProgram(it)
  214.         }
  215.     }
  216.  
  217.     fun draw(mvpMatrix: FloatArray, textureHandle: Int) {
  218.         GLES20.glUseProgram(mProgram)
  219.  
  220.         val positionHandle: Int = GLES20.glGetAttribLocation(mProgram, "vPosition")
  221.         GLES20.glEnableVertexAttribArray(positionHandle)
  222.         GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer)
  223.  
  224.         val mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix")
  225.         GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
  226.  
  227.         val textureCoordinateHandle: Int = GLES20.glGetAttribLocation(mProgram, "aTexCoordinate")
  228.         GLES20.glEnableVertexAttribArray(textureCoordinateHandle)
  229.         GLES20.glVertexAttribPointer(textureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer)
  230.  
  231.         val textureUniformHandle: Int = GLES20.glGetUniformLocation(mProgram, "uTexture")
  232.         GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
  233.         GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle)
  234.         GLES20.glUniform1i(textureUniformHandle, 0)
  235.  
  236.         GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4)
  237.  
  238.         GLES20.glDisableVertexAttribArray(positionHandle)
  239.         GLES20.glDisableVertexAttribArray(textureCoordinateHandle)
  240.     }
  241. }
  242.  
  243. class Triangle {
  244.     private val triangleCoords = floatArrayOf(
  245.         0.0f,  0.9f, 0.0f,  // Верхняя точка
  246.         -0.5f, 0.1f, 0.0f, // Левая нижняя точка
  247.         0.5f, 0.1f, 0.0f   // Правая нижняя точка
  248.     )
  249.  
  250.     private val textureCoords = floatArrayOf(
  251.         0.5f, 0.0f,  // Верхняя точка текстуры
  252.         0.0f, 1.0f,  // Левая нижняя точка текстуры
  253.         1.0f, 1.0f   // Правая нижняя точка текстуры
  254.     )
  255.  
  256.     private val vertexShaderCode =
  257.         "uniform mat4 uMVPMatrix;" +
  258.                 "attribute vec4 vPosition;" +
  259.                 "attribute vec2 aTexCoordinate;" +
  260.                 "varying vec2 vTexCoordinate;" +
  261.                 "void main() {" +
  262.                 "  gl_Position = uMVPMatrix * vPosition;" +
  263.                 "  vTexCoordinate = aTexCoordinate;" +
  264.                 "}"
  265.  
  266.     private val fragmentShaderCode =
  267.         "precision mediump float;" +
  268.                 "uniform sampler2D uTexture;" +
  269.                 "varying vec2 vTexCoordinate;" +
  270.                 "void main() {" +
  271.                 "  gl_FragColor = texture2D(uTexture, vTexCoordinate);" +
  272.                 "}"
  273.  
  274.     private var mProgram: Int = 0
  275.  
  276.     private val vertexBuffer: FloatBuffer = ByteBuffer.allocateDirect(triangleCoords.size * 4)
  277.         .order(ByteOrder.nativeOrder())
  278.         .asFloatBuffer()
  279.         .put(triangleCoords)
  280.         .apply { position(0) }
  281.  
  282.     private val textureBuffer: FloatBuffer = ByteBuffer.allocateDirect(textureCoords.size * 4)
  283.         .order(ByteOrder.nativeOrder())
  284.         .asFloatBuffer()
  285.         .put(textureCoords)
  286.         .apply { position(0) }
  287.  
  288.     init {
  289.         val vertexShader: Int = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
  290.         val fragmentShader: Int = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)
  291.  
  292.         mProgram = GLES20.glCreateProgram().also {
  293.             GLES20.glAttachShader(it, vertexShader)
  294.             GLES20.glAttachShader(it, fragmentShader)
  295.             GLES20.glLinkProgram(it)
  296.         }
  297.     }
  298.  
  299.     fun draw(mvpMatrix: FloatArray, textureHandle: Int) {
  300.         GLES20.glUseProgram(mProgram)
  301.  
  302.         val positionHandle: Int = GLES20.glGetAttribLocation(mProgram, "vPosition")
  303.         GLES20.glEnableVertexAttribArray(positionHandle)
  304.         GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer)
  305.  
  306.         val mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix")
  307.         GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
  308.  
  309.         val textureCoordinateHandle: Int = GLES20.glGetAttribLocation(mProgram, "aTexCoordinate")
  310.         GLES20.glEnableVertexAttribArray(textureCoordinateHandle)
  311.         GLES20.glVertexAttribPointer(textureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer)
  312.  
  313.         val textureUniformHandle: Int = GLES20.glGetUniformLocation(mProgram, "uTexture")
  314.         GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
  315.         GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle)
  316.         GLES20.glUniform1i(textureUniformHandle, 0)
  317.  
  318.         GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3)
  319.  
  320.         GLES20.glDisableVertexAttribArray(positionHandle)
  321.         GLES20.glDisableVertexAttribArray(textureCoordinateHandle)
  322.     }
  323. }
  324.  
  325. fun loadShader(type: Int, shaderCode: String): Int {
  326.     return GLES20.glCreateShader(type).also { shader ->
  327.         GLES20.glShaderSource(shader, shaderCode)
  328.         GLES20.glCompileShader(shader)
  329.     }
  330. }
  331.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement