My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for

Table of Contents

MyFirstTriangle  
Creating a libgdx project, create your first triangle
Updated Apr 22, 2011 by nathan.s...@gmail.com

Introduction

The HelloWorld tutorial demonstrated how a libgdx application is structured by importing an existing project. Lets now go one step further and create project from scratch. This tutorial is more verbose in case the reader is also a novice with Eclipse. Future tutorials will have more concise instructions.

The source files for this guide is contained within MyFirstTriangle_<data>.zip in the Downloads page.

Creating the Desktop Project

Download the latest nightly zip and uncompress it to a temporary directory called libgdx-nightly.

Most of the code, including all of the game logic, will reside in a regular Java project. In Eclipse, click File -> New -> Java Project. Use my-first-triangle as the project name. In the JRE section, select JavaSE-1.6 or something similar, then click Finish.

Lets copy libraries contain all the necessary libgdx classes and methods into our workspace. In the Package Explorer view, right-click on the my-first-triangle folder, select New -> Folder, and name the new folder libs. From the libgdx-nightly directory, copy the following files into libs:

  • gdx-backend-jogl.jar
  • gdx-backend-jogl-natives.jar
  • gdx-sources.jar
  • gdx-natives.jar
  • gdx.jar

Now we'll add the libraries to our project so that our Java code can reference the classes in the libgdx libraries. Right click on the my-first-triangle folder again and select Properties. Go to the Java Build Path section, select the Libraries tab, click Add JARs..., navigate to the my-first-triangle/libs directory and select the files:

  • gdx-backend-jogl.jar
  • gdx-backend-jogl-natives.jar
  • gdx-natives.jar
  • gdx.jar

Eclipse can also show you the javadoc documention for the libgdx classes and methods you use. While still in the Libraries tab, expand the gdx.jar listing and double click on the entry named Source attachment. Click Workspace and navigate to the my-first-triangle/libs directory again, this time selecting gdx-sources.jar.

Now we can create a class that will draw our triangle. Expand the my-first-triangle folder, right-click on the src source directory and select New -> Package. Name it anything you want, in this example we'll use com.test.myfirsttriangle. Right-click on the new package, and select New -> Class, use the name MyFirstTriangle. In the Interfaces section, add the com.badlogic.gdx.ApplicationListener interface. Your new class should look something like this:

package com.test.myfirsttriangle;

import com.badlogic.gdx.ApplicationListener;

public class MyFirstTriangle implements ApplicationListener {

	@Override
	public void create() {
		// TODO Auto-generated method stub

	}

	@Override
	public void dispose() {
		// TODO Auto-generated method stub

	}

	@Override
	public void pause() {
		// TODO Auto-generated method stub

	}

	@Override
	public void render() {
		// TODO Auto-generated method stub

	}

	@Override
	public void resize(int width, int height) {
		// TODO Auto-generated method stub

	}

	@Override
	public void resume() {
		// TODO Auto-generated method stub

	}

}

We will soon add logic to MyFirstTriangle to draw a triangle. It will be capable of being run in either the desktop or Android environment. Lets create the desktop entry point now. In the same package as the MyFirstTriangle class, create another class, this time named MyFirstTriangleDesktop. Put a main method in the class so that it looks like this:

package com.test.myfirsttriangle;

import com.badlogic.gdx.backends.jogl.JoglApplication;

public class MyFirstTriangleDesktop {
	public static void main (String[] argv) {
		new JoglApplication(new MyFirstTriangle(), "My First Triangle", 480, 320, false);		
	}
}

The MyFirstTriangleDesktop class gives a starting point to launch a desktop application. It does that by creating a JoglApplication, passing in an instance of the MyFirstTriangle class to perform the rendering.

