How Kotlin can change developer experience with modern graphics APIs
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 490 | |
Author | ||
License | CC Attribution 2.0 Belgium: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/47407 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
00:00
Bit rateLevel (video gaming)Utility softwareLeakField (computer science)Software developerSoftwareDifferent (Kate Ryan album)Computer animationLecture/Conference
00:59
Point (geometry)Mechanism designComputing platformCausalitySoftware developerRevision controlCodeContext awarenessCartesian coordinate systemComputer animation
02:10
Computer programmingFunction (mathematics)Social classLine (geometry)Row (database)Social classFunctional programmingLink (knot theory)CodeCompilerMereologyLibrary (computing)Lambda calculusBoilerplate (text)Functional (mathematics)IntegerMassObject (grammar)Multiplication signParameter (computer programming)Computer animation
03:44
Element (mathematics)Vertex (graph theory)Data bufferBuffer solutionDiffusionoutputLink (knot theory)Position operatorUniform convergenceMathematicsSource codeInformationVortexLengthIntegrated development environmentCycle (graph theory)Arithmetic meanMultiplication signCASE <Informatik>Position operatorGraph coloringSampling (statistics)String (computer science)Data compressionSpacetimeException handlingSource codeSound effectPhysical lawComputer programmingMereologyEquivalence relationArchaeological field surveyBit rateWhiteboardFunctional (mathematics)Data storage deviceBuffer solutionSemiconductor memoryUniformer RaumLibrary (computing)Projective planeAttribute grammarE-learningLine (geometry)Process (computing)Type theoryPoint (geometry)AdditionGeneric programmingShader <Informatik>Vector spaceCompilation albumInformationObject (grammar)CodeSocial classVertex (graph theory)Interior (topology)LoginLengthDatabase normalizationDiffuser (automotive)Boolean algebraEnumerated typeSet (mathematics)View (database)Beta functionEndliche ModelltheorieIntegerMatrix (mathematics)
10:54
Position operatorVortexComputer programConvex hullAxonometric projectionRead-only memoryExecution unitBoolean algebraString (computer science)Line (geometry)Attribute grammarComputer programmingVariable (mathematics)Moment (mathematics)SurfaceInternetworkingOffice suiteUniform resource locatorElement (mathematics)Uniformer RaumBuffer solutionE-learningPosition operatorFigurate numberCASE <Informatik>Software testingStreaming mediaHand fanType theoryNumeral (linguistics)Block (periodic table)Internet forumTouch typingBit rateTwitterVideo gameGroup actionGraph coloringTriangleDefault (computer science)Goodness of fitLibrary (computing)Directory serviceSemiconductor memoryPoint (geometry)Extension (kinesiology)Term (mathematics)Keyboard shortcutObject (grammar)NumberThomas BayesSource codeMetreAeroelasticityCore dumpSystem callError messageStack (abstract data type)Vertex (graph theory)Latent heatLambda calculusFunctional (mathematics)Primitive (album)Standard deviationShader <Informatik>Link (knot theory)Pointer (computer programming)Interior (topology)Parameter (computer programming)Vector spaceVolumenvisualisierungWindowData storage deviceSocial classNatural numberMatrix (mathematics)Operator overloadingProjective planeView (database)Order (biology)Just-in-Time-CompilerMessage passingMatching (graph theory)CodeComputer animation
18:04
Artistic renderingComputing platformOverhead (computing)BootingLine (geometry)Computing platformSocial classInsertion lossGame theoryComputer animation
18:27
Social classFunction (mathematics)Computer programmingFunctional (mathematics)Computer programmingTerm (mathematics)System callObject (grammar)AreaGeneral linear modelFunctional programmingComputer animation
19:01
Form (programming)Computing platformStack (abstract data type)Validity (statistics)SpacetimeSpecial unitary groupPoint (geometry)Type theoryCartesian coordinate systemDecision theoryWeightCore dumpFunctional (mathematics)String (computer science)Row (database)State of matterExtension (kinesiology)Instance (computer science)InformationBuffer solutionStack (abstract data type)Order (biology)Software bugPointer (computer programming)Revision controlOcean current
20:53
Host Identity ProtocolFunctional (mathematics)Point (geometry)Uniform resource locatorCodeState of matterHand fanNetwork topologyCategory of beingPointer (computer programming)LengthLine (geometry)Multiplication signWritingInformation retrievalProcess (computing)QuicksortNumberLattice (order)Recurrence relationDisk read-and-write headHuman migrationData miningClosed setString (computer science)Buffer solutionInstance (computer science)Type theory1 (number)Library (computing)Cartesian coordinate systemJava appletCountingUniqueness quantificationError messageInformationElectronic mailing listSocial classValidity (statistics)Interior (topology)Resource allocationResultant
23:46
Instance (computer science)ResultantConstructor (object-oriented programming)Lambda calculusInstance (computer science)Functional (mathematics)Line (geometry)Core dumpComputer animationLecture/Conference
24:07
CodeInstance (computer science)Semiconductor memoryFunctional (mathematics)Loop (music)Category of beingIncidence algebraGraph coloring
25:09
Library (computing)Multiplication signSelf-organizationComputer animation
25:31
Point cloudOpen sourceFacebook
Transcript: English(auto-generated)
00:05
So please welcome on stage Giuseppe. He's going to talk about how Kotlin can change developer experience with modern graphics APIs. Please. Hi, thank you.
00:22
As I said, I'm Giuseppe Ververi. I am a graphic developer by Reno who is working on a software called Mcheck which is a cat-like software for analyzing the visibility field of different types of vehicles. Basically, I fell in love
00:41
with Kotlin some years ago and then I started writing some utility leaks to help the development with graphics. So let's get started. We'll start with OpenGL. I will assume that we are all Kotlinians and some of you might already know OpenGL and maybe Vulkan. How
01:05
many know OpenGL? Okay. Vulkan? Okay. So for the others, let's say there's much more about code so you can still understand most of the stuff. So let's get started with OpenGL.
01:25
So it's a really whole library, let's say, started in 1991 with STI. Then they left the development in 2006 and basically hand over to Kronos which released a very big version 3.0
01:46
in 2008. They also introduced the application mechanism and context and the 4.1 is the less available because there's a little shame and the last release available
02:02
for all the other platforms is 4.6 which was released in 2017, two years ago. Vulkan came a little earlier than that. So welcome to GLN. What it is about, basically about, makes some, I would say, some massive use of inline classes where basically
02:23
you already know it's an integer and most of the time it's an integer but works like classes and also enums, although they are not really available in Kotlin but there's a little trick. Then also we have inline functions. So basically you write the nice code and then everything,
02:43
all the, let's say, I will not say ugly but all the boilerplate code will be then replaced by the compiler. It's also object-oriented. So as I say, on the inline classes we have all the methods. DSL, where you can easily wrap some scope, some, let's say, OpenGL object
03:06
and then inside the scope do something nice. Functional programming, so you can pass around lambdas whenever needed and there are also some convenience of loading functions that basically take maybe some parameter, some, let's say, parameters which are quite obvious
03:28
out of the question so we can have some more concise code and it plays quite well quite nicely with another library. GLN is basically a part of the original CGLN.
03:46
The best way is just to start showing code and let's go through a very, very simple hello world program. So in this case, for example, we start our main, we define some variable where we have, for example, the program variable, then an enumerator to identify
04:06
the two buffer that we are going to use, one for the vertex and one for the element, then the actual variable which is under the hood, it's direct in buffer, it's native memory, then we have one integer for the vertex array and two for the uniform,
04:25
the so-called MVP for the model view projection matrix and one for the diffuse color. Then let's dig into our first method, any program. Okay, here you can see in our function we start
04:43
just, I will show you first the plain way to do it in Kotlin. So we first create our program, then we want to create our vertex shader, we have another function for that called init vertex shader, we go inside our init vertex shader, we can define here the source,
05:05
this is a pretty standard shader where we have, for example, matrix to then incoming attribute, vertex attributes, and here Kotlin makes very nice because first we have the simple quote, so compared to Java this is already a very nice point, very nice advantages,
05:24
and if we want we can also inject, as you see in the comment, we can inject some explicit vertex layout, like for example position, then we have also one for the color, we have an outside for the color that will be linearly interpreted by the fragment shader, and then
05:44
in the main we simply multiply the incoming position by the matrix, we assign to the glsl position and then we also pass the color. Then we create our vertex shader,
06:01
we need to pass of course the type of vertex shader that we want to create, in this case vertex shader, then we can have a generic init shader where we give the object we just created and the source. In the init shaders, we just say the shaders
06:21
and the source, so first we want to set the source to the shaders, we want them to compile the shaders, it's a lot of redundancy here, then we want to check if of course everything went fine or we want to know if there was some problem, so we retrieve the compile status, gl get shader i means that of course we
06:47
will get an int, then we need to for example to check this int against one OpenGL concept like gl false, if the compile failed then we want to see what went wrong,
07:03
so we want of course to retrieve the info log, but to retrieve the info log we need first to retrieve the info log length and this is what we are doing here, gl get shader i, we pass the shader set and then the concept info log length, we return an int, then with this we can call gl get shader info which will return automatically a string
07:25
and then finally we can prove our nice exception with the reason why the compilation failed. Then we can come back and we can return our vertex. How can we make this nicer? First we return from the Linux vector shader a gl shader,
07:47
this is an inline classes, the source is the same, let's comment out for space problems, then our original gl create shader will be converted to a static function on the inline
08:03
class, so we want a gl shader and we call create passing, in this case beta shader, you can think about like an enemy, then what we do here is basically we scope the gl shader and then we can simply type much shorter code because we scoped it,
08:27
so we know what this is going about and we don't want any more redundancy, so we call simply source, maybe this is unfortunately naming, then we compile our
08:41
shaders, compile status, this is also nice, we are inside this, let's say inside the scopes, so compile status is just, let's say, get custom get variable, which we return of course the
09:03
compile status and we already know that the compile status should be a boolean, so immediately we can return directly a boolean. And then also the info log, I don't want to write all the boiler code, so I want to hide in the library, I just want to type gl shader
09:21
info log and then I retrieve all the log that is telling me what went wrong. So we saw here gl shader dot create vertex shader, question is what is this vertex shader, it's an inline class or a numerator, well it's actually both because although Kotlin doesn't
09:51
which I personally hoping to implement also inline enumerator, it's going to take some time, hopefully one day we will get them but in the meantime there was a user, I don't remember
10:03
anymore the name but on the forum, on the Kotlin forum, wrote this nitrix where we can basically use inline classes as an enumerator. There's just one disadvantage, let's say basically the the end user can create some additional enumerator but of course we want to play nice so
10:25
it's a cooperative environment and we don't, I mean the user will not hurt itself and create an additional maybe wrong enumerator. Then in our init we come back to the init program,
10:42
we just came back from create a vector shader, fragment is basically the same, I will not go inside because it's a matter of time. Then we have to attach the vertex and fragment to our program, in this case for example we bind the attribute location like position and color to some
11:06
parameterized variable and then we link our program. Let's for a moment pause here and see what this can become. So program can be also an inline classes where we call basically
11:26
glProgramCreate and then we call apply, here glProgram will be scoped again, we call our corresponding create vertex and fragment shader which in this case they will return
11:41
inline classes instead of int. Then you can use for example the nice overload operator from Kotlin to attach the vertex to the program. We can then instead all of this stuff glBinding attribute location blah blah blah, we can simply type the string, we are inside the scope so we offer an extension function on the string
12:05
that will when will be set it will be automatically called glBinding attribute location behind the curtains, so it's more like I would say natural. Then we link just one call and then we continue, we continue. Here instead link status we have as before
12:27
just one variable because we are inside this block, also info log is just one line. Then we detach the shaders, it's not mandatory but if you want to do the things clear,
12:43
we detach them from the program and then we simply delete the shaders since they are inline classes we have a method available on the inline class itself. Honestly you can do all of this with just one line, using glProgram init from path you give the path of the
13:07
you give up to the name of the shaders, then the shaders need to be that you have all the same name and then through some standard shader extension like vert, frag, gem, test and so on.
13:26
We look if they are available, if they are available we load them and then we will compile into the program. Also we will look in the same directory if you have any import on any additional shaders. Remember when we had to bind the attribute location, this if you remember need
13:47
to be done before linking the program. So how can we do? We just pass them as a lambda at the end of our init program and this lambda will be of course served to you with the program base
14:00
it's an object basically offer you this all these nice stuff like attribute with it an extension variable on the on a string and this will be called before the link program then link program blah blah return the glProgram to you. Everything nice and puffy. Okay now init
14:23
buffer we go in the init buffer this is pretty standard we generate the buffer we bind it we bind the buffer that we retrieve from our buffer variable using the numerator just to make it nicer then we bind to the glArrayBuffer target we upload the position we detach the buffer
14:47
then we do the same for the element and then we check the error and we come out so here the buffer we can basically generate them in just one line we scope them we since we scope we can just use
15:04
the numerator to retrieve the corresponding buffer we bound it and then we pass the lambda what we call for example just data position data. Everything is already known we know the buffer we know the target no need to re-declare them same for the element and so on at the end the
15:25
buffer will be detached check error init vectors array we do the same generate the vectors array bind we need to bind the buffer we need to call a JIT vectors attribute point where we give all the stuff of all the stuff to specification for our vertex layout then we detach a
15:44
bind buffer and the vertex array required to left bond the element array this is what we do we enable we detach we check the error what we can do we can call gel vertex array we give the reference to our inline function it's also something really cool in Kotlin we bound it
16:06
we buffer we scope the buffers we call the numerator bound on array GLN offers some predefined layout just post two called preset will automatically call all the line that you see above we bind the element we enable we check the error and we
16:26
come back then here in the render we basically have a window size vector position vector hit position where we calculate our projection matrix view and MVP matrix then GLN offer you some overloading function like this GL you bought the window size
16:44
set the color right there then we have the corresponding buffer and we go to the next stuff we use the program we retrieve the memory stack in order to allocate our matrix on the in netting memory on the thread stack and we bind the vertex array draw element and bind
17:07
and use the program virtual and true this can be done in the following code program used we enter just your uniform uniform MVP and we get the matches everything will be done in the background vertex array bound as before your element just pass element
17:24
triangle is the default type primitive and all the rest will be retrieved from the in this case element is an int buffer so we can retrieve the number of elements that remains the type and then the pointer at the end is defaulted to zero let's run through at the end we can
17:42
just call the corresponding delete on the stuff so with dsa we can basically what was before like GL buffer parameter get translated to GL get named buffer parameter with GLN you simply call buffer immutable storage on the line class itself pretty natural and standard
18:04
so Vulkan it's not only across platform rendering but also computing API we're supposed to supposed to also um let's say take over OpenCL really low horror that you have more than 1000 line for a single hello triangle boot upon mountain mantle uh donated by MD was released on 2016
18:24
and the last release was at the beginning of this year we are basically also in line classes and any inline functions it's object oriented all the vke um object has a lot of function on there
18:40
functional programming and um convenience overloading low function so where basically we um call the very end function all over the lvg gl binding just before passing going to the native and then also play nice with glm let's go just through a very short stuff so just like
19:06
creating sense we want to have a validation what we need to do first usually you want to retrieve the stack at the beginning of the function and then use in the in the body we need to call we need to allocate a vk application info but in order to do this
19:24
we need the first two um for our application enjoy name create um allocate some native space and then allocate this string on the native memory via stack utf-8 then we call vk application info we set this type all the string happy
19:43
version one we go next we retrieve the required extension it's a pointer buffer if it's null then we get we are we know we are in in a narrow state then we create a vk instance create info also we require this type and then we pass our application info we just
20:04
created then if this required instance extension is not empty and we require we want the user want to have validation then we need to allocate we need to take the pointer buffer and then make space for another slot and then copy back all the stuff and finally allocate the
20:23
new extension like we have done here so we copy all the extension for the from the required extension to the instance extension variable we allocate the vk the bug utils then we
20:40
actually put it and then we set the variable otherwise we set immediately the variable or before because we didn't have to add a new extension then again if we need validation then we need the vk layer kernels validation which has all the current validation functionality we want to check if this is available so basically we retrieve all the instance layer properties in
21:06
this way you create a pointer to nanita to retrieve all the layer properties count and then with this you can actually allocate all the buffer for the layer properties and then finally all the layer properties then we check if this layer is present
21:26
if this is present then we simply allocate a pointer buffer we give the this financial layer name in this pointer buffer and then we assign to the corresponding variable if not we find another at the end we create a pointer buffer where we'll be saved the
21:48
instance pointer so we call recreate create instance and we pass at the end our pointer buffer we will return we will get an int at the end then we will create our vk instance
22:02
we pop the stack and we return the result create instance so with vke2 we can just do this create instance we return directly an inline classes it's everything in java we don't want to deal we already take the heat of the performance since we are in jvm i don't want also to take the heat about writing let's say i would not say hardly but pass me that bear
22:25
with me on this so i don't want to write all the boiler paper so application info hello triangle my giant ones no need to deal with pre-string and so on i don't have to type also the the i don't have to specify the type so then i require i get the required instance
22:42
session it's one unique release of string i want to avoid the nullability so just it's empty i'm in the fatal state then i create the instance create info if it's not empty if i want validation i just add the string into the array list and then i simply pass the
23:02
array list to the corresponding variable if it's validation vk layer validation we just one line we retrieve all our layer properties all the boiler code is again hidden by the by the library we check if it's present the layer if it's present we simply add them otherwise we find the error and then we create the instance again no pointers
23:28
so we don't have to create a pointer buffer and then retrieve from the pointer buffer after calling the function it's a direct instantiation and there is no allocation function because i never saw anything about passing something for the allocation so this is always null
23:46
where is the expected vk result well since everything is in line we can just call the function that it's a dummy constructor and then uh also accept a lambda at the end it's in line so we can write a return and in the lambda we'll
24:04
be given the result at the first one we return the instance what happened to the stack well you remember we had to break the stack once and then use inside the code here what we do basically we use the stack just in two places where we retrieve the layer properties and
24:23
when we get the instance this will be all automatically done i mean if you don't pass the in this way the stack will be retrieved you you will get the hit of the stack get twice if you don't want to get this hit then what you do you basically call create instance using
24:42
the memory stack as a receiver so everything nice very few modification and it's really um efficient because in the hot loop you don't want to pay an additional hit so you can you should pass the stack that you get all through down the the stack function where it's needed
25:10
all the libraries are available at github.com under kotik that is organization sorry i don't have time for a question and answer and i hope you will find some interest over there