Poly API: 3D-middelen ophalen voor uw VR- en AR Android-apps

Schrijver: Peter Berry
Datum Van Creatie: 14 Lang L: none (month-012) 2021
Updatedatum: 17 April 2024
Anonim
WebAR Markerless Object Placement - AR in Browser using WebXR API|| Google WebXR API||WebXR Emulator
Video: WebAR Markerless Object Placement - AR in Browser using WebXR API|| Google WebXR API||WebXR Emulator

Inhoud


Heb je een geweldig idee voor een Virtual Reality (VR) of Augmented Reality (AR) mobiele app, maar heb je geen idee hoe je je visie tot leven kunt brengen?

Tenzij je een Android-ontwikkelaar bent die toevallig ook een ervaren 3D-artiest is, kan het een ontmoedigend proces zijn om alle middelen te creëren die nodig zijn om een ​​meeslepende, 360 graden ervaring te bieden.

Alleen omdat je niet de tijd, middelen of ervaring hebt die nodig is om 3D-modellen te maken, niet betekent dat je geen geweldige VR- of AR-mobiele app kunt bouwen! Er is een enorm scala aan 3D-bronnen vrij beschikbaar op het World Wide Web, plus alle API's, frameworks en bibliotheken die u nodig hebt om deze middelen te downloaden en weer te geven in uw Android-applicaties.

Lees volgende: U kunt nu elke website bezoeken met Daydream VR. Zelfs die.

In dit artikel gaan we kijken naar Poly, een online repository en API waarmee je duizenden 3D-middelen binnen handbereik hebt. Tegen het einde van dit artikel hebt u een app gemaakt die tijdens runtime een 3D Poly-item ophaalt en deze vervolgens weergeeft met behulp van de populaire bibliotheek Verwerken voor Android.


3D-middelen weergeven met Poly

Als je ooit in Unity-ontwikkeling bent geweest, dan is de Poly-repository vergelijkbaar met de Unity Asset Store - behalve dat alles in Poly gratis is!

Veel van de 3D-modellen van Poly worden gepubliceerd onder de Creative Commons-licentie, dus je bent vrij om deze middelen te gebruiken, aan te passen en te remixen, op voorwaarde dat je de maker het juiste krediet geeft.

Alle 3D-modellen van Poly zijn ontworpen om compatibel te zijn met de VR- en AR-platforms van Google, zoals Daydream en ARCore, maar u kunt ze gebruiken waar en hoe u maar wilt - mogelijk kunt u ze zelfs gebruiken met ARKit van Apple!

Als het gaat om het ophalen en weergeven van Poly-activa, hebt u twee opties. Ten eerste kunt u de middelen naar uw computer downloaden en ze vervolgens in Android Studio importeren, zodat ze bij uw toepassing worden geleverd en bijdragen aan de APK-grootte, of u kunt deze middelen tijdens runtime ophalen met behulp van de Poly API.


De platformonafhankelijke, op REST gebaseerde Poly API biedt programmatische, alleen-lezen toegang tot de enorme verzameling 3D-modellen van Poly. Dit is ingewikkelder dan het bundelen van middelen met uw APK, maar er zijn verschillende voordelen aan het ophalen van Poly-activa tijdens runtime, met name dat het helpt om uw APK-grootte onder controle te houden, wat kan beïnvloeden hoeveel mensen uw toepassing downloaden.

Je kunt de Poly API ook gebruiken om je gebruikers meer keuze te geven, bijvoorbeeld als je een mobiele game ontwikkelt, kun je je gebruikers laten kiezen uit een reeks personagemodellen.

Omdat je de Poly-modellen vrij kunt aanpassen, kun je je gebruikers zelfs hun gekozen karakter laten aanpassen, bijvoorbeeld door de haar- of oogkleur te wijzigen, of door het te combineren met andere Poly-middelen, zoals verschillende wapens en uitrusting. Op deze manier kan de Poly API u helpen een indrukwekkend scala aan 3D-middelen te leveren, met veel ruimte voor het personaliseren van de ervaring - en dat alles voor relatief weinig werk. Uw gebruikers zullen ervan overtuigd zijn dat u heel wat tijd hebt besteed aan het zorgvuldig maken van al deze 3D-modellen!