You can run the application right now by right-clicking on the MyFirstTriangleDesktop class in the Package Explorer and selecting Run As -> Java Application. The application should either look blank or display rendering artifacts (we'll fix that now).

Rendering a Triangle

The application shows a blank screen because our MyFirstTriangle class contains no rendering logic. Now it's time to finally create the code to draw a triangle. Replace the contents of the MyFirstTriangle class with this:

package com.test.myfirsttriangle;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;

public class MyFirstTriangle implements ApplicationListener {
	private Mesh mesh;

	@Override
	public void create() {
		if (mesh == null) {
			mesh = new Mesh(true, 3, 3, 
			        new VertexAttribute(Usage.Position, 3, "a_position"));		

			mesh.setVertices(new float[] { -0.5f, -0.5f, 0,
			                               0.5f, -0.5f, 0,
			                               0, 0.5f, 0 });	
			mesh.setIndices(new short[] { 0, 1, 2 });			
		}
	}

	@Override
	public void dispose() { }

	@Override
	public void pause() { }

	@Override
	public void render() {
                Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		mesh.render(GL10.GL_TRIANGLES, 0, 3);
	}

	@Override
	public void resize(int width, int height) { }

	@Override
	public void resume() { }
}

Run the project again. The application should now have a white triangle rendered in the middle of the screen:

Lets look at the changes we made. create() is called when the the rendering surface is created. We create a Mesh, which represents an object that will be drawn onscreen. Its constructor takes several parameters, but for now just take note of the VertexAttribute object we pass in. VertexAttribes are passed into the constructor to indicate what type of information the resulting mesh will contain. A mesh can potentially contain information regarding an object's position, color, texture, and more, but right now we'll only assign positional information. Since this mesh is a triangle, its position (and shape) is made up of three vertices, each denoted by three values (x, y, z) in the Cartesian coordiante. The three vertices for this mesh are located at (-0.5f, -0.5f, 0), (0.5f, -0.5f, 0), and (0, 0.5f, 0). We then set the mesh's indices, which is the order of the vertices, sort of like the order in a game of connecting the dots. In a simple shape like a triangle, the order doesn't matter because no matter which order you connect the vertices, it will always form a triangle. With more vertices, the order will greatly affect the final shape of the object.

When the application starts running the render() method is called again and again, basically repainting the screen as fast as it can. In render() we just tell the mesh we created earlier in create() to render itself. We also clear the screen each time render() is called. This is done via OpenGL directly.

For simplicity, we've skipped over many details of how different parameters change the behavior of the methods we used. These we'll go over in more detail in a later tutorials. In the mean time, you can see the javadoc of any method simply by hovering over the method name in the editor.

Setting Up an Android Project

Testing the application on Android only requires setting up a small Android project that refers to the desktop project we just created. In Eclipse, click File -> New -> Other.... Under the Android section, select Android Project and click Next. Name the project anything you want, for our example we'll use my-first-triangle-android. Under the Build Target section, select the Android platform version you're targetting. Different platform version have different support for OpenGL ES, but for our simple example, selecting Android 1.5 is fine. Enter any application name, we'll use my-first-triangle-android again. For package name, use the same package from the desktop project, enter com.test.myfirsttriangle. Check the Create Activity checkbox and give the activity a name, we'll use MyFirstTriangleAndroid. For Min SDK Version, type in the API Level of the platform version you chose earlier. That means for Android 1.5, enter 3 as the Min SDK Version. Click Finish.

Similar to the desktop project, we'll copy some libgdx libraries into our workspace. In the Package Explorer view, right-click on the my-first-triangle-android folder and select New -> Folder. Name the folder libs. Go back to the libgdx-nightly directory that stores all the libgdx library files and copy the following folders and files into the new libs directory:

  • armeabi/
  • armeabi-v7a/
  • gdx-backend-android.jar
  • gdx.jar
Again, we'll have to reference these files in our project settings. Right-click on the my-first-triangle-android folder and select Properties. Under the Java Build Path section, go to the Libraries tab. Click Add JARs... and navigate to my-first-triangle-android/libs and select gdx-backend-android.jar and gdx.jar.

We need to be able to reference the libgdx classes and also our previous project. While still in the Java Build Path screen, go to the Projects tab and click Add... and add the my-first-triangle project we created earlier.

The last task remaining is to modify our Activity to act as the Android entry point into the game code we wrote earlier. In the Package Explorer view, go into the MyFirstTriangleAndroid class and replace the contents with the following:

package com.test.myfirsttriangle;

import android.os.Bundle;

import com.badlogic.gdx.backends.android.AndroidApplication;

public class MyFirstTriangleAndroid extends AndroidApplication {
    @Override
	public void onCreate (Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		initialize(new MyFirstTriangle(), false);		
	}
}

Similar to our desktop entry point in the MyFirstTirangleDesktop class, all this code does is to create an instance of MyFirstTriangle to manage the rendering process. Run the application by right-clicking on the my-first-triangle-android folder and selecting Run As -> Android Application. The application is then installed on the device or compatible simulator. After the simulator is finished loading, the application should start automatically. If it doesn't, find and click on the my-first-triangle-android application icon. The application should look like this:

What's Next

That's it for your first triangle. To learn more about the fundamentals of the libgdx framework, check out the MeshColorTexture guide.

Updates

Feb 22 2011

  • use nightly build
  • added gdx-backend-jogl-natives.jar to libraries to hopefully remove link errors
  • MyFirstTriangle class is now importing com.badlogic.gdx.Gdx
  • updated the MyFirstTriangle_<date>.zip source files for this guide
  • added screen shots
Comment by shirazi...@yahoo.com, Nov 22, 2010

I'm very interested in libgdx. I developed a game in Cocos2d for the iPhone, but on Android, Cocos2d is pretty slow. The low-level approach of libgdx sounds very attractive to me.

When building the myfirsttriangle example, as well as running the gdx-helloworld example, I get an error message, stating: Exception in thread "main" java.lang.UnsatisfiedLinkError?: no gdx in java.library.path

What am I doing wrong, what did I forget?

Comment by thlo...@gmail.com, Nov 30, 2010

@Shirazi You need to copy over the .so files into your project directory. Search for the .so files in the zip file you downloaded, copy it over and it should work.

Comment by RunnerP...@gmail.com, Dec 9, 2010

I reject your IDE and substitute my own. ;)

