/* Ċ Ġ* ĠAll Ġcode Ġsamples , Ġunless Ġexplicitly Ġstated Ġotherwise , Ċ Ġ* Ġare Ġlicensed Ġunder Ġthe Ġterms Ġof Ġthe ĠCC ĠBY - NC Ġ 4 . 0 Ġlicense Ċ Ġ* Ġas Ġpublished Ġby ĠCreative ĠCommons , Ġeither Ġversion Ġ 4 Ġof Ġthe ĠLicense , Ċ Ġ* Ġor Ġ( at Ġyour Ġoption ) Ġany Ġlater Ġversion . ĠYou Ġcan Ġfind Ġa Ġhuman - readable Ċ Ġ* Ġformat Ġof Ġthe Ġlicense Ġhere : Ċ Ġ* Ġhttps :// creativecommons . org / licenses / by - nc / 4 . 0 / Ċ Ġ* Ġand Ġthe Ġfull Ġlicense Ġhere : Ċ Ġ* Ġhttps :// creativecommons . org / licenses / by - nc / 4 . 0 / legal code Ċ Ġ* Ċ Ġ* ĠTranslation Ġto Ġkotlin Ġand Ġadapt ation Ġto Ġandroid Ġarchitecture : Ċ Ġ* ĠJim ĠAnd reas Ġ Ġj im @ j im andre as . com Ċ Ġ*/ Ċ Ċ package Ġcom . android kotlin . opengl . learn opengl Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . opengl . GLES 2 0 .* Ċ import Ġandroid . opengl . GLES 3 0 Ċ import Ġandroid . opengl . GLES 3 0 . glBind VertexArray Ċ import Ġandroid . opengl . GLES 3 0 . gl Gen Vertex Arrays Ċ import Ġandroid . opengl . GL Surface View Ċ import Ġcom . android kotlin . opengl . realtime . Renderer Base Class Ċ import Ġcom . android kotlin . opengl . ui . ViewModel Ċ import Ġcom . android kotlin . opengl . util . Shader Ċ import Ġcom . android kotlin . opengl . util . check GL err Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . nio . ByteBuffer Ċ import Ġjava . nio . Byte Order Ċ import Ġjava . nio . Float Buffer Ċ import Ġjavax . micro edition . kh ronos . e gl . EGL Config Ċ import Ġjavax . micro edition . kh ronos . openg les . GL 1 0 Ċ Ċ class ĠRenderer 1 2 1 Hello Triangle ( ĊĠĠĠĠĠĠĠ Ġval Ġcontext : ĠContext , ĊĠĠĠĠĠĠĠ ĠviewModel : ĠViewModel Ċ ) Ġ: ĠRenderer Base Class ( context , ĠviewModel ), ĠGL Surface View . Renderer Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġshader Object Ġ= ĠShader () ĊĊĠĠĠ Ġprivate Ġvar Ġv bo Ġ= ĠInt Array ( 1 ) ĊĠĠĠ Ġprivate Ġvar Ġv ao Ġ= ĠInt Array ( 1 ) ĊĠĠĠ Ġ// private Ġvar Ġe bo Ġ= ĠInt Array ( 1 ) ĊĊĠĠĠ Ġprivate Ġval Ġvertex Buffer : ĠFloat Buffer ĊĠĠĠ Ġ// Ġprivate Ġval Ġindices Buffer : ĠInt Buffer ĊĊĠĠĠ Ġprivate Ġval Ġvertices Ġ= Ġfloat ArrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ- 0 . 5 f , Ġ- 0 . 5 f , Ġ 0 . 0 f , Ġ// Ġleft ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 . 5 f , Ġ- 0 . 5 f , Ġ 0 . 0 f , Ġ// Ġright ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 . 0 f , ĠĠ 0 . 5 f , Ġ 0 . 0 f Ġ Ġ// Ġtop ĊĠĠĠ Ġ) ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġinitialize Ġvertex Ġbyte Ġbuffer Ġfor Ġshape Ġcoordinates ĊĠĠĠĠĠĠĠ Ġval Ġbb Ġ= ĠByteBuffer . allocate Direct ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ( number Ġof Ġcoordinate Ġvalues Ġ* Ġ 4 Ġbytes Ġper Ġfloat ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvertices . size Ġ* Ġ 4 ) ĊĠĠĠĠĠĠĠ Ġ// Ġuse Ġthe Ġdevice Ġhardware 's Ġnative Ġbyte Ġorder ĊĠĠĠĠĠĠĠ Ġbb . order ( Byte Order . native Order ()) ĊĠĠĠĠĠĠĠ Ġ// Ġcreate Ġa Ġfloating Ġpoint Ġbuffer Ġfrom Ġthe ĠByteBuffer ĊĠĠĠĠĠĠĠ Ġvertex Buffer Ġ= Ġbb . as Float Buffer () ĊĠĠĠĠĠĠĠ Ġ// Ġadd Ġthe Ġcoordinates Ġto Ġthe ĠFloat Buffer ĊĠĠĠĠĠĠĠ Ġvertex Buffer . put ( vertices ) ĊĠĠĠĠĠĠĠ Ġ// Ġset Ġthe Ġbuffer Ġto Ġread Ġthe Ġfirst Ġcoordinate ĊĠĠĠĠĠĠĠ Ġvertex Buffer . position ( 0 ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġinitialize Ġbyte Ġbuffer Ġfor Ġthe Ġdraw Ġlist Ċ // ĠĠĠĠĠĠĠ Ġval Ġd lb Ġ= ĠByteBuffer . allocate Direct ( Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ(# Ġof Ġcoordinate Ġvalues Ġ* Ġ 4 Ġbytes Ġper ĠInt ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindices . size Ġ* Ġ 4 ) Ċ // ĠĠĠĠĠĠĠ Ġd lb . order ( Byte Order . native Order ()) Ċ // ĠĠĠĠĠĠĠ Ġindices Buffer Ġ= Ġd lb . as Int Buffer () Ċ // ĠĠĠĠĠĠĠ Ġindices Buffer . put ( indices ) Ċ // ĠĠĠĠĠĠĠ Ġindices Buffer . position ( 0 ) ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Surface Created ( gl Unused : ĠGL 1 0 , Ġconfig : ĠE GL Config ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠSet Ġthe Ġbackground Ġclear Ġcolor Ġto Ġblack . ĊĠĠĠĠĠĠĠ Ġgl Clear Color ( 0 . 0 f , Ġ 0 . 0 f , Ġ 0 . 0 f , Ġ 0 . 0 f ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠUse Ġc ull ing Ġto Ġremove Ġback Ġfaces . ĊĠĠĠĠĠĠĠ Ġgl Disable ( GL _ C ULL _ FACE ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠEnable Ġdepth Ġtesting ĊĠĠĠĠĠĠĠ Ġgl Enable ( GL _ DEPTH _ TEST ) ĊĊĠĠĠĠĠĠĠ Ġshader Object . shader Read Compile Link ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠShader . Shader Source . FROM _ STRING , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvertex Shader Source , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfragment Shader Source ) ĊĊĠĠĠĠĠĠĠ Ġgl Gen Vertex Arrays ( 1 , Ġv ao , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġgl Gen Buffers ( 1 , Ġv bo , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġ// gl Gen Buffers ( 1 , Ġe bo , Ġ 0 ) ĊĊĠĠĠĠĠĠĠ ĠglBind VertexArray ( v ao [ 0 ]) ĊĠĠĠĠĠĠĠ ĠGLES 3 0 . glBind Buffer ( GL _ ARRAY _ BUFFER , Ġv bo [ 0 ]) ĊĠĠĠĠĠĠĠ ĠGLES 3 0 . gl BufferData ( GL _ ARRAY _ BUFFER , Ġvertices . size Ġ* Ġ 4 , Ġvertex Buffer , ĠGL _ STATIC _ DRAW ) ĊĠĠĠĠĠĠĠ ĠGLES 3 0 . glVertex Attrib Pointer ( 0 , Ġ 3 , ĠGL _ FLOAT , Ġfalse , Ġ 3 Ġ* Ġ 4 , Ġ 0 ) ĊĠĠĠĠĠĠĠ ĠGLES 3 0 . gl Enable VertexAttrib Array ( 0 ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġnote Ġthat Ġthis Ġis Ġallowed , Ġthe Ġcall Ġto ĠglVertex Attrib Pointer ĊĠĠĠĠĠĠĠ Ġ// Ġregistered ĠV BO Ġas Ġthe Ġvertex Ġattribute 's Ġbound Ġvertex Ġbuffer Ġobject ĊĠĠĠĠĠĠĠ Ġ// Ġso Ġafterwards Ġwe Ġcan Ġsafely Ġun bind ĊĠĠĠĠĠĠĠ ĠglBind Buffer ( GL _ ARRAY _ BUFFER , Ġ 0 ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġremember : Ġdo ĠNOT Ġun bind Ġthe ĠE BO Ġwhile Ġa ĠV AO Ġis Ġactive ĊĠĠĠĠĠĠĠ Ġ// Ġas Ġthe Ġbound Ġelement Ġbuffer Ġobject ĠIS Ġstored Ġin Ġthe ĠV AO ; ĊĠĠĠĠĠĠĠ Ġ// Ġkeep Ġthe ĠE BO Ġbound . ĊĠĠĠĠĠĠĠ Ġ// glBind Buffer ( GL _ ELEMENT _ ARRAY _ BUFFER , Ġ 0 ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠYou Ġcan Ġun bind Ġthe ĠV AO Ġafterwards Ġso Ġother ĠV AO Ġcalls ĊĠĠĠĠĠĠĠ Ġ// Ġwon 't Ġaccidentally Ġmodify Ġthis ĠV AO , Ġbut Ġthis Ġrare ly Ġhappens . ĊĠĠĠĠĠĠĠ Ġ// ĠModify ing Ġother ĠVA Os Ġrequires Ġa Ġcall Ġto ĠglBind VertexArray Ġanyway ĊĠĠĠĠĠĠĠ Ġ// Ġso Ġwe Ġgenerally Ġdon 't Ġun bind ĠVA Os Ġ( nor ĠV BO s ) Ġwhen Ġit 's Ġnot Ġdirectly Ġnecessary . ĊĠĠĠĠĠĠĠ ĠglBind VertexArray ( 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Draw Frame ( gl Unused : ĠGL 1 0 ) Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . i (" On Draw Frame ") ĊĠĠĠĠĠĠĠ ĠGLES 3 0 . gl Clear Color ( 0 . 1 f , Ġ 0 . 1 f , Ġ 0 . 1 f , Ġ 1 . 0 f ) ĊĠĠĠĠĠĠĠ ĠGLES 3 0 . gl Clear ( GLES 3 0 . GL _ COLOR _ BUFFER _ BIT Ġor ĠGLES 3 0 . GL _ DEPTH _ BUFFER _ BIT ) ĊĊĠĠĠĠĠĠĠ Ġcheck GL err (" O DF 1 ") ĊĠĠĠĠĠĠĠ Ġshader Object . use () ĊĠĠĠĠĠĠĠ Ġcheck GL err (" O DF 2 ") ĊĠĠĠĠĠĠĠ Ġ// Ġseeing Ġas Ġwe Ġonly Ġhave Ġa Ġsingle ĠV AO Ġthere 's Ġno Ġneed ĊĠĠĠĠĠĠĠ Ġ// Ġto Ġbind Ġit Ġevery Ġtime , Ġbut Ġwe 'll Ġbind Ġit Ġanyway Ġso Ġto Ġkeep Ġthings Ġa Ġbit Ġmore Ġorganized ĊĠĠĠĠĠĠĠ ĠglBind VertexArray ( v ao [ 0 ]) ĊĠĠĠĠĠĠĠ Ġcheck GL err (" O DF 3 ") ĊĠĠĠĠĠĠĠ Ġgl Draw Arrays ( GL _ TRI ANG LES , Ġ 0 , Ġ 3 ) ĊĠĠĠĠĠĠĠ Ġ// gl Draw Elements ( GL _ TRI ANG LES , Ġ 6 , ĠGL _ UNSIGNED _ INT , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġcheck GL err (" O DF 4 ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Surface Changed ( gl Unused : ĠGL 1 0 ?, Ġwidth : ĠInt , Ġheight : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . i (" On Surface Changed , Ġwidth Ġ% d , Ġheight Ġ% d ", Ġwidth , Ġheight Ġ) ĊĠĠĠĠĠĠĠ Ġ// ĠSet Ġthe ĠOpenGL Ġviewport Ġto Ġthe Ġsame Ġsize Ġas Ġthe Ġsurface . ĊĠĠĠĠĠĠĠ Ġgl Viewport ( 0 , Ġ 0 , Ġwidth , Ġheight ) ĊĠĠĠĠĠĠĠ Ġscreen Width Ġ= Ġwidth ĊĠĠĠĠĠĠĠ Ġscreen Height Ġ= Ġheight ĊĊĠĠĠĠĠĠĠ Ġlast X Ġ= Ġscreen Width Ġ/ Ġ 2 . 0 f ĊĠĠĠĠĠĠĠ Ġlast Y Ġ= Ġscreen Height Ġ/ Ġ 2 . 0 f ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġvertex Shader Source Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ# version Ġ 3 0 0 Ġes ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprecision Ġmedi ump Ġfloat ; ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlayout Ġ( location Ġ= Ġ 0 ) Ġin Ġvec 3 Ġa Pos ; ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvoid Ġmain () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgl _ Position Ġ= Ġvec 4 ( a Pos . x , Ġa Pos . y , Ġa Pos . z , Ġ 1 . 0 ); ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfragment Shader Source Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ# version Ġ 3 0 0 Ġes ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprecision Ġmedi ump Ġfloat ; ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout Ġvec 4 ĠF rag Color ; ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvoid Ġmain () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠF rag Color Ġ= Ġvec 4 ( 1 . 0 f , Ġ 0 . 5 f , Ġ 0 . 2 f , Ġ 1 . 0 f ); ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġscreen Width Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġscreen Height Ġ= Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġlast X Ġ= Ġ 0 f ĊĠĠĠ Ġprivate Ġvar Ġlast Y Ġ= Ġ 0 f Ċ } Ċ