Een 3D-modelleringsproject maken

We gaan een applicatie maken die een bepaald Poly-activum ophaalt wanneer de applicatie voor het eerst wordt gestart, en dat activum vervolgens op volledig scherm weergeeft, op verzoek van de gebruiker.

Om ons te helpen dit item op te halen, gebruik ik Fuel, een HTTP-netwerkbibliotheek voor Kotlin en Android. Begin met het maken van een nieuw project met de instellingen van uw keuze, maar kies desgevraagd voor 'Inclusief Kotlin-ondersteuning'.

Alle oproepen die u naar de Poly API doet, moeten een API-sleutel bevatten, die wordt gebruikt om uw app te identificeren en gebruikslimieten af ​​te dwingen. Tijdens het ontwikkelen en testen gebruikt u vaak een onbeperkte API-sleutel, maar als u plannen hebt om deze app vrij te geven, moet u een Android-beperkte API-sleutel gebruiken.

Om een ​​beperkte sleutel te maken, moet u het SHA-1-handtekeningcertificaat van uw project kennen, dus laten we deze informatie nu krijgen:

  • Selecteer het tabblad "Gradle" van Android Studio (waar de cursor zich in de volgende schermafbeelding bevindt). Dit opent een paneel "Projecten".

  • Dubbelklik in het paneel "Projecten" om de ‘root" van uw project uit te vouwen en selecteer vervolgens "Taken> Android> Ondertekeningsrapport". Dit opent een nieuw paneel onderaan het venster van Android Studio.
  • Selecteer de knop 'Taken uitvoeren / tekstmodus wisselen' (waarbij de cursor in de volgende schermafbeelding staat).

Het "Uitvoeren" -paneel wordt nu bijgewerkt en toont veel informatie over uw project, inclusief de SHA-1-vingerafdruk.

Maak een Google Cloud Platform-account

Om de benodigde API-sleutel te verkrijgen, hebt u een Google Cloud Platform (GPC) -account nodig.

Als u geen account hebt, kunt u zich aanmelden voor een gratis proefperiode van 12 maanden door naar de gratis pagina van het Try Cloud Platform te gaan en de instructies te volgen. Houd er rekening mee dat een creditcard of betaalpas vereist is, maar volgens de pagina Veelgestelde vragen wordt dit alleen gebruikt om uw identiteit te verifiëren en "er worden geen kosten in rekening gebracht of gefactureerd tijdens uw gratis proefperiode".

Download uw Poly API-sleutel

Als u eenmaal bent aangemeld, kunt u de Poly API inschakelen en uw sleutel maken:

  • Ga naar de GCP-console.
  • Selecteer het omlijnde pictogram in de linkerbovenhoek en kies 'API's en services> Dashboard'.
  • Selecteer 'API's en services inschakelen'.
  • Kies 'Overig' in het menu aan de linkerkant.
  • Selecteer de "Poly API" -kaart.
  • Klik op de knop "Inschakelen".
  • Na enkele ogenblikken wordt u naar een nieuw scherm gebracht; open het zijmenu en kies "API's & Services> Referenties".

  • Selecteer "Sleutel beperken" in de volgende pop-up.
  • Geef uw sleutel een onderscheidende naam.
  • Selecteer 'Android-apps' onder 'Toepassingsbeperkingen'.
  • Selecteer "Pakketnaam en vingerafdruk toevoegen".
  • Kopieer / plak de SHA-1-vingerafdruk van uw project in het veld "Signing-certificate fingerprint".
  • Voer de pakketnaam van uw project in (deze verschijnt in uw manifest en bovenaan elk klassenbestand).
  • Klik op 'Opslaan'.

U wordt nu naar het scherm 'Referenties' van uw project gebracht, dat een lijst met al uw API-sleutels bevat, inclusief de Poly-enabled API-sleutel die u zojuist hebt gemaakt.

Projectafhankelijkheden: brandstof-, P3D- en Kotlin-uitbreidingen