So... what "android:name" do I put in the "uses-library" tag in my AndroidManifest??.xml? The Dev Guide says you're supposed to provide this in the docs :x

Shouldn't the example manifest given in the README (in the "android:configChanges" part) have a "uses-library" tag, anyway?

Thanks for making and supporting this (by all accounts) great library! I can't wait to start playing with it (not to mention making some moolah {Lord willing :)} with it)!

Comment by project member badlogicgames, Dec 11, 2010

Hi,

the uses-library part tag in the manifest is not necessary as we load the natives ourselves.

Ciao, Mario

Comment by colkas...@gmail.com, Dec 16, 2010

Hi,

gdx-natives.jar is not located in libgdx-0.81.zip linked to in the downloads link in the first step.

Comment by zuljin...@gmail.com, Dec 18, 2010

Hi Yf you don't have gdx-natives.jar then you should download latest nightly build from http://libgdx.l33tlabs.org/libgdx-nightly.zip. This should help.

Comment by dpkirch...@gmail.com, Dec 22, 2010

Using the nightly from tonight, I'm running in to:

GdxNativesLoader?: Couldn't unpack and load native 'libgdx.dylib'

I unpacked the jar and checked, libgdx.dylib exists and otool confirms I have the libraries necessary to load it. The exception is the standard:

Exception in thread "main" java.lang.UnsatisfiedLinkError?: no gdx in java.library.path

The fix was to add gdx-natives.jar to the Java Build Path in Eclipse.

Comment by develuti...@gmail.com, Jan 2, 2011

The gdx-natives.jar is not required, I can run this by adding the attribute tag to in the .classpath file like this

<classpathentry kind="lib" path="C:/app/eclipse-android/workspace/triangle/libs/gdx.jar">

<attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="my-first-triangle/libs"/>
</attributes>
</classpathentry>

if you run on windows make sure that the gdx.dll is in the libs directory. If you are using nix, use the .so files instead.

Comment by Araesm...@gmail.com, Jan 10, 2011

