Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.example.myapplication
- import android.content.Context
- import android.opengl.GLES20
- 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.os.SystemClock
- import android.view.MotionEvent
- 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()
- setRenderer(renderer)
- }
- }
- class MyGLRenderer : 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
- override fun onSurfaceCreated(unused: GL10?, config: EGLConfig?) {
- GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
- square = Square()
- triangle = Triangle()
- }
- 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)
- triangle.draw(scratch)
- }
- 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)
- }
- }
- 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 vertexShaderCode =
- "uniform mat4 uMVPMatrix;" +
- "attribute vec4 vPosition;" +
- "void main() {" +
- " gl_Position = uMVPMatrix * vPosition;" +
- "}"
- private val fragmentShaderCode =
- "precision mediump float;" +
- "uniform vec4 vColor;" +
- "void main() {" +
- " gl_FragColor = vColor;" +
- "}"
- private var mProgram: Int = 0
- private val vertexBuffer: FloatBuffer = ByteBuffer.allocateDirect(squareCoords.size * 4)
- .order(ByteOrder.nativeOrder())
- .asFloatBuffer()
- .put(squareCoords)
- .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) {
- 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 mColorHandle: Int = GLES20.glGetUniformLocation(mProgram, "vColor")
- GLES20.glUniform4fv(mColorHandle, 1, floatArrayOf(0.63671875f, 0.76953125f, 0.22265625f, 1.0f), 0)
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4)
- GLES20.glDisableVertexAttribArray(positionHandle)
- }
- }
- 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 vertexShaderCode =
- "uniform mat4 uMVPMatrix;" +
- "attribute vec4 vPosition;" +
- "void main() {" +
- " gl_Position = uMVPMatrix * vPosition;" +
- "}"
- private val fragmentShaderCode =
- "precision mediump float;" +
- "uniform vec4 vColor;" +
- "void main() {" +
- " gl_FragColor = vColor;" +
- "}"
- private var mProgram: Int = 0
- private val vertexBuffer: FloatBuffer = ByteBuffer.allocateDirect(triangleCoords.size * 4)
- .order(ByteOrder.nativeOrder())
- .asFloatBuffer()
- .put(triangleCoords)
- .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) {
- 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 mColorHandle: Int = GLES20.glGetUniformLocation(mProgram, "vColor")
- GLES20.glUniform4fv(mColorHandle, 1, floatArrayOf(0.63671875f, 0.76953125f, 0.22265625f, 1.0f), 0)
- GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3)
- GLES20.glDisableVertexAttribArray(positionHandle)
- }
- }
- 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