Om Poly-activa op te halen en weer te geven, hebben we hulp nodig van enkele aanvullende bibliotheken:

  • Brandstof. Poly heeft momenteel geen officiële Android-toolkit, dus u moet rechtstreeks met de API werken via de REST-interface. Om dit proces eenvoudiger te maken, gebruik ik de Fuel HTTP-netwerkbibliotheek.
  • Verwerking voor Android. Ik gebruik de P3D-renderer van deze bibliotheek om het Poly-activum weer te geven.

Open het build.gradle-bestand van uw project en voeg deze twee bibliotheken toe als projectafhankelijkheden:

afhankelijkheden {implementatie fileTree (include:, dir: libs) implementatie "org.jetbrains.kotlin: kotlin-stdlib-jre7: $ kotlin_version" implementatie com.android.support:appcompat-v7:27.1.1 // Brandstofbibliotheek toevoegen / / implementatie com.github.kittinunf.fuel: fuel-android: 1.13.0 // Voeg de Processing voor Android-engine toe // implementatie org.p5android: processing-core: 4.0.1}

Om onze code beknopter te maken, gebruik ik ook Kotlin Android-extensies, dus laten we deze plug-in toevoegen terwijl we het build.gradle-bestand open hebben:

plugin toepassen: kotlin-android-extensions

Omdat we het item van internet halen, heeft onze app ten slotte de internetmachtiging nodig. Open uw manifest en voeg het volgende toe:

Uw API-sleutel toevoegen

Elke keer dat onze app een activum van Poly vraagt, moet deze een geldige API-sleutel bevatten. Ik gebruik plaatsaanduidingstekst, maar jij moet vervang deze tijdelijke aanduiding door uw eigen API-sleutel als de toepassing ooit gaat werken.

Ik voeg ook een vinkje toe, zodat de toepassing een waarschuwing weergeeft als u vergeet de tekst "INSERT-YOUR-API-KEY" te vervangen:

import android.os.Bundle import android.support.v7.app.AppCompatActivity class MainActivity: AppCompatActivity () {companion object {const val APIKey = "INSERT-YOUR-API-KEY"} negeer plezier onCreate (opgeslagenInstanceState: Bundle?) { super.onCreate (saveInstanceState) setContentView (R.layout.activity_main) // Als de API-sleutel begint met "INSERT" ... // if (APIKey.startsWith ("INSERT")) {// geef dan de volgende toast weer ... .// Toast.makeText (dit, "U hebt uw API-sleutel niet bijgewerkt", Toast.LENGTH_SHORT) .show ()} anders {... ... ...

Activa ophalen

U kunt elk item op de Google Poly-site kiezen, maar ik gebruik dit model van planeet Aarde.

U haalt een activum op met behulp van de ID, die aan het einde van de URL-naaktslak verschijnt (gemarkeerd in de vorige schermafbeelding). We combineren dit activum-ID met de Poly API-host, "https://poly.googleapis.com/v1".

import android.content.Intent import android.os.Bundel import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {companion object {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} het plezier onCreate (saveInstanceState: Bundle?) Overschrijven {super.onCreate (saveInstanceState) setContentView (R.layout.activity_main) if ( APIKey.startsWith ("INSERT")) {Toast.makeText (dit: "U hebt uw API-sleutel niet bijgewerkt", Toast.LENGTH_SHORT) .show ()} anders {

Vervolgens moeten we een GET-verzoek indienen bij de item-URL, met behulp van de methode httpGet (). Ik geef ook op dat het antwoordtype JSON moet zijn:

import android.content.Intent import android.os.Bundel import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {companion object {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} het plezier onCreate (saveInstanceState: Bundle?) Overschrijven {super.onCreate (saveInstanceState) setContentView (R.layout.activity_main) if ( APIKey.startsWith ("INSERT")) {Toast.makeText (dit, "U hebt uw API-sleutel niet bijgewerkt", Toast.LENGTH_SHORT) .show ()} anders {// Voer een serveroproep en geef de gegevens door met de "ListOf" -methode // assetURL.httpGet (listOf ("key" to APIKey)). ResponseJson {request, response, result -> // Doe iets met de response // result.fold ({val as set = it.obj ()

Het item kan verschillende indelingen hebben, zoals OBJ, GLTF en FBX. We moeten bepalen dat het activum het OBJ-formaat heeft.

In deze stap haal ik ook de naam en URL op van alle bestanden die we moeten downloaden,
inclusief het primaire bestand van het activum ('root'), plus alle bijbehorende materiaal- en textuurbestanden ('resources').

Als onze applicatie het item niet correct kan ophalen, wordt er een toast weergegeven waarin de gebruiker wordt geïnformeerd.

import android.content.Intent import android.os.Bundel import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {companion object {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} het plezier onCreate (saveInstanceState: Bundle?) Overschrijven {super.onCreate (saveInstanceState) setContentView (R.layout.activity_main) if ( APIKey.startsWith ("INSERT")) {Toast.makeText (dit, "U hebt uw API-sleutel niet bijgewerkt", Toast.LENGTH_SHORT) .show ()} anders {// Maak een GET-verzoek aan de activ-URL // assetURL. httpGet (listOf ("key" to APIKey)). responseJson {request, response, result -> // Doe iets met de response // result.fold ({val asset = it.obj () var objectURL: String? = null var materialLibraryName: String? = null var materialLibraryURL: String? = null // Controleer de indeling van het activum, met behulp van de array “formaten” // val assetFormats = asset.getJSONArray ("formats") // Doorloop alle formaten // voor (i in 0 tot assetFormats.length ()) { val currentFormat = assetFormats.getJSONObject (i) // Gebruik formatType om het opmaaktype van deze bron te identificeren. Als het formaat OBJ is ... .// if (currentFormat.getString ("formatType") == "OBJ") {//... haal dan het 'root'-bestand van deze bron op, dwz het OBJ-bestand // objectURL = currentFormat. getJSONObject ("root") .getString ("url") // Alle afhankelijkheden van het rootbestand ophalen // materialLibraryName = currentFormat.getJSONArray ("resources") .getJSONObject (0) .getString ("relativePath") materialLibraryURL = currentFormat.getJSONArray ("resources") .getJSONObject (0) .getString ("url") break}} objectURL !!. httpDownload (). bestemming {_, _ -> Bestand (filesDir, "globeAsset.obj")} .response {_ , _, result -> result.fold ({}, {// Als u het OBJ-bestand niet kunt vinden of downloaden, geeft u een fout weer // Toast.makeText (dit, "Kan bron niet downloaden", Toast.LENGTH_SHORT ) .show ()})} materialLibraryURL !!. httpDownload (). bestemming {_, _ -> Bestand (filesDir, materialLibraryName)} .response {_, _, result -> result.fold ({}, {Toast. makeText (dit, "Kan bron niet downloaden", Toast.LENGTH_SHORT) .show ()})}}, { Toast.makeText (dit, "Kan bron niet downloaden", Toast.LENGTH_SHORT) .show ()})}}}

Als u het project op dit moment op uw Android-smartphone of -tablet of Android Virtual Device (AVD) installeert, wordt het item met succes gedownload, maar wordt het in de app niet weergegeven. Laten we dit nu oplossen!

Een tweede scherm maken: navigatie toevoegen

We gaan het activum in volledig scherm weergeven, dus laten we ons bestand main_activity.xml bijwerken met een knop die, wanneer erop wordt getikt, de activiteit Volledig scherm start.

Laten we nu de onClickListener toevoegen aan het einde van het bestand MainActivity.kt:

import android.content.Intent import android.os.Bundel import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {companion object {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} het plezier onCreate (saveInstanceState: Bundle?) Overschrijven {super.onCreate (saveInstanceState) setContentView (R.layout.activity_main) if ( APIKey.startsWith ("INSERT")) {Toast.makeText (dit, "U heeft uw API-sleutel niet bijgewerkt", Toast.LENGTH_SHORT) .show ()} else {assetURL.httpGet (listOf ("key" to APIKey))). responseJson {request, response, result -> result.fold ({val asset = it.obj () var objectURL: String? = null var materialLibraryName: String? = null var materialLibraryURL: Str ing? = null val assetFormats = asset.getJSONArray ("formaten") voor (i in 0 tot assetFormats.length ()) {val currentFormat = assetFormats.getJSONObject (i) if (currentFormat.getString ("formatType") == "OBJ" ) {objectURL = currentFormat.getJSONObject ("root") .getString ("url") materialLibraryName = currentFormat.getJSONArray ("resources") .getJSONObject (0) .getString ("relativePath") materialLibraryURL = currentFormat.getJSONArray ("resources" "resources" ) .getJSONObject (0) .getString ("url") break}} objectURL !!. httpDownload (). bestemming {_, _ -> Bestand (filesDir, "globeAsset.obj")} .response {_, _, resultaat -> result.fold ({}, {Toast.makeText (dit, "Kan bron niet downloaden", Toast.LENGTH_SHORT) .show ()})} materialLibraryURL !!. httpDownload (). bestemming {_, _ -> Bestand (filesDir, materialLibraryName)} .response {_, _, result -> result.fold ({}, {Toast.makeText (dit, "Kan bron niet downloaden", Toast.LENGTH_SHORT) .show ()})}}, {Toast.makeText (dit, "Kan bron niet downloaden", Toast.LENGTH_SHORT) .sh ow ()})} // Implementeer een knop // displayButton.setOnClickListener {val intent = Intent (this, SecondActivity :: class.java) startActivity (intent); }}}

Een 3D-canvas bouwen

Laten we nu de activiteit maken waarin we ons bedrijfsmiddel op volledig scherm weergeven:

  • Houd Control ingedrukt en klik op het bestand MainActivity.kt van uw project en selecteer "Nieuw> Kotlin-bestand / klasse".
  • Open de vervolgkeuzelijst 'Soort' en selecteer 'Klasse'.
  • Geef deze klasse de naam 'SecondActivity' en klik vervolgens op 'OK'.

Om een ​​3D-object te tekenen, hebben we een 3D-canvas nodig! Ik ga de P3D-renderer van Processing for Android gebruiken, wat betekent dat de PApplet-klasse wordt uitgebreid, de methode settings () wordt vervangen en vervolgens P3D als argument wordt doorgegeven aan de methode fullScreen (). We moeten ook een eigenschap maken die het Poly-activum vertegenwoordigt als een PShape-object.

private fun displayAsset () {val canvas3D = object: PApplet () {var polyAsset: PShape? = null-instellingen voor plezier overschrijven () {fullScreen (PConstants.P3D)}

Vervolgens moeten we het PShape-object initialiseren door de methode setup () te negeren, de methode loadShape () aan te roepen en vervolgens het absolute pad van het .obj-bestand door te geven:

leuke instelling opheffen () {polyAsset = loadShape (File (filesDir, "globeAsset.obj"). absolutePath)}

Tekening op het canvas van P3D

Om op dit 3D-canvas te tekenen, moeten we de methode draw () overschrijven:

leuke tekening overschrijven () {achtergrond (0) vorm (polyAsset)}}

Standaard zijn veel van de items die uit de Poly API zijn opgehaald aan de kleine kant, dus als u deze code nu uitvoert, ziet u het item mogelijk niet eens, afhankelijk van uw schermconfiguratie. Bij het maken van 3D-scènes maakt u meestal een aangepaste camera, zodat de gebruiker de scène kan verkennen en uw 3D-middelen vanaf de volledige 360 ​​graden kan bekijken. Dit valt echter buiten het bestek van dit artikel, dus ik zal de grootte en positie van het activum handmatig wijzigen om te zorgen dat het comfortabel op het scherm past.

U kunt de grootte van het activum vergroten door een negatieve waarde door te geven aan de methode scale ():

schaal (-10f)

U kunt de positie van het activum in de virtuele 3D-ruimte aanpassen met de methode translate () en de volgende coördinaten:

  • X. Plaatst het activum langs de horizontale as.
  • Y. Plaatst het activum langs de verticale as.
  • Z. Dit is de as "diepte / hoogte", die een 2D-object omzet in een 3D-object. Positieve waarden wekken de indruk dat het object naar u toe komt en negatieve waarden wekken de indruk dat het object van u af beweegt.

Merk op dat transformaties cumulatief zijn, dus alles wat er gebeurt nadat de functie het effect accumuleert.

Ik gebruik het volgende:

vertalen (-50f, -100f, 10f)

Hier is de voltooide code:

leuke tekening overschrijven () {achtergrond (0) schaal (-10f) translate (-50f, -100f) // Teken het element door de methode shape () aan te roepen // shape (polyAsset)}}

Vervolgens moeten we het bijbehorende lay-outbestand maken, waar we het 3D-canvas als een FrameLayout-widget toevoegen:

  • Houd Control ingedrukt en klik op de map "res> layout" van uw project.
  • Selecteer 'Layout resource file'.
  • Geef dit bestand de naam 'activity_second' en klik vervolgens op 'OK'.

Nu we onze “asset_view” FrameLayout hebben, moeten we onze SecondActivity hiervan op de hoogte stellen! Ga terug naar het SecondActivity.kt-bestand, maak een nieuwe PFragment-instantie en wijs deze in de richting van onze widget "asset_view":

import android.os.Bundle import android.support.v7.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_second. * importverwerking.android.PFragment importverwerking.core.PApplet importverwerking.core.PConstants importverwerking.core .PShape import java.io.File class SecondActivity: AppCompatActivity () {plezier vervangen onCreate (opgeslagenInstanceState: Bundle?) {Super.onCreate (opgeslagenInstanceState) setContentView (R.layout.activity_second) displayAsset ()} private fun displayAsset () {val canvas3D = object: PApplet () {var polyAsset: PShape? = null instellingen voor plezier overschrijven () {fullScreen (PConstants.P3D)} instellingen voor plezier opheffen () {polyAsset = loadShape (File (filesDir, "globeAsset.obj"). absolutePath)} opheffen fun draw () {background (0) schaal (-10f) vertaal (-50f, -100f) vorm (polyAsset)}} // Voeg de volgende // val assetView = PFragment (canvas3D) assetView.setView (asset_view, this)}} toe

De laatste stap is het toevoegen van de SecondActivity aan uw manifest:

// Voeg het volgende toe //

Uw project testen

We zijn nu klaar om het voltooide project te testen! Installeer het op uw Android-apparaat of AVD en zorg ervoor dat u een actieve internetverbinding hebt. Zodra de app wordt gestart, wordt het item gedownload en kunt u het bekijken door op de knop "Activa weergeven" te tikken.

Je kunt dit complete project downloaden van GitHub.

Afsluiten

In dit artikel hebben we gekeken hoe de Poly API te gebruiken om een ​​3D-activum tijdens runtime op te halen en hoe dat activum weer te geven met behulp van de Processing voor Android-bibliotheek. Denkt u dat de Poly API het potentieel heeft om VR- en AR-ontwikkeling voor meer mensen toegankelijk te maken? Laat het ons weten in de reacties hieronder!

Verwant

  • Google brengt AR-apps in 2018 naar 'honderden miljoenen' Android-apparaten
  • Google leert je gratis over AI en machine learning
  • 15 beste VR-games voor Google Cardboard
  • 10 beste VR-apps voor Google Cardboard
  • Wat is Google Fuchsia? Is dit de nieuwe Android?
  • Wat is Google Duplex? - functies, releasedatum en meer
  • Hoe maak je een VR-app voor Android in slechts 7 minuten
  • Mobiele VR-headsets - wat zijn uw beste opties?

C-programmering i een van de meet gevraagde codeertalen ter wereld, met mogelijkheden om uw eigen app, programma' en game te maken. Er i echter een leercurve bij betrokken....

Een gebruikte martphone kopen of geen gebruikte martphone kopen? Voor de zuinige menen onder on lijkt de vraag tamelijk vanzelfprekend: gebruikte telefoon zijn goedkoper, du hoe beter koopje....

De Meest Lezen