When I tried this out, one of the issues I noted was that it was missing an import line in the MyFirstTriangle class file.

import com.badlogic.gdx.Gdx;

Comment by dgoem...@gmail.com, Jan 16, 2011

I bumped into a few problems while trying to follow this. The setup is pretty simple except that the given download doesn't have the gdx-natives in it. So using the nightly, i ran into some other issues:

First it won't execute on Linux ( running Ubuntu 10.04 ). Issue that it churns out in the console window is:

Exception in thread "main" com.badlogic.gdx.utils.GdxRuntimeException: Creating window failed
	at com.badlogic.gdx.backends.jogl.JoglApplication.<init>(Unknown Source)
	at com.davidgoemans.Sweeper3D.Sweeper3D_Desktop.main(Sweeper3D_Desktop.java:10)
Caused by: java.lang.reflect.InvocationTargetException
	at java.awt.EventQueue.invokeAndWait(EventQueue.java:1000)
	at javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1351)
	... 2 more
Caused by: java.lang.RuntimeException: couldn't find libgluegen-rt-linux32.so in jar file.
	at com.badlogic.gdx.backends.jogl.JoglNativesLoader.loadLibrary(Unknown Source)
	at com.badlogic.gdx.backends.jogl.JoglNativesLoader.loadLibraries(Unknown Source)
	at com.badlogic.gdx.backends.jogl.JoglApplication.initialize(Unknown Source)
	at com.badlogic.gdx.backends.jogl.JoglApplication$1.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:216)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:602)
	at 
blah blah blah....

So i figured it was probably something broken in the nightlies that applies to linux. So i tried Android and all is well again in the world! Just thought i should let you know about the linux issue.

Thanks for the awesome engine!!! :)

Comment by yargata...@gmail.com, Jan 18, 2011

Hi,

As the poster above indicates I also run in the same/similar problem, but on windows XP 32: Code Exception in thread "main" com.badlogic.gdx.utils.GdxRuntimeException?: Creating window failed

at com.badlogic.gdx.backends.jogl.JoglApplication?.<init>(Unknown Source) at test.opengl.OpenGLTestDesktop.main(OpenGLTestDesktop.java:8)
Caused by: java.lang.reflect.InvocationTargetException?
at java.awt.EventQueue?.invokeAndWait(Unknown Source) at javax.swing.SwingUtilities?.invokeAndWait(Unknown Source) ... 2 more
Caused by: java.lang.RuntimeException?: couldn't find gluegen-rt-win32.dll in jar file.
at com.badlogic.gdx.backends.jogl.JoglNativesLoader?.load(Unknown Source) at com.badlogic.gdx.backends.jogl.JoglNativesLoader?.loadLibrary(Unknown Source) at com.badlogic.gdx.backends.jogl.JoglNativesLoader?.loadLibraries(Unknown Source) at com.badlogic.gdx.backends.jogl.JoglApplication?.initialize(Unknown Source) at com.badlogic.gdx.backends.jogl.JoglApplication?$1.run(Unknown Source) at java.awt.event.InvocationEvent?.dispatch(Unknown Source) at java.awt.EventQueue?.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread?.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread?.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread?.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread?.pumpEvents(Unknown Source) at java.awt.EventDispatchThread?.pumpEvents(Unknown Source) at java.awt.EventDispatchThread?.run(Unknown Source)
</source> code

Comment by ghd.214, Jan 18, 2011

hi, i get this exception

Exception in thread "main" com.badlogic.gdx.utils.GdxRuntimeException?: Creating window failed

