Advertisement
Veretelnikov_VO

Veretelnikov_lab4

Apr 19th, 2024
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 8.50 KB | None | 0 0
  1. package com.example.myapplication
  2.  
  3. import android.content.Context
  4. import android.opengl.GLES20
  5. import android.opengl.GLSurfaceView
  6. import android.os.Bundle
  7. import androidx.appcompat.app.AppCompatActivity
  8. import java.nio.ByteBuffer
  9. import java.nio.ByteOrder
  10. import java.nio.FloatBuffer
  11. import javax.microedition.khronos.egl.EGLConfig
  12. import javax.microedition.khronos.opengles.GL10
  13. import android.opengl.Matrix
  14. //import android.os.SystemClock
  15. import android.view.MotionEvent
  16.  
  17. class MainActivity : AppCompatActivity() {
  18.     private lateinit var glSurfaceView: MyGLSurfaceView
  19.  
  20.     override fun onCreate(savedInstanceState: Bundle?) {
  21.         super.onCreate(savedInstanceState)
  22.         glSurfaceView = MyGLSurfaceView(this)
  23.         setContentView(glSurfaceView)
  24.     }
  25. }
  26.  
  27. private const val TOUCH_SCALE_FACTOR: Float = 180.0f / 320f
  28.  
  29. class MyGLSurfaceView(context: Context) : GLSurfaceView(context) {
  30.  
  31.     private val renderer: MyGLRenderer
  32.     private var previousX: Float = 0f
  33.     private var previousY: Float = 0f
  34.  
  35.     override fun onTouchEvent(e: MotionEvent): Boolean {
  36.         // MotionEvent reports input details from the touch screen
  37.         // and other input controls. In this case, you are only
  38.         // interested in events where the touch position changed.
  39.  
  40.         val x: Float = e.x
  41.         val y: Float = e.y
  42.  
  43.         when (e.action) {
  44.             MotionEvent.ACTION_MOVE -> {
  45.  
  46.                 var dx: Float = x - previousX
  47.                 var dy: Float = y - previousY
  48.  
  49.                 // reverse direction of rotation above the mid-line
  50.                 if (y > height / 2) {
  51.                     dx *= -1
  52.                 }
  53.  
  54.                 // reverse direction of rotation to left of the mid-line
  55.                 if (x < width / 2) {
  56.                     dy *= -1
  57.                 }
  58.  
  59.                 renderer.angle += (dx + dy) * TOUCH_SCALE_FACTOR
  60.                 requestRender()
  61.             }
  62.         }
  63.  
  64.         previousX = x
  65.         previousY = y
  66.         return true
  67.     }
  68.  
  69.     init {
  70.         setEGLContextClientVersion(2)
  71.         renderer = MyGLRenderer()
  72.         setRenderer(renderer)
  73.     }
  74. }
  75.  
  76. class MyGLRenderer : GLSurfaceView.Renderer {
  77.     private lateinit var square: Square
  78.     private lateinit var triangle: Triangle
  79.     private val vPMatrix = FloatArray(16)
  80.     private val projectionMatrix = FloatArray(16)
  81.     private val viewMatrix = FloatArray(16)
  82.     private val rotationMatrix = FloatArray(16)
  83.  
  84.     @Volatile
  85.     var angle: Float = 0f
  86.  
  87.     override fun onSurfaceCreated(unused: GL10?, config: EGLConfig?) {
  88.         GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
  89.         square = Square()
  90.         triangle = Triangle()
  91.     }
  92.  
  93.     override fun onDrawFrame(gl: GL10) {
  94.         val scratch = FloatArray(16)
  95.  
  96.         // Set the camera position (View matrix)
  97.         Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, 3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
  98.         // Calculate the projection and view transformation
  99.         Matrix.multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0)
  100.  
  101.         // Create a rotation transformation for the triangle
  102.         //val time = SystemClock.uptimeMillis() % 4000L
  103.         //val angle = 0.090f * time.toInt()
  104.         Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1.0f)
  105.  
  106.         // Combine the rotation matrix with the projection and camera view
  107.         Matrix.multiplyMM(scratch, 0, vPMatrix, 0, rotationMatrix, 0)
  108.  
  109.         GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
  110.  
  111.         square.draw(scratch)
  112.         triangle.draw(scratch)
  113.  
  114.     }
  115.  
  116.     override fun onSurfaceChanged(unused: GL10?, width: Int, height: Int) {
  117.         GLES20.glViewport(0, 0, width, height)
  118.         val ratio: Float = width.toFloat() / height.toFloat()
  119.  
  120.         // this projection matrix is applied to object coordinates
  121.         // in the onDrawFrame() method
  122.         Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
  123.     }
  124. }
  125.  
  126. class Square {
  127.     private val squareCoords = floatArrayOf(
  128.         -0.4f,  0.0f, 0.0f,   // Верхний левый угол
  129.         -0.4f, -0.8f, 0.0f,   // Нижний левый угол
  130.         0.4f, -0.8f, 0.0f,   // Нижний правый угол
  131.         0.4f,  0.0f, 0.0f    // Верхний правый угол
  132.     )
  133.  
  134.     private val vertexShaderCode =
  135.         "uniform mat4 uMVPMatrix;" +
  136.                 "attribute vec4 vPosition;" +
  137.                 "void main() {" +
  138.                 "  gl_Position = uMVPMatrix * vPosition;" +
  139.                 "}"
  140.  
  141.     private val fragmentShaderCode =
  142.         "precision mediump float;" +
  143.                 "uniform vec4 vColor;" +
  144.                 "void main() {" +
  145.                 "  gl_FragColor = vColor;" +
  146.                 "}"
  147.  
  148.     private var mProgram: Int = 0
  149.  
  150.     private val vertexBuffer: FloatBuffer = ByteBuffer.allocateDirect(squareCoords.size * 4)
  151.         .order(ByteOrder.nativeOrder())
  152.         .asFloatBuffer()
  153.         .put(squareCoords)
  154.         .apply { position(0) }
  155.  
  156.     init {
  157.         val vertexShader: Int = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
  158.         val fragmentShader: Int = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)
  159.  
  160.         mProgram = GLES20.glCreateProgram().also {
  161.             GLES20.glAttachShader(it, vertexShader)
  162.             GLES20.glAttachShader(it, fragmentShader)
  163.             GLES20.glLinkProgram(it)
  164.         }
  165.     }
  166.  
  167.     fun draw(mvpMatrix: FloatArray) {
  168.         GLES20.glUseProgram(mProgram)
  169.         val positionHandle: Int = GLES20.glGetAttribLocation(mProgram, "vPosition")
  170.         GLES20.glEnableVertexAttribArray(positionHandle)
  171.         GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer)
  172.  
  173.         val mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix")
  174.         GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
  175.  
  176.         val mColorHandle: Int = GLES20.glGetUniformLocation(mProgram, "vColor")
  177.         GLES20.glUniform4fv(mColorHandle, 1, floatArrayOf(0.63671875f, 0.76953125f, 0.22265625f, 1.0f), 0)
  178.  
  179.         GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4)
  180.  
  181.         GLES20.glDisableVertexAttribArray(positionHandle)
  182.     }
  183. }
  184.  
  185. class Triangle {
  186.     private val triangleCoords = floatArrayOf(
  187.         0.0f,  0.9f, 0.0f,  // Верхняя точка
  188.         -0.5f, 0.1f, 0.0f, // Левая нижняя точка
  189.         0.5f, 0.1f, 0.0f   // Правая нижняя точка
  190.     )
  191.  
  192.     private val vertexShaderCode =
  193.         "uniform mat4 uMVPMatrix;" +
  194.                 "attribute vec4 vPosition;" +
  195.                 "void main() {" +
  196.                 "  gl_Position = uMVPMatrix * vPosition;" +
  197.                 "}"
  198.  
  199.     private val fragmentShaderCode =
  200.         "precision mediump float;" +
  201.                 "uniform vec4 vColor;" +
  202.                 "void main() {" +
  203.                 "  gl_FragColor = vColor;" +
  204.                 "}"
  205.  
  206.     private var mProgram: Int = 0
  207.  
  208.     private val vertexBuffer: FloatBuffer = ByteBuffer.allocateDirect(triangleCoords.size * 4)
  209.         .order(ByteOrder.nativeOrder())
  210.         .asFloatBuffer()
  211.         .put(triangleCoords)
  212.         .apply { position(0) }
  213.  
  214.     init {
  215.         val vertexShader: Int = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
  216.         val fragmentShader: Int = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)
  217.  
  218.         mProgram = GLES20.glCreateProgram().also {
  219.             GLES20.glAttachShader(it, vertexShader)
  220.             GLES20.glAttachShader(it, fragmentShader)
  221.             GLES20.glLinkProgram(it)
  222.         }
  223.     }
  224.  
  225.     fun draw(mvpMatrix: FloatArray) {
  226.         GLES20.glUseProgram(mProgram)
  227.  
  228.         val positionHandle: Int = GLES20.glGetAttribLocation(mProgram, "vPosition")
  229.         GLES20.glEnableVertexAttribArray(positionHandle)
  230.         GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 12, vertexBuffer)
  231.  
  232.         val mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix")
  233.         GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
  234.  
  235.         val mColorHandle: Int = GLES20.glGetUniformLocation(mProgram, "vColor")
  236.         GLES20.glUniform4fv(mColorHandle, 1, floatArrayOf(0.63671875f, 0.76953125f, 0.22265625f, 1.0f), 0)
  237.  
  238.         GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3)
  239.  
  240.         GLES20.glDisableVertexAttribArray(positionHandle)
  241.     }
  242. }
  243.  
  244. fun loadShader(type: Int, shaderCode: String): Int {
  245.     return GLES20.glCreateShader(type).also { shader ->
  246.         GLES20.glShaderSource(shader, shaderCode)
  247.         GLES20.glCompileShader(shader)
  248.     }
  249. }
  250.  
  251.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement