برای ترسیم گرافیک با OpenGL ES در برنامه اندرویدی خود، باید یک View Container برای آنها ایجاد کنید. یکی از راههای سادهتر برای انجام این کار، پیادهسازی GLSurfaceView
و GLSurfaceView.Renderer
است. یک GLSurfaceView
یک محفظه نمایش برای گرافیک است که با OpenGL و GLSurfaceView.Renderer
ترسیم شده است.Renderer آنچه را که در آن نمای ترسیم شده است کنترل می کند. برای اطلاعات بیشتر در مورد این کلاس ها، راهنمای توسعه دهنده OpenGL ES را ببینید.
GLSurfaceView
تنها یک راه برای گنجاندن گرافیک OpenGL ES در برنامه شما است. برای نمایش گرافیکی تمام صفحه یا تقریباً تمام صفحه، انتخاب معقولی است. توسعهدهندگانی که میخواهند گرافیک OpenGL ES را در بخش کوچکی از طرحبندیهای خود بگنجانند، باید نگاهی به TextureView
بیندازند. برای توسعه دهندگان واقعی که خودتان انجام می دهید، ایجاد نمای OpenGL ES با استفاده از SurfaceView
نیز امکان پذیر است، اما این نیاز به نوشتن مقدار کمی کد اضافی دارد.
این درس نحوه تکمیل حداقل پیاده سازی GLSurfaceView
و GLSurfaceView.Renderer
را در یک فعالیت کاربردی ساده توضیح می دهد.
استفاده OpenGL ES را در مانیفست اعلام کنید
برای اینکه برنامه شما از API OpenGL ES 2.0 استفاده کند، باید اعلان زیر را به مانیفست خود اضافه کنید:
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
اگر برنامه شما از فشردهسازی بافت استفاده میکند، باید همچنین فرمتهای فشردهسازی را که برنامه شما پشتیبانی میکند، اعلام کنید تا فقط بر روی دستگاههای سازگار نصب شود.
<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" /> <supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />
برای اطلاعات بیشتر در مورد فرمت های فشرده سازی بافت، راهنمای توسعه دهنده OpenGL را ببینید.
یک فعالیت برای گرافیک OpenGL ES ایجاد کنید
برنامههای اندرویدی که از OpenGL ES استفاده میکنند، مانند هر برنامه دیگری که رابط کاربری دارد، فعالیتهایی دارند. تفاوت اصلی با سایر برنامه ها این است که در چیدمان فعالیت خود قرار می دهید. در حالی که در بسیاری از برنامهها ممکن است از TextView
، Button
و ListView
استفاده کنید، در برنامهای که از OpenGL ES استفاده میکند، میتوانید GLSurfaceView
نیز اضافه کنید.
مثال کد زیر اجرای حداقلی از یک فعالیت را نشان می دهد که از GLSurfaceView
به عنوان نمای اولیه خود استفاده می کند:
کاتلین
class OpenGLES20Activity : Activity() { private lateinit var gLView: GLSurfaceView public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Create a GLSurfaceView instance and set it // as the ContentView for this Activity. gLView = MyGLSurfaceView(this) setContentView(gLView) } }
جاوا
public class OpenGLES20Activity extends Activity { private GLSurfaceView gLView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a GLSurfaceView instance and set it // as the ContentView for this Activity. gLView = new MyGLSurfaceView(this); setContentView(gLView); } }
توجه: OpenGL ES 2.0 به Android 2.2 (API Level 8) یا بالاتر نیاز دارد، بنابراین مطمئن شوید که پروژه Android شما آن API یا بالاتر را هدف قرار می دهد.
یک شی GLSurfaceView بسازید
GLSurfaceView
یک نمای تخصصی است که در آن می توانید گرافیک OpenGL ES را ترسیم کنید. به خودی خود کار زیادی انجام نمی دهد. ترسیم واقعی اشیا در GLSurfaceView.Renderer
که روی این نما تنظیم کرده اید کنترل می شود. در واقع، کد این شی بسیار نازک است، ممکن است وسوسه شوید که از گسترش آن صرف نظر کنید و فقط یک نمونه GLSurfaceView
اصلاح نشده ایجاد کنید، اما این کار را نکنید. برای ثبت رویدادهای لمسی، که در درس پاسخ به رویدادهای لمسی پوشش داده شده است، باید این کلاس را گسترش دهید.
کد ضروری برای GLSurfaceView
حداقل است، بنابراین برای پیاده سازی سریع، معمول است که فقط یک کلاس داخلی در فعالیتی که از آن استفاده می کند ایجاد کنید:
کاتلین
import android.content.Context import android.opengl.GLSurfaceView class MyGLSurfaceView(context: Context) : GLSurfaceView(context) { private val renderer: MyGLRenderer init { // Create an OpenGL ES 2.0 context setEGLContextClientVersion(2) renderer = MyGLRenderer() // Set the Renderer for drawing on the GLSurfaceView setRenderer(renderer) } }
جاوا
import android.content.Context; import android.opengl.GLSurfaceView; class MyGLSurfaceView extends GLSurfaceView { private final MyGLRenderer renderer; public MyGLSurfaceView(Context context){ super(context); // Create an OpenGL ES 2.0 context setEGLContextClientVersion(2); renderer = new MyGLRenderer(); // Set the Renderer for drawing on the GLSurfaceView setRenderer(renderer); } }
یکی دیگر از گزینههای اضافه شده به پیادهسازی GLSurfaceView
شما این است که حالت رندر را طوری تنظیم کنید که فقط زمانی که تغییری در دادههای طراحی شما با استفاده از تنظیم GLSurfaceView.RENDERMODE_WHEN_DIRTY
ایجاد شود، نما را ترسیم کند:
کاتلین
// Render the view only when there is a change in the drawing data renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY
جاوا
// Render the view only when there is a change in the drawing data setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
این تنظیم از ترسیم مجدد فریم GLSurfaceView
تا زمانی که requestRender()
فراخوانی نکنید، جلوگیری می کند، که برای این برنامه نمونه کارآمدتر است.
یک کلاس رندر بسازید
پیاده سازی کلاس GLSurfaceView.Renderer
یا رندر در برنامه ای که از OpenGL ES استفاده می کند، جایی است که چیزها شروع به جالب شدن می کنند. این کلاس آنچه را که بر روی GLSurfaceView
که با آن مرتبط است ترسیم می شود، کنترل می کند. سه روش در یک رندر وجود دارد که توسط سیستم اندروید فراخوانی می شود تا بفهمیم چه چیزی و چگونه روی GLSurfaceView
ترسیم شود:
-
onSurfaceCreated()
- یک بار برای تنظیم محیط OpenGL ES view فراخوانی شد. -
onDrawFrame()
- برای هر ترسیم مجدد نما فراخوانی می شود. -
onSurfaceChanged()
- اگر هندسه نمای تغییر کند، برای مثال زمانی که جهت صفحه نمایش دستگاه تغییر کند، فراخوانی می شود.
در اینجا یک پیاده سازی بسیار ابتدایی از یک رندر OpenGL ES وجود دارد که کاری جز ترسیم پس زمینه سیاه در GLSurfaceView
ندارد:
کاتلین
import javax.microedition.khronos.egl.EGLConfig import javax.microedition.khronos.opengles.GL10 import android.opengl.GLES20 import android.opengl.GLSurfaceView class MyGLRenderer : GLSurfaceView.Renderer { override fun onSurfaceCreated(unused: GL10, config: EGLConfig) { // Set the background frame color GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f) } override fun onDrawFrame(unused: GL10) { // Redraw background color GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) } override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) { GLES20.glViewport(0, 0, width, height) } }
جاوا
import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLES20; import android.opengl.GLSurfaceView; public class MyGLRenderer implements GLSurfaceView.Renderer { public void onSurfaceCreated(GL10 unused, EGLConfig config) { // Set the background frame color GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); } public void onDrawFrame(GL10 unused) { // Redraw background color GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); } public void onSurfaceChanged(GL10 unused, int width, int height) { GLES20.glViewport(0, 0, width, height); } }
این تمام چیزی است که وجود دارد! مثالهای کد بالا یک برنامه اندروید ساده ایجاد میکنند که با استفاده از OpenGL یک صفحه سیاه نمایش میدهد. در حالی که این کد کار چندان جالبی انجام نمی دهد، با ایجاد این کلاس ها، شما پایه و اساس لازم را برای شروع طراحی عناصر گرافیکی با OpenGL ایجاد کرده اید.
توجه: ممکن است تعجب کنید که چرا این روش ها دارای پارامتر GL10
هستند، وقتی از API های OpengGL ES 2.0 استفاده می کنید. این امضاهای روش به سادگی برای APIهای 2.0 مجددا استفاده می شوند تا کد فریمورک اندروید ساده تر بماند.
اگر با APIهای OpenGL ES آشنا هستید، اکنون باید بتوانید یک محیط OpenGL ES را در برنامه خود راه اندازی کنید و شروع به ترسیم گرافیک کنید. با این حال، اگر برای شروع با OpenGL به کمک بیشتری نیاز دارید، برای چند نکته بیشتر به درس های بعدی بروید.