{"id":296010,"date":"2019-12-18T15:00:55","date_gmt":"2019-12-18T15:00:55","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=296010"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=296010","title":{"rendered":"Android. Surface"},"content":{"rendered":"\n<div class=\"post__text post__text-html js-mediator-article\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/480878\/\">\n<h2 id=\"diskleymer\">\u0414\u0438\u0441\u043a\u043b\u0435\u0439\u043c\u0435\u0440<\/h2>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0434\u043b\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0445 \u0430\u043d\u0434\u0440\u043e\u0438\u0434 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0432\u0438\u0434\u0435\u043e \u0438\/\u0438\u043b\u0438 \u043a\u0430\u043c\u0435\u0440\u043e\u0439, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0442\u0435\u0445 \u043a\u0442\u043e \u043d\u0430\u0447\u0430\u043b \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u044b <a href=\"https:\/\/github.com\/google\/grafika\" rel=\"nofollow\">grafika<\/a> \u0438 \u043a\u043e\u043c\u0443 \u043e\u043d\u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u043c\u0438 \u2014 \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u043f\u043e\u0445\u043e\u0436\u0438\u0439 \u043a\u043e\u0434 \u0441 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u044b\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0448\u0430\u0433\u043e\u0432, \u043f\u0440\u043e\u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439. <\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435 \u0432\u044b\u043d\u0435\u0441\u0435\u043d \u043a\u043b\u0430\u0441\u0441 Surface? \u0412 android \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0438\u043c\u0435\u044e\u0442 \u0432 \u0441\u0432\u043e\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438 \u0441\u043b\u043e\u0432\u043e <em>Surface<\/em> (Surface, SurfaceHolder, SurfaceTexture, SurfaceView, GLSurfaceView) \u043e\u043d\u0438 \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u043e\u0431\u0449\u0435\u0439 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0435\u0439 \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0432\u044b\u0432\u043e\u0434 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u041c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u0437\u0443\u043c\u043d\u044b\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0447\u0435\u0440\u043a\u043d\u0443\u0442\u044c \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u0441 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e SDK.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"primer-ispolzovaniya-s-raznym-api\">\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441 \u0440\u0430\u0437\u043d\u044b\u043c API<\/h2>\n<p>  <\/p>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440: <strong>\u0431\u0443\u0434\u0435\u043c \u0431\u0440\u0430\u0442\u044c preview \u0441 \u043a\u0430\u043c\u0435\u0440\u044b, \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u043d\u0435\u0433\u043e \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 drawable, \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u044d\u0442\u043e \u0432\u0441\u0435 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0438 \u043f\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432 \u0444\u0430\u0439\u043b.<\/strong> \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0436\u0430\u0442\u044c <a href=\"https:\/\/github.com\/tttzof351\/AndroidSurfaceExample\/\" rel=\"nofollow\">https:\/\/github.com\/tttzof351\/AndroidSurfaceExample\/<\/a><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u044b \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f <a href=\"https:\/\/developer.android.com\/reference\/android\/opengl\/GLSurfaceView\" rel=\"nofollow\">GLSurfaceView<\/a>, \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 <a href=\"https:\/\/developer.android.com\/reference\/android\/media\/MediaCodec\" rel=\"nofollow\">MediaCodec<\/a> \u0438 <a href=\"https:\/\/developer.android.com\/reference\/android\/opengl\/EGLSurface\" rel=\"nofollow\">EGLSurface<\/a>, \u0430 \u0441 \u043a\u0430\u043c\u0435\u0440\u043e\u0439 \u043e\u0431\u0449\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/developer.android.com\/reference\/android\/hardware\/camera2\/package-summary\" rel=\"nofollow\">API V2<\/a>. \u041e\u0431\u0449\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/9o\/rc\/o5\/9orco54m0chpg_og4db_qppsrjm.png\"><\/p>\n<p>  <\/p>\n<h2 id=\"nalozhenie-neskolkih-surface\">\u041d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 Surface<\/h2>\n<p>  <\/p>\n<p>Surface \u2014 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c. \u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0435\u0433\u043e \u043f\u044b\u0442\u0430\u044f\u0441\u044c \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0447\u0442\u043e \u0442\u043e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0438\u043b\u0438 \u0432 \u0444\u0430\u0439\u043b, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0431\u0443\u0444\u0435\u0440 \u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u201c\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u201d \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 Surface \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f OpenGL.<br \/>  \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0432\u0435 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0435 external-\u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0438\u0437 \u043d\u0438\u0445 Surface-\u044b <\/p>\n<p>  <\/p>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u0430\u043a \u0442\u043e \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/tttzof351\/AndroidSurfaceExample\/blob\/881270636942f695427f6f5a283580417798336b\/app\/src\/main\/java\/com\/example\/surfaces\/helpers\/OpenGLExternalTexture.kt#L43\" rel=\"nofollow\">OpenGLExtarnalTexture.kt<\/a><\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">val textures = IntArray(1) GLES20.glGenTextures(1, textures, 0) val textureId = textures[0] \/\/\u041a\u0430\u043a \u0442\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u044b val textureWidth = ... val textureHeight = ... \/\/\u041f\u0440\u043e\u0441\u043b\u043e\u0439\u043a\u0430 \u043c\u0435\u0436\u0434\u0443  val surfaceTexture = SurfaceTexture(textureId) surfaceTexture.setDefaultBufferSize(textureWidth, textureHeight) \/\/\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, surface \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \"\u0441\u0432\u044f\u0437\u0430\u043d\" \u0441 \u043d\u0430\u0448\u0435\u0439 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u043e\u0439 val surface = Surface(surfaceTexture)<\/code><\/pre>\n<p>  <\/p>\n<p><strong>XYZ \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b<\/strong><\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b, \u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043d\u0430\u044f \u0441\u0435\u0442\u043a\u0430 \u0432 OpenGL: \u0435\u0435 \u0446\u0435\u043d\u0442\u0440 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u0446\u0435\u043d\u0442\u0440\u043e\u043c \u0441\u0446\u0435\u043d\u044b (\u043e\u043a\u043d\u0430), \u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0442.\u0435 \u043e\u0442 -1 \u0434\u043e 1. <\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u0439 \u0441\u0446\u0435\u043d\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0437\u0430\u0434\u0430\u0442\u044c \u0434\u0432\u0430 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430 (\u0440\u0430\u0431\u043e\u0442\u0430 \u0438\u0434\u0435\u0442 \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435 z \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u0432 0f) \u2014 \u043a\u0440\u0430\u0441\u043d\u044b\u043c \u043c\u044b \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u043c \u0442\u043e\u0442 \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043c\u0435\u0449\u0430\u0442\u044c preview \u0434\u043b\u044f \u043a\u0430\u043c\u0435\u0440\u044b, \u0430 \u0441\u0438\u043d\u0438\u043c \u0434\u043b\u044f \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e drawable-\u0430:<\/p>\n<p>  <\/p>\n<p>\u0412\u044b\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0448\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u044f\u0432\u043d\u043e:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/mu\/fj\/kr\/mufjkrznafatofs4lsn-ywm_h7i.png\"><\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">fullscreenTexture = floatArrayOf(    \/\/ X,     Y,     Z      -1.0f,  -1.0f,  0.0f,     1.0f,  -1.0f,  0.0f,    -1.0f,   1.0f,  0.0f,     1.0f,   1.0f,  0.0f, ) smallTexture = floatArrayOf(    \/\/ X,      Y,    Z     0.3f,   0.3f,  0.0f,     0.8f,   0.3f,  0.0f,     0.3f,   0.8f,  0.0f,     0.8f,   0.8f,  0.0f )<\/code><\/pre>\n<p>  <\/p>\n<p><strong>UV \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043b\u0438 \u044d\u0442\u043e\u0433\u043e? \u041e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043d\u0435\u0442 \ud83d\ude41<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043a\u0441\u0442\u0443\u0440\u0430 \u044d\u0442\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u043d\u0430 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0441\u0446\u0435\u043d\u044b \u0438 \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043a\u0430\u043a\u043e\u0435 \u0442\u043e\u0447\u043d\u043e \u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0447\u043a\u0438 \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435 \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u2014 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 OpenGL \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f <strong>UV<\/strong> \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u2014 \u043e\u043d\u0438 \u0432\u044b\u0445\u043e\u0434\u044f\u0442 \u0438\u0437 \u043b\u0435\u0432\u043e\u0433\u043e \u043d\u0438\u0436\u043d\u0435\u0433\u043e \u0443\u0433\u043b\u0430 \u0438 \u0438\u043c\u0435\u044e\u0442 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0442 0 \u0434\u043e 1 \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043e\u0441\u0435\u0439. <\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u044d\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u2014 \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0440\u0448\u0438\u043d\u0435 \u043d\u0430\u0448\u0435\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043c\u044b \u0437\u0430\u0434\u0430\u0434\u0438\u043c <strong>UV<\/strong> \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0442\u043e\u0447\u043a\u0438 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438, \u0441\u0447\u0438\u0442\u0430\u044f \u0447\u0442\u043e \u0442\u0430\u043c \u0448\u0438\u0440\u0438\u043d\u0430 \u0438 \u0432\u044b\u0441\u043e\u0442\u0430 \u0440\u0430\u0432\u043d\u044b \u043f\u043e 1.<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u2014 \u0431\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0447\u0442\u043e \u043a\u0430\u043c\u0435\u0440\u0430 \u043e\u0442\u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0442\u043e\u043c \u0438 \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0430\u0432\u0443\u044e-\u0432\u0435\u0440\u0445\u043d\u044e\u044e \u0447\u0430\u0441\u0442\u044c \u0442.\u0435 \u0432\u0437\u044f\u0442\u044c 0.8 \u043f\u043e \u0448\u0438\u0440\u043e\u0442\u044b \u0438 \u0432\u044b\u0441\u043e\u0442\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0422\u043e\u043d\u043a\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u2014 \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u043e\u043d \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u2014 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0432\u0430\u0434\u0440\u0430\u0442 \u0432 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442 \u0441\u043e\u0431\u043e\u0439 \u0432\u0441\u044e \u0441\u0446\u0435\u043d\u0443 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0430\u0441\u0442\u044f\u043d\u0435\u0442\u0441\u044f. \u0415\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0434\u0435\u043b\u0430\u043b\u0438 fullscreen \u043a\u0430\u043c\u0435\u0440\u0443 \u0442\u043e \u043d\u0430\u0448\u0438 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u044b (2 \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435) \u0440\u0430\u0441\u0442\u044f\u043d\u0443\u043b\u0438\u0441\u044c \u0431\u044b \u0434\u043e \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0445 1080&#215;1920. \u0411\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0447\u0442\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0441\u0446\u0435\u043d\u044b \u043c\u044b \u0437\u0430\u0434\u0430\u0434\u0438\u043c \u0442\u0430\u043a\u0438\u0435 \u0447\u0442\u043e \u0438\u0445 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0432\u043d\u043e \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u043a\u0430\u043c\u0435\u0440\u044b.<br \/>  \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0443\u0434\u0430 \u043f\u0435\u0440\u0435\u0439\u0434\u0443\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u2014 \u043f\u0440\u0430\u0432\u0430\u044f \u0432\u0435\u0440\u0445\u043d\u044f\u044f \u0442\u043e\u0447\u043a\u0430 \u043d\u0430\u0448\u0435\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 (1, 1, 0) \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 UV \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0443 (0, 0), \u043b\u0435\u0432\u0430\u044f \u043d\u0438\u0436\u043d\u044f\u044f \u0432 (0.8f, 0.8f) \u0438 \u0442. \u0434<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/fk\/ur\/ig\/fkurigpfo4l_hnl1fonbgj1dao0.png\"><\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 XYZ \u0438 UV:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">\/\/ X,     Y,     Z,     U,     V -1.0f,  -1.0f,  0.0f,  0.8f, 0.8f,  1.0f,  -1.0f,  0.0f,  0.8f, 0.0f, -1.0f,   1.0f,  0.0f,  0.0f, 0.8f,  1.0f,   1.0f,  0.0f,  0.0f, 0.0f<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0441\u0442\u043e\u0440\u043e\u043d \u043c\u0435\u0436\u0434\u0443 preview \u0441 \u043a\u0430\u043c\u0435\u0440\u044b \u0438 \u043e\u0431\u043b\u0430\u0441\u0442\u044c\u044e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u043b\u043e \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0442\u043e \u043e\u043d\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0442.\u043a \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0438 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u043c\u043d\u043e\u0436\u0438\u043b\u0438 \u043d\u0430 0.8f.<br \/>  \u0410 \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0435\u0441\u0442\u044c \u043c\u044b \u0437\u0430\u0434\u0430\u0434\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0435 1? \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 OpenGL-\u0443 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u043e\u0447\u043a\u0438 \u043a\u0430\u043a\u043e\u0439 \u0442\u043e \u0447\u0430\u0441\u0442\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043b\u0438\u043d\u0438\u044f \u043f\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043e\u0441\u0438 \u0438 \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0432 \u0432\u0438\u0434\u0435 \u201c\u043f\u043e\u043b\u043e\u0441\u043e\u043a\u201d<\/p>\n<p>  <\/p>\n<p><strong>\u0418\u0442\u043e\u0433: \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0441\u0436\u0430\u0442\u044c\/\u0432\u044b\u0440\u0435\u0437\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u0442\u043e UV \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0430\u0448 \u0432\u044b\u0431\u043e\u0440!<\/strong><\/p>\n<p>  <\/p>\n<p><strong>\u0417\u0430\u0434\u0430\u0434\u0438\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u0442\u0435\u043a\u0441\u0442\u0443\u0440<\/strong><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/au\/wp\/zx\/auwpzx9wgczhb79_4bbfu9nyk_a.png\"><\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">fullscreenTexture = floatArrayOf(   \/\/ X,   Y,      Z,      U,  V    -1.0f,  -1.0f,  0.0f,  1f, 0f,     1.0f,  -1.0f,  0.0f,  0f, 0f,    -1.0f,   1.0f,  0.0f,  1f, 1f,     1.0f,   1.0f,  0.0f,  0f, 1f ) smallTexture = floatArrayOf(   \/\/ X,   Y,      Z,      U,  V     0.3f,   0.3f,  0.0f,  0f, 0f,     0.8f,   0.3f,  0.0f,  1f, 0f,     0.3f,   0.8f,  0.0f,  0f, 1f,     0.8f,   0.8f,  0.0f,  1f, 1f )<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0428\u0435\u0439\u0434\u0435\u0440\u044b<\/strong><\/p>\n<p>  <\/p>\n<p>\u0418\u043c\u0435\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0435 XYZ \u0438 UV-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u2014 \u043c\u044b \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0445\u043e\u0442\u0435\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0436\u0435\u0441\u0442\u0430\u043c\u0438 \u043d\u0430\u0448\u0438 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b. \u0427\u0442\u043e\u0431\u044b \u0438\u0445 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0432\u0435\u0434\u0435\u043c \u0434\u0432\u0435 \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b: <strong>MVPMatrix<\/strong> \u0438 <strong>TexMatrix<\/strong> \u0434\u043b\u044f \u0434\u043b\u044f XYZ \u0438 UV \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. <\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u0430\u044f OpenGL2 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0448\u0435\u0439\u0434\u0435\u0440\u044b \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043c \u0442\u0435\u043c\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044c \u0432 \u043e\u0434\u043d\u043e\u043c \u0430\u0431\u0437\u0430\u0446\u0435, \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u043c\u0438, \u0430 \u043f\u043e\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0447\u0442\u043e \u043e\u043d\u0438 \u0447\u0442\u043e \u043e\u043d\u0438 \u0434\u0435\u043b\u0430\u044e\u0442, \u0431\u0435\u0437 \u043e\u0441\u043e\u0431\u043e\u0433\u043e \u0437\u043d\u0430\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430. <\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u0434\u0432\u0430 \u2014 vertex \u0438 fragment. <\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 (vertex) \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0448\u0438 \u0432\u0435\u0440\u0448\u0438\u043d\u044b, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u043d\u043e\u0436\u0430\u0442\u044c \u043d\u0430\u0448\u0438 XYZ \/ UV \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u0438\u043c \u043c\u0430\u0442\u0440\u0438\u0446\u0430\u043c\u0438 \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c OpenGL \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <strong>gl_Position<\/strong> \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u0430\u043a \u0440\u0430\u0437 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0439 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435. <\/p>\n<p>  <\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 (fragment) \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c <strong>gl_FragColor<\/strong> \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u043c\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0418\u0442\u043e\u0433\u043e \u0438\u043c\u0435\u0435\u043c: \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 vertex \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u043e\u043b\u044f \u043d\u0430\u0448\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e:<\/p>\n<p>  <\/p>\n<ul>\n<li>MVPMatrix -&gt; <strong>uMVPMatrix<\/strong><\/li>\n<li><strong>TexMatrix -&gt; uTexMatrix<\/strong><\/li>\n<li>\u043d\u0430\u0448\u0438 XYZ \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0435\u0440\u0448\u0438\u043d\u044b -&gt; <strong>aPosition<\/strong><\/li>\n<li>UV \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b -&gt; <strong>aTextureCoord<\/strong><\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>vTextureCoord<\/strong> \u2014 \u043d\u0443\u0436\u043d\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 vertex \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u0432 fragment \u0448\u0435\u0439\u0434\u0435\u0440<br \/>  \u0412 fragment \u0448\u0435\u0439\u0434\u0435\u0440\u0435 \u043c\u044b \u0431\u0435\u0440\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 UV \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u0445 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">val vertexShader = \"\"\"    uniform mat4 uMVPMatrix;    uniform mat4 uTexMatrix;    attribute vec4 aPosition;    attribute vec4 aTextureCoord;    varying vec2 vTextureCoord;    void main() {        gl_Position = uMVPMatrix * aPosition;        vTextureCoord = (uTexMatrix * aTextureCoord).xy;    } \"\"\" val fragmentShader = \"\"\"    #extension GL_OES_EGL_image_external : require    precision mediump float;    varying vec2 vTextureCoord;    uniform samplerExternalOES sTexture;    void main() {        gl_FragColor = texture2D(sTexture, vTextureCoord);    } \"\"\"<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0430\u0434\u0438 \u0441\u043f\u0440\u0430\u0432\u043a\u0438 \u0443\u043a\u0430\u0436\u0435\u043c \u0447\u0435\u043c \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u0442\u0438\u043f\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li>uniform \u2014 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u0434\u0438\u043d \u0448\u0435\u0439\u0434\u0435\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0434\u0432\u0443\u0445 \u0442\u0435\u043a\u0441\u0442\u0443\u0440, \u0442\u0430\u043a \u0447\u0442\u043e \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438<\/li>\n<li>attribute \u2014 \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0430\u043a\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u0432\u0435\u0440\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430, \u0438\u0445 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438<\/li>\n<li>varying \u2014 \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 vertex \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u0432 fragment<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432 \u0448\u0435\u0439\u0434\u0435\u0440? \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c id (\u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c) \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">val aPositionHandle = GLES20.glGetAttribLocation(programId, \"aPosition\")<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e \u044d\u0442\u043e\u043c\u0443 id \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">\/\/\u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043c \u043d\u0430\u0448 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u0435\u0440\u0448\u0438\u043d \u0432\u043e floatbuffer val verticesBuffer = ByteBuffer.allocateDirect(     fullscreenTexture.size * FLOAT_SIZE_BYTES ).order(     ByteOrder.nativeOrder() ).asFloatBuffer() verticesBuffer.put(fullscreenTexture).position(0) \/* \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 - \u0434\u043b\u044f XYZ \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 0 \u0442.\u043a \u043e\u043d\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0417\u0430\u0442\u0435\u043c\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c id \u043d\u0430\u0448\u0435\u0433\u043e \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u0430 \u043a\u0443\u0434\u0430 \u043c\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435, \u0443\u043a\u0430\u0437\u0430\u0432 \u0441\u043a\u043e\u043b\u044c\u043a\u043e  \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0431\u0440\u0430\u0442\u044c, \u0438 \u043a\u0430\u043a\u043e\u0435 \u0442\u043e \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432 \u0431\u0430\u0439\u0442\u0430\u0445 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0442\u0435\u043c \u0441\u043e\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0432\u0435\u0440\u0448\u0443\u043d\u044b - 5 \u044d\u0442\u043e \u043a\u043e\u043b-\u0432\u043e XYZUV, \u0430 4 - \u043a\u043e\u043b-\u0432\u043e \u0431\u0430\u0439\u0442 \u0432\u043e float *\/ verticesBuffer.position(0) GLES20.glVertexAttribPointer(     aPositionHandle,     3,     GLES20.GL_FLOAT,     false,     5 * 4,     verticesBuffer )<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430<\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043c\u044b \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043b\u0438 \u043d\u0430\u0448\u0438 \u0448\u0435\u0439\u0434\u0435\u0440\u044b \u0432\u0441\u0435\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0430 OpenGL \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0432\u0435\u0440\u0448\u0438\u043d\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">fun updateFrame(...) {     ...     surfaceTexture.updateTexImage()     GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4) } <\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u044c\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 OpenGL \u0441\u0446\u0435\u043d\u043e\u0439 \u043d\u0430 \u0434\u0432\u0430 \u043a\u043b\u0430\u0441\u0441\u044b \u2014 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u0446\u0435\u043d\u044b \u0438 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b: <\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/tttzof351\/AndroidSurfaceExample\/blob\/master\/app\/src\/main\/java\/com\/example\/surfaces\/helpers\/OpenGLExternalTexture.kt\/\" rel=\"nofollow\">OpenGLExternalTexture.kt<\/a><\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">class OpenGLExternalTexture(verticesData: FloatArray, ...) {     val surfaceTexture: SurfaceTexture     val surface: Surface     init {         \/\/\u041f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043c\u0430\u0442\u0440\u0438\u0446\u044b, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443 \u0438 \u0442.\u0434     }     ...     fun updateFrame(aPositionHandle: Int, ...) {...} \/\/\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435, \u043e\u0442\u0440\u0438\u0441\u0443\u0435\u043c \u043a\u0430\u0434\u0440     fun release() {...} \/\/ \u043e\u0442\u0447\u0438\u0441\u0442\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/tttzof351\/AndroidSurfaceExample\/blob\/master\/app\/src\/main\/java\/com\/example\/surfaces\/helpers\/OpenGLScene.kt\" rel=\"nofollow\">OpenGLScene.kt<\/a><\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">class OpenGLScene(     sceneWidth: Int,     sceneHeight: Int,     ... ) {     val fullscreenTexture = OpenGLExternalTexture(...)     val smallTexture = OpenGLExternalTexture(..)      val aPositionHandle: Int      ...     init {       \/\/\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0448\u0435\u0439\u0434\u0435\u0440\u044b, \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0432\u0441\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0430\u043b\u0438 \u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u0438 \u0442.\u0434     }     fun updateFrame() {         ...         fullscreenTexture.updateFrame(aPositionHandle, ...)         smallTexture.updateFrame(aPositionHandle, ...)     }     fun release() {         fullscreenTexture.release()         smallTexture.release()             } }<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"statemachine--mashina-sostoyaniy--konechnyy-avtomat\">StateMachine \/ \u041c\u0430\u0448\u0438\u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \/ \u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442<\/h2>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 API \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 (\u043d\u0443 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e Drawable-\u0430). \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 StateMachine-\u044b \u2014 \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u043a\u043e\u0433\u0434\u0430 \u044f\u0432\u043d\u043e \u0432\u044b\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u0447\u0435\u0440\u0435\u0437 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439.<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">imageView.setOnClickListener {     loadImage { bitmap -&gt;          imageView.setBitmap(bitmap)     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c \u0432\u0441\u0435 \u0445\u043e\u0440\u043e\u0448\u043e \u2014 \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u0438 \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u043e, \u043d\u043e \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">val uiMachine = UIMachine() imageView.setOnClickListener { uiMachine.send(Click(imageView)) } class UIMachine {     var state: State = WaitClick()     fun send(action: Action) = transition(action)     private fun transition(action: Action) {         val state = this.state         when {             state is WaitingClick &amp;&amp; action is Click -&gt; {                 this.state = WaitBitmap(imageView = action.imageView)                 loadImage { send(BitmapIsReady(bitmap = it)) }             }             state is WaitingBitmap &amp;&amp; action is BitmapIsReady -&gt; {                 this.state = WaitClick                 state.imageView.setImageBitmap(action.bitmap)             }         }     } }  sealed class State {     object WaitingClick : State()     class WaitingBitmap(val imageView: ImageView): State() } sealed class Action {     class Click(val imageView: ImageView): Action()     class BitmapIsReady(val bitmap: Bitmap): Action() }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c <strong><em>\u0441\u0438\u043b\u044c\u043d\u043e<\/em><\/strong> \u0431\u043e\u043b\u044c\u0448\u0435, \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u044f\u0432\u043d\u044b\u0445, \u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432: \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043b\u0438\u0448\u043d\u0438\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043c <strong>loadImage,<\/strong> \u0445\u043e\u0442\u044f \u0438 \u043d\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u0441 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u044a\u0435\u043c\u043e\u043c, \u043d\u043e \u043c\u044b \u0438\u0437\u0431\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u043e\u0442 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u043a\u043e\u043b\u0431\u0435\u043a\u043e\u0432, \u0447\u0435\u043c \u0438 \u0431\u0443\u0434\u0435\u043c \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0430 \u0435\u0449\u0435 \u0441\u0442\u0438\u043b\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u0430 transition \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0443 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0434\u0438\u043d \u0432 \u043e\u0434\u0438\u043d \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442 \u043a\u043e\u0434 \u0442.\u0435 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0438:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/-n\/2p\/mq\/-n2pmqdwfsps932me0wfsrvyj_q.png\"><br \/>  \u0421\u0435\u0440\u044b\u043c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0432\u044b\u043f\u0438\u0441\u0430\u043d\u044b \u044f\u0432\u043d\u043e. \u0427\u0430\u0441\u0442\u043e \u0438\u0445 \u043b\u043e\u0433\u0438\u0440\u0443\u044e\u0442 \u0438\u043b\u0438 \u043a\u0438\u0434\u0430\u044e\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0441\u0447\u0438\u0442\u0430\u044f \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u043c \u043e\u0448\u0438\u0431\u043a\u0438. \u041c\u044b \u043f\u043e\u043a\u0430 \u043e\u0431\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u0445\u0435\u043c\u0430\u0445.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u0434\u043b\u044f StateMachine:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">interface Action interface State interface StateMachine&lt;S : State, A : Action&gt; {     var state: S     fun transition(action: A)     fun send(action: A) }<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"glsurfaceview\">GLSurfaceView<\/h2>\n<p>  <\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f OpenGL \u0432 android \u044d\u0442\u043e \u043a\u043b\u0430\u0441\u0441 GLSurfaceView \u2014 \u043e\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0435 \u043f\u043e\u0442\u043e\u043a \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f, \u0437\u0430\u043f\u0443\u0441\u043a\/\u043f\u0430\u0443\u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u043c\u0435\u0442\u043e\u0434\u0430\u043c GLSurfaceView::onResume\/onPause.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0435\u0439 \u0432\u044c\u044e\u0445\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 16:9<\/p>\n<p>  <\/p>\n<p>\u0421\u0430\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0432\u044b\u043d\u0435\u0441\u0435\u043d \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043b\u0431\u0435\u043a \u2014 GLSurfaceView.Renderer.<br \/>  \u0417\u0430\u0432\u0435\u0440\u043d\u0443\u0432 \u0435\u0433\u043e \u0432 StateMachine-\u0443 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0447\u0442\u043e \u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u044d\u0442\u043e\u0433\u043e:<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/tttzof351\/AndroidSurfaceExample\/blob\/master\/app\/src\/main\/java\/com\/example\/surfaces\/machines\/GLSurfaceMachine.kt\" rel=\"nofollow\">GLSurfaceMachine.kt<\/a><\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">class GLSurfaceMachine: StateMachine&lt;GLSurfaceState, GLSurfaceAction&gt; {     override var state: GLSurfaceState = WaitCreate()     override fun send(action: GLSurfaceAction) = transition(action)     override fun transition(action: GLSurfaceAction) {         val state = this.state         when {             state is WaitCreate &amp;&amp; action is Create -&gt; {                 this.state = WaitSurfaceReady(...)                 this.state.glSurfaceView?.setRenderer(object :Renderer {                     override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int)                         send(SurfaceReady(width, height, gl))                     }                     override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {                     }                     override fun onDrawFrame(gl: GL10?) {                         send(Draw)                     }                 })                       }             state is WaitSurfaceReady &amp;&amp; action is SurfaceReady -&gt; {                             val openGLScene = OpenGLScene(width, height)                 this.state = DrawingAvailable(openGLScene, ...)             }             state is DrawingAvailable &amp;&amp; action is Draw -&gt; {                 state.openGLScene.updateFrame()             }             state !is WaitCreate &amp;&amp; action is Stop -&gt; {                 state.uiHolder.glSurfaceView?.onPause()                 state.uiHolder.openGLScene?.release()                 this.state = WaitSurfaceReady()             }              state is WaitSurfaceReady &amp;&amp; action is Start -&gt; {               state.uiHolder.glSurfaceView?.onResume()             }                    }     } } ... val glSurfaceMachine = GLSurfaceMachine() val glSurfaceView = findViewById(R.id.gl_view) glSurfaceView.layoutParams.width = width glSurfaceView.layoutParams.height = ((16f\/9f) * width).toInt() glSurfaceMachine.send(GLSurfaceAction.Create(glSurfaceView, ...))<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0440\u0438\u0441\u0443\u0435\u043c \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0443 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/mx\/5i\/xb\/mx5ixbssfaqci1ktsmumu94jbz0.png\"><\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0448 \u043a\u043e\u0434 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0447\u0442\u043e \u0442\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d, \u043f\u0440\u0430\u0432\u0434\u0430 \u043f\u043e\u043a\u0430 \u0443 \u043d\u0435\u0433\u043e \u044d\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043f\u043b\u043e\u0445\u043e \u2014 \u043d\u0438 \u0447\u0435\u0433\u043e \u043a\u0440\u043e\u043c\u0435 \u0447\u0435\u0440\u043d\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430 \u043c\u044b \u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u043c. \u041a\u0430\u043a \u043d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f \u0434\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u043d\u0430\u0448\u0438 Surface-\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0438 \u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0442.\u043a \u043c\u044b \u043f\u043e\u043a\u0430 \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c \u2014 \u043f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c CanvasDrawable:<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/tttzof351\/AndroidSurfaceExample\/blob\/master\/app\/src\/main\/java\/com\/example\/surfaces\/CanvasDrawable.kt\" rel=\"nofollow\">CanvasDrawable.kt<\/a><\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">class CanvasDrawable : Drawable() {     private val backgroundPaint = Paint().apply { ... }     private val circlePaint = Paint().apply { ... }     override fun draw(canvas: Canvas) {         canvas.drawRect(bounds, backgroundPaint)         val width = bounds.width()         val height = bounds.height()         val posX = ...         val posY = ...         canvas.drawCircle(posX, posY, 0.1f * width, circlePaint)     }     ... }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0435\u043a\u0446\u0438\u044e \u0432 GLSurfaceMachine \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u043e\u0439 canvasDrawable \u043d\u0430 canvas-\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 surface \u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">state is DrawingAvailable &amp;&amp; action is Draw -&gt; {   val canvasDrawable = state.canvasDrawable   val smallTexture = state.openGLScene.smallTexture   val bounds = canvasDrawable.bounds   val canvas = smallSurface.lockCanvas(bounds)   canvasDrawable.draw(canvas)   smallSurface.unlockCanvasAndPost(canvas)   state.openGLScene.updateFrame() }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0443\u0432\u0438\u0434\u0438\u043c \u0447\u0442\u043e \u0442\u043e \u043d\u0430\u043f\u043e\u0434\u043e\u0431\u0438\u0435:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/vo\/4r\/-d\/vo4r-dgpynjvynvxdomy2fezp9y.png\"><\/p>\n<p>  <\/p>\n<h2 id=\"camera-api-v2\">Camera API V2<\/h2>\n<p>  <\/p>\n<p>\u0417\u0435\u043b\u0435\u043d\u044b\u0439 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u044d\u0442\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0432\u0435\u0441\u0435\u043b\u043e \u0438 \u0438\u043d\u0442\u0440\u0438\u0433\u0443\u044e\u0449\u0435, \u043d\u043e \u043f\u043e\u0440\u0430 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0432\u0435\u0441\u0442\u0438 preview \u0441 \u043a\u0430\u043c\u0435\u0440\u044b \u043d\u0430 \u043e\u0441\u0442\u0430\u0432\u0448\u0435\u0439\u0441\u044f surface. <\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u044b\u043f\u0438\u0448\u0435\u043c \u044d\u0442\u0430\u043f\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u0430\u043c\u0435\u0440\u043e\u0439:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u041e\u0436\u0438\u0434\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 permission-\u0430. \u0423 \u043d\u0430\u0441 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <strong>WaitingStart<\/strong><\/li>\n<li>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441 camera manager-\u0430, \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 id (\u043e\u0431\u044b\u0447\u043d\u043e \u0438\u0445 \u0434\u0432\u0430 \u2014 \u0434\u043b\u044f back \u0438 front, \u0430 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u043d \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0434\u0435\u0432\u0430\u0439\u0441\u0430\u0445 \u043a\u0430\u043c\u0435\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u0432) \u043d\u0443\u0436\u043d\u043e\u0439 \u043a\u0430\u043c\u0435\u0440\u044b, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u043c\u0435\u0440\u0443, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c cameraDevice. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <strong>WaitingOpen<\/strong><\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"kotlin\">val manager = getSystemService(Context.CAMERA_SERVICE) as CameraManager var resultCameraId: String? = null var resultSize: Size? = null for (cameraId in manager.cameraIdList) {     val chars = manager.getCameraCharacteristics(cameraId)     val facing = chars.get(CameraCharacteristics.LENS_FACING) ?: -1     if (facing == LENS_FACING_BACK) {          val confMap = chars.get(             CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP         )         val sizes = confMap?.getOutputSizes(SurfaceTexture::class.java)         resultSize = findSize(sizes)         resultCameraId = cameraId         break     } } resultCameraId?.let { cameraId -&gt;      manager.openCamera(cameraId, object : CameraDevice.StateCallback() {         override fun onOpened(camera: CameraDevice) {             \/\/Success open camera             ...         }     }) }<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li>\u0418\u043c\u0435\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0443\u044e \u043a\u0430\u043c\u0435\u0440\u0443 \u043c\u044b \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u0432 \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u0437\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435\u043c Surface-\u0430 \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <strong>WaitingSurface<\/strong><\/li>\n<li>\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u043c\u0435\u044f cameraDevice, Surface \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0441\u0435\u0441\u0441\u0438\u044e \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u043c\u0435\u0440\u0430 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <strong>WaitingSession<\/strong><\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"kotlin\">cameraDevice.createCaptureSession(     arrayListOf(surface),     object : CameraCaptureSession.StateCallback() {         override fun onConfigured(session: CameraCaptureSession) {             send(CameraAction.SessionReady(session))         }     },     handler )<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0445\u0432\u0430\u0442\u0438\u0442\u044c preview. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <strong>StartingPreview<\/strong><\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"kotlin\">val request = cameraDevice.createCaptureRequest(     CameraDevice.TEMPLATE_PREVIEW ).apply {     addTarget(surface) } session.setRepeatingRequest(     request.build(),     object : CameraCaptureSession.CaptureCallback() {...}     handler )<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448\u0443 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0441\u0445\u0435\u043c\u0443:<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/tttzof351\/AndroidSurfaceExample\/blob\/master\/app\/src\/main\/java\/com\/example\/surfaces\/machines\/CameraMachine.kt\" rel=\"nofollow\">CameraMachine.kt<\/a><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/i6\/tj\/q1\/i6tjq12xls77hudocvpnt0m6qy0.png\"><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/6w\/ad\/fp\/6wadfpayduldvtqwcrjggkoce6y.png\"><\/p>\n<p>  <\/p>\n<h2 id=\"mediacodec\">MediaCodec<\/h2>\n<p>  <\/p>\n<p>MediaCodec \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u043c\u0438 \u043a\u043e\u0434\u0435\u043a\u0430\u043c\u0438, \u0432 \u043e\u0431\u0449\u0435\u043c \u0432\u0438\u0434\u0435 \u0435\u0433\u043e API \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 input\/output \u0431\u0443\u0444\u0435\u0440\u043e\u0432 (\u0437\u0432\u0443\u0447\u0438\u0442, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043f\u0440\u043e\u0449\u0435 \u0447\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c) \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 (\u0441\u044b\u0440\u044b\u0435 \u0438\u043b\u0438 \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0440\u0435\u0436\u0438\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b encoder\/decoder), \u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. <\/p>\n<p>  <\/p>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043a \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0431\u0443\u0444\u0435\u0440\u043e\u0432 \u043e\u0431\u044b\u0447\u043d\u043e \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u044e\u0442 ByteBuffer, \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0432\u0438\u0434\u0435\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Surface \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u0440\u043d\u0435\u0442 \u043d\u0430\u043c MediaCodec::createInputSurface, \u043d\u0430 \u043d\u0435\u043c \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u0434\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0445\u043e\u0442\u0438\u043c \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c (\u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043e\u0431\u0435\u0449\u0430\u0435\u0442 \u043d\u0430\u043c \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430 \u0441\u0447\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f gpu).<\/p>\n<p>  <\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 Surface-\u044b \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0432 GLSurfaceMachine \u043d\u0430 Surface \u043e\u0442 MediaCodec-\u0430. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u0430\u0436\u043d\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c: Surface \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 consumer-\u043e\u043c \u0438 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0447\u0442\u043e \u0442\u043e \u0438\u0437 \u043d\u0435\u0433\u043e \u0432 \u043e\u0431\u0449\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0438 \u043d\u0435\u043b\u044c\u0437\u044f \u0442.\u0435 \u043d\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 getBitmap\/readImage\/\u2026<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e GL \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u0438\u043c\u0435\u0442\u044c \u043e\u0431\u0449\u0443\u044e \u0441 \u043d\u0438\u043c \u043f\u0430\u043c\u044f\u0442\u044c, \u0430 \u043f\u043e\u0442\u043e\u043c\u0443 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043c id-\u0448\u043d\u0438\u043a\u0438 \u0442\u0435\u043a\u0441\u0442\u0443\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435. \u0417\u0430\u0442\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043d\u043e\u0432\u044b\u0439 GL \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 Surface \u043e\u0442 MediaCodec-\u0430, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c EGLSurface \u2014 \u0432\u043d\u0435\u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0442\u0430\u043a \u0436\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0448 \u043a\u043b\u0430\u0441\u0441 OpenGLScene. \u0417\u0430\u0442\u0435\u043c \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0435 \u043a\u0430\u0434\u0440\u0430 \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u0434\u0440 \u043d\u0430 \u0444\u0430\u0439\u043b.<\/p>\n<p>  <\/p>\n<p>EGL \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f OpenGL API \u0441 \u043e\u043a\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0434\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b, \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u043d\u0438\u043c \u043c\u044b \u0443\u043a\u0440\u0430\u0434\u0435\u043c \u0438\u0437 grafika. \u041a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 (EncoderHelper) \u0441 MediaCodec-\u043e\u043c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u0436\u0435 \u043d\u0435 \u0431\u0443\u0434\u0443, \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043b\u0438\u0448\u044c \u0438\u0442\u043e\u0433\u043e\u0432\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0430\u0448\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432:<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/tttzof351\/AndroidSurfaceExample\/blob\/master\/app\/src\/main\/java\/com\/example\/surfaces\/machines\/EncoderMachine.kt\" rel=\"nofollow\">EncoderMachine.kt<\/a><br \/>  <a href=\"https:\/\/github.com\/tttzof351\/AndroidSurfaceExample\/blob\/master\/app\/src\/main\/java\/com\/example\/surfaces\/helpers\/EncoderHelper.kt\" rel=\"nofollow\">EncoderHelper.kt<\/a><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/d1\/gc\/kf\/d1gckfqligsrwynmmkq_bb2yzoy.png\"><\/p>\n<p>  <\/p>\n<h2 id=\"itog\">\u0418\u0442\u043e\u0433:<\/h2>\n<p>  <\/p>\n<ul>\n<li>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0432\u0438\u0434\u0435\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0445\u043e\u0442\u044f \u0431\u044b \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043d\u0430\u0432\u044b\u043a\u043e\u0432 \u0432 OpenGL-\u0435<\/li>\n<li>Media API android \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0435, \u0447\u0442\u043e \u0434\u0430\u0435\u0442 \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c, \u043e\u0434\u043d\u0430\u043a\u043e \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043d\u043e\u0433\u0434\u0430 \u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u043e\u0434 \u0447\u0435\u043c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b<\/li>\n<li>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 API \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0432 StateMachine-\u044b<\/li>\n<\/ul>\n<\/div>\n<p>               <script class=\"js-mediator-script\">!function(e){function t(t,n){if(!(n in e)){for(var r,a=e.document,i=a.scripts,o=i.length;o--;)if(-1!==i[o].src.indexOf(t)){r=i[o];break}if(!r){r=a.createElement(\"script\"),r.type=\"text\/javascript\",r.async=!0,r.defer=!0,r.src=t,r.charset=\"UTF-8\";var d=function(){var e=a.getElementsByTagName(\"script\")[0];e.parentNode.insertBefore(r,e)};\"[object Opera]\"==e.opera?a.addEventListener?a.addEventListener(\"DOMContentLoaded\",d,!1):e.attachEvent(\"onload\",d):d() } } }t(\"\/\/mediator.mail.ru\/script\/2820404\/\",\"_mediator\")}(window);<\/script>      <br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/480878\/\"> https:\/\/habr.com\/ru\/post\/480878\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html js-mediator-article\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/480878\/\">\n<h2 id=\"diskleymer\">\u0414\u0438\u0441\u043a\u043b\u0435\u0439\u043c\u0435\u0440<\/h2>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0434\u043b\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0445 \u0430\u043d\u0434\u0440\u043e\u0438\u0434 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0432\u0438\u0434\u0435\u043e \u0438\/\u0438\u043b\u0438 \u043a\u0430\u043c\u0435\u0440\u043e\u0439, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0442\u0435\u0445 \u043a\u0442\u043e \u043d\u0430\u0447\u0430\u043b \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u044b <a href=\"https:\/\/github.com\/google\/grafika\" rel=\"nofollow\">grafika<\/a> \u0438 \u043a\u043e\u043c\u0443 \u043e\u043d\u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u043c\u0438 \u2014 \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u043f\u043e\u0445\u043e\u0436\u0438\u0439 \u043a\u043e\u0434 \u0441 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u044b\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0448\u0430\u0433\u043e\u0432, \u043f\u0440\u043e\u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439. <\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435 \u0432\u044b\u043d\u0435\u0441\u0435\u043d \u043a\u043b\u0430\u0441\u0441 Surface? \u0412 android \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0438\u043c\u0435\u044e\u0442 \u0432 \u0441\u0432\u043e\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438 \u0441\u043b\u043e\u0432\u043e <em>Surface<\/em> (Surface, SurfaceHolder, SurfaceTexture, SurfaceView, GLSurfaceView) \u043e\u043d\u0438 \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u043e\u0431\u0449\u0435\u0439 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0435\u0439 \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0432\u044b\u0432\u043e\u0434 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u041c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u0437\u0443\u043c\u043d\u044b\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0447\u0435\u0440\u043a\u043d\u0443\u0442\u044c \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u0441 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e SDK.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-296010","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/296010","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=296010"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/296010\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=296010"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=296010"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=296010"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}