at com.badlogic.gdx.backends.jogl.JoglApplication?.<init>(Unknown Source) at com.badlogic.gdxinvaders.GdxInvadersDesktop?.main(GdxInvadersDesktop?.java:25)
Caused by: java.lang.reflect.InvocationTargetException?
at java.awt.EventQueue?.invokeAndWait(EventQueue?.java:998) at javax.swing.SwingUtilities?.invokeAndWait(SwingUtilities?.java:1320) ... 2 more
Caused by: java.lang.UnsatisfiedLinkError?: Can't load library: /tmp/liblwjgl.so
at java.lang.ClassLoader?.loadLibrary(ClassLoader?.java:1702) at java.lang.Runtime.load0(Runtime.java:770) at java.lang.System.load(System.java:1003) at org.lwjgl.Sys$1.run(Sys.java:69) at java.security.AccessController?.doPrivileged(Native Method) at org.lwjgl.Sys.doLoadLibrary(Sys.java:65) at org.lwjgl.Sys.loadLibrary(Sys.java:81) at org.lwjgl.Sys.<clinit>(Sys.java:98) at org.lwjgl.openal.AL.<clinit>(AL.java:59)

Comment by schultz....@gmail.com, Feb 5, 2011

Hi,

I'm fairly new to Eclipse and Android and I'm getting this error when I try and run the application. I downloaded the nightly build to get the gdx.natives jar as well. What could be causing this error?

Exception in thread "main" java.lang.UnsatisfiedLinkError?: no gdx-64 in java.library.path

Thank You

Comment by Robinv...@gmail.com, Feb 13, 2011

Hi,

I'm new to Android development and wanted to get started with libgdx but I too get the exception: Exception in thread "main" java.lang.UnsatisfiedLinkError??: no gdx-64 in java.library.path

I'm using 64bit Windows 7.

Any leads would be much appreciated.

Comment by Robinv...@gmail.com, Feb 13, 2011

Hmm I checked out the libgdx project from the public svn repository. There I opened the HelloWorld project. It worked fine. The difference between the projects is that the project from the public repository had additional dependencies defined.

Comment by duri...@gmail.com, Feb 13, 2011

for those with java.lang.UnsatisfiedLinkError??: no gdx-64 in java.library.path

use nightly build. maybe it's because the 0.81 lacks "natives" jar, maybe because of some clash of 64bit java on windows. just get the nightly and use it.

Comment by michael....@gmail.com, Feb 18, 2011

Hi,

Sorry to continue this thread. I'm running Windows 7 64 bits, and I've tried all of the above, but the desktop version still doesn't launch. I've tried several of the latest nightly builds, all with the same result. Here is a summary:

Stable release (0.81): Launching the desktop version results in the exception

Exception in thread "main" java.lang.UnsatisfiedLinkError?: no gdx-64 in java.library.path

Latest nightly build (2011/02/18): Launching the desktop version results in the exception

Exception in thread "main" com.badlogic.gdx.utils.GdxRuntimeException?: Creating window failed ... Caused by: java.lang.UnsatisfiedLinkError?: org.lwjgl.DefaultSysImplementation?.getPointerSize()I

Note that in both cases, the Android version works perfectly fine.

Any help would much appreciated!

Best,

Michael

Comment by mrgu...@gmail.com, Feb 18, 2011

Using in Desktop version Mesh.render(...) crashes video graphic cards. After a while windows 7 manages to recover from video driver crash. While this problem is not present in Android version running on emulator. System specs: Windows 7 x64, java x86/x64 (while i noticed it uses x84 system to run), ATI HD 3870x2 1Gb OC Edition.

Comment by jukka.he...@gmail.com, Feb 20, 2011

I too had the "Creating window failed..." error in Win7 64-bit but it was fixed by adding also "gdx-backend-jogl-natives.jar" to the libs. Hope this helps.

Comment by cesarver...@gmail.com, Feb 20, 2011

Maybe this Wiki page might be improved adding the missing "import com.badlogic.gdx.Gdx;" in the MyFirstTriangle java class, and a refering to another pages with tutoriales explaining how to configure the jogl and lwjgl backends.

Comment by project member manifa...@gmail.com, Feb 21, 2011

Hey folks I've updated this guide to hopefully eliminate the UnsatisfiedLinkError?. In short, use the nightly instead of the package from the download page. Furthermore, the list of libraries to include now are:

gdx-backend-jogl.jar gdx-backend-jogl-natives.jar gdx-natives.jar gdx.jar

Please post any further problems.

Powered by Google Project Hosting