Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

13. January 2016

 

I recently published a tutorial on creating a game level in Blender over three parts, but I never actually illustrated how such a level would be used by a game engine.  A user on /r/gamedev asked exactly this question, so I figured I would throw together a quick post showing how such content could be loaded into a game engine, in this case LibGDX.  This code is lifted directly from my LibGDX tutorial series, as is further information on how to export your model from Blender.

 

Here is the process...

First, and this is LibGDX specific... there is a data size limit of short int (32k) for the number of indices you can have.  This means by default the landscape we have generated is too dense for use in LibGDX.  I simply applied the decimate modifier to the plane object to get my face count down to 8,600.

image

 

Now export the scene as an FBX file.  Default settings should work fine.

 

Next you need the FBX-Conv for your platform, which can be downloaded here.

 

With the FBX file and the proper fbx-conv.exe extracted to the same folder, run the command:

fbx-conv.exe -f -o G3DJ level.fbx

Obviously change the exe name and level name to match your own.  This will generate a g3dj file, copy it to the assets folder of your LibGDX project.  You also need to copy in the Skybox and Ground textures you used in this project to the assets folder.  If these files are embedded in your .Blend file, you can export them using the command File->External Data->Unpack All Into Files or you can manually save the files externally in UV Image Editor.

image

 

Now with all of these files copied into your assets folder, write the following code:

package com.gamefromscratch.levelloader;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Files.FileType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.loader.G3dModelLoader;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.JsonReader;
import com.badlogic.gdx.utils.UBJsonReader;
import com.badlogic.gdx.graphics.g3d.utils.AnimationController;
import com.badlogic.gdx.graphics.g3d.utils.AnimationController.AnimationDesc;
import com.badlogic.gdx.graphics.g3d.utils.AnimationController.AnimationListener;



public class LevelLoader implements ApplicationListener {
	private PerspectiveCamera camera;
	private ModelBatch modelBatch;
	private Model model;
	private ModelInstance modelInstance;
	private Environment environment;

	@Override
	public void create() {
		camera = new PerspectiveCamera(
				90,
				Gdx.graphics.getWidth(),
				Gdx.graphics.getHeight());

		camera.position.set(0f,0f,300f);
		camera.lookAt(0f,0f,1f);

		camera.near = 0.1f;
		camera.far = 5000.0f;

		modelBatch = new ModelBatch();

		JsonReader jsonReader = new JsonReader();
		G3dModelLoader modelLoader = new G3dModelLoader(jsonReader);
		model = modelLoader.loadModel(Gdx.files.getFileHandle("level.g3dj", FileType.Internal));
		modelInstance = new ModelInstance(model);

		environment = new Environment();
		environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.8f, 0.8f, 0.8f, 1.0f));

	}

	@Override
	public void dispose() {
		modelBatch.dispose();
		model.dispose();
	}

	@Override
	public void render() {
		Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
		Gdx.gl.glClearColor(1, 1, 1, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

		camera.rotateAround(Vector3.Zero, new Vector3(0,1,0),1f);
		camera.update();

		modelBatch.begin(camera);
		modelBatch.render(modelInstance, environment);
		modelBatch.end();
	}

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

	@Override
	public void pause() {
	}

	@Override
	public void resume() {
	}
}

 

And when you run this code:

resizedLevelGif

13. January 2016

 

To be honest, I am shocked it took this long.  JetBrains have made an excellent Java IDE for ages.  Then they released IDEs for just about every single language out there, as well as the C# refactoring tool Resharper, but never a full blown C# IDE, until today that is.

Interestingly though, this isn’t running on a JVM like their others (IntelliJ, Webstorm, PHPStorm), instead:image

Project Rider is a standalone IDE built on the IntelliJ Platform, much like WebStorm, DataGrip and our other IDEs.

The difference however, is that instead of reimplementing ReSharper’s features on the IntellIJ Platform, which runs on the JVM, we’re using ReSharper in a headless mode, out of process, and communicating with it via a very fast custom binary protocol. As such, the backend continues to be ReSharper written in C# running on .NET or Mono, and the frontend is written in Kotlin, talking to the IntelliJ Platform’s APIs.

 

And you may ask, why create a C# IDE with Visual Studio and Xamarin filling the need?

Well you kept asking us, so we finally got around to doing it!

Jokes aside though, our main reason is to provide choice. We believe that we can provide a great user experience for developers that might be interested in using alternative environments.

So why now? Because we believe it is the right time due to several factors:

  • We’ve been working for several years in allowing ReSharper to work in different environments, independently of Visual Studio. An example of this is dotPeek.
  • It’s quite clear that there’s an ever increasing tendency of developers using non-Windows platforms, and we’d like to give them the same experience they’ve come to know and love with ReSharper.
  • Finally, Microsoft moving its platform and C# language towards Open Source, along with initiatives such as CoreCLR, have been an added incentive.

 

So, what timeframe are we looking at then?

We’re aiming to open a private EAP in the coming weeks, towards the end of February. We’ll announce the signup form here on the blog, as well as on Twitter.

Soon after the private EAP we’ll move to a public EAP. When this will happen very much depends on the feedback we get from the early testers. Our aim is to release sometime in Autumn 2016.

 

For more details on Project Rider, click herehttp://blog.jetbrains.com/dotnet/2016/01/13/project-rider-a-csharp-ide.

GameDev News

13. January 2016

 

Welcome to the final part of our three part series on level creation using Blender.  In the first part of the tutorial we created a skybox for our world.  In the second we used a height map to create some terrain.  Today we are going to look at applying multiple textures to that terrain.

 

We are going to pick up where we left off, we have a large plane distorted to create our landscape.  If you haven’t already, apply the Displace modifier to make it permanent.  You should have already UV Unwrapped the plane object before we applied the displace modifier, giving us a nice even UV grid to work with.

 

Next we are going to need some textures to paint with.  Seamless textures work best as they can be tiled without creating a noticeable seam.  For this example however, I just downloaded a couple textures from TextureLib, a grass, rock and water texture.  Use whatever textures you wish to use.  Now that you have your textures, we need to import them into Blender.  I find the easiest way is to just add them as textures to the plane object and name them appropriately, like so:

image

No need to setup mapping coordinates or anything else, as we arent going to be using these textures directly, they just needed to be made available for Blender.

 

Now with your Plane selected, make sure there is a Material, and if there isn’t, create a new one.

image

 

Now switch over to the texture tab and add a new texture of type Image or Movie, then click the New button:

image

 

Call in GroundTexture or something similar:

image

 

You may find 1024x1024 is too low res for a large terrain, so you might want to try 2048x2048.  Now it’s time to start painting our texture.  Configure your Blender windows so you have a 3D view on one side and the UV/Image Editor on the other, and switch the 3D view to Texture Paint mode, like so:

image

 

Now in the UV editor, make sure that your GroundTexture is active:

image

 

In the 3D view, in the Tools (T) sidebar, we now set the texture we want to paint with.  Locate the texture area, click the thumbnail icon and select one of your textures, like so:

GIF

 

Now we can paint directly on the 3D model.  You have a ton of control over your brush, but the two most important settings are these:

image

 

These set the size of your brush and the strength of your paint tool.  Now simply paint the terrain as you desire:

GIF2

 

You will notice that the texture updated automatically the the UV/Image Editor:

image

 

If you prefer, you can edit in the UV editor window instead, simply turn Edit mode on:

image

 

The brush settings from the 3D View Tools window will be applied to the UV editor in Paint mode.  Now simply change textures and repeat the process until your texture is complete.  When you are done, you may want to export your texture for use in an external engine.  In the UV/Image Editor, select Image->Save As Image:

image

 

End result:

image

 

Not the greatest looking level, but that’s due to lack of effort, not the tool.  Not bad for 20 minutes work.  Obviously there are other tasks you’d want to perform.  You probably want a normal or displacement map on the terrain to give it small surface level imperfections, and obviously you’d want to add static meshes for trees, shrubs etc... but that is simply a matter of doing more of the same.

 

The Video

Art, Design , ,

12. January 2016

 

Corona Labs, the makers of the popular Lua based mobile game engine, just release version 1.6 of Corona Editor.  Corona Editor is a light weight IDE built as a plugin for Sublime Text that enables debugging, code snippets, code completion and more.

Details of the 1.6 release from the blog announcement:

Corona Labs is happy to announce the availability of Corona Editor 1.6. This is an update for the add-on package for Sublime Text 2 and Sublime Text 3 that provides code completion, syntax highlighting, documentation, and debugging to Corona developers.

The release of 1.6 includes the following updates:

Debugger improvements
  • Fixed an issue with a hanging after pressing Shift+F10.
  • Fixed a bug with spaces in project pathnames.
  • Current status is now displayed in the “Console” pane.
  • The “Console” output is now cleaner.
  • Generally improved reliability.
Corona Editor Project improvements
  • On OS X, Corona EditorRun Project now uses the most recent daily build in the/Applications folder by default. It will fall back to the public build if there are no daily builds.
  • Removed project “build system.” The menu command Corona EditorRun Project or the Cmd+F10(Mac) Win+F10(Windows, maybe mapped to FN+F10) key sequence is much more reliable.
  • Added Clear Build Panel command to main menu and context menu.
Editing improvements
  • Fixed indentation of elseif blocks.
  • Latest code completions are up to date to daily build 2016.2803.

Learn more about Corona Editor.

GameDev News ,

12. January 2016

 

In Part One of our level creation in Blender tutorial series, we created a skybox to define the boundaries of our game level.  In this tutorial we are going to create the terrain for our level.  You will probably be surprised by just how much we can accomplish with almost zero effort.

 

Creating a Height Map

First we need a height map.  A height map is a remarkably simple concept that has been around for ages.  Essentially you are defining the height of a grid of terrain using a simple gray scale image.  You can create this image a couple of different ways.  First you can simply fire up any image editor, even MS Paint, and draw the texture.  The blacker the pixels, the lower the corresponding terrain, while a white pixel is as high as possible.  In addition to painting by hand there are several applications free and commercial that are capable of exporting a height map for you.  Examples include Terragen, Bryce and Geovox although there are many more.

 

For this example I’m simply going to use Paint.Net, but any image editing program would work fine.  Create a new image, while not a requirement, power of 2 ( 512x512, 1024x512, etc ) textures generally perform best.  Next set the base colour to 128/128/128 RBG, like so:

image 

Use the bucket fill tool to fill the entire image with this color.  This will be the neutral value, the resulting terrain will neither be elevated nor depressed.

 

You can then vary the grayscale by either raising/lowering all RGB values ( aka 43,43,43 or 250,250,250 ) or by sliding the V slider under HSV.  Remember, darker the colour, lower the terrain, lighter the colour, higher the terrain. 

 

In the end, I painted this rather simplistic height map.

heightmap

 

This will result in a high border around a pit of utter and complete dispair... muhahahaha.

 

Displacement in Blender

 

Now that we have a height map, it’s time to put it to use.  The good news is, this process is remarkably simple.  First we need something to apply the height map.  A height map needs an underlying mesh to apply to and if there aren’t sufficient vertices to be displaced by the height map, your results aren’t going to be very good.  This means we need a large flat surface with a decent amount of detail...  We need a plane.

I’m building on our scene from Part 1.  Set the 3d cursor to the origin, then create a new Plane via Add->Mesh->Plane.

image

 

Your scene should now look something like this:

image

 

Now we simply want to scale the Plane to the appropriate size, which is going to be entirely dependent on your skybox dimensions.  I personally scaled by a factor of 10.  After scaling it, we need to add details.  To do so, in edit mode, simply apply a subdivision (W->Subdivide)

image

 

Each time you perform this, you will double the mesh density.  I preformed it about a half a dozen times, resulting in a mesh with 32K triangles, which seems about appropriate.

image

While you are here you might as well UV unwrap your plane (U->U).  Also switch to Smooth shading:

image

Or your terrain is going to look VERY edgy and not at all organic.

 

Ok, now that we have our plane to deform, we need to load in our height map.  It doesn’t really matter where you add the texture, but I will go ahead and attach it to our plane.  Switch over to the textures tab, add a new image texture and load our heightmap.  It might make sense to rename it heightmap so it doesn’t get confusing, but you don’t have to:

image

 

Don’t bother setting UV coordinates, we aren’t going to be displaying this texture.

 

Now, in Object mode, with your Plane selected add a Displace modifier:

image

 

Now select your image in the texture field, change Texture Coordinates to UV, then select the UVMap.  If you don’t have the option, you didn’t UV Unwrap earlier!

image

 

Our height map will now be applied to our terrain:

image

 

Now we can use the Strength value of the Displace modifier to determine the strength of the height map on the displacement:

HeightMapInBlender

 

The Video

 

Back To Part One  ||  On To Part Three

Art, Design

Month List

Popular Comments

Godot Renderer Progress and Asset Library Update
Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon


1. November 2016

 

The Godot Game Engine has seen a slew of recent updates and is heavily under development in anticipation of Godot 3.0.  In the recent 2.1 update the Asset Library functionality was added (click here for details of the Godot 2.1 release), which is the Godot equivalent of the Unity or Unreal Engine asset stores.  Yesterday they announced the beta release of the web front end for browsing assets in the asset library using your web browser.

image

 

The announcement also documents the process of submitting your own asset to the library.

 

Another recent announcement from the Godot team was an update on the renderer changes for Godot 3.0.  The process is split across 3 milestones, and milestone 1 has just been reached, including:

Done for Milestone #1 (October 2016):
  • Make Godot compile against GLES 3.
  • Refactor the Image class to include modern data types.
  • Refactor the texture API to include more modern texture compression formats.
  • Refactor the rendering API to make it easier to understand (and contribute to!).
  • Write a more flexible, GLES 3 GLSL compatible shader language.
  • Write a more efficient Mesh format, which allows faster loading/saving.
  • Optimize scene rendering to use less function calls.
  • Make rendering always happen in Linear colorspace.
  • Investigate Physically Based Rendering (PBR), using GGX and alternatives.
  • Investigate cubemap filtering.
  • Create a new FixedMaterial that reflects PBR capabilities.
  • Implement PBR.
  • Convert gizmos to use the new FixedMaterial.
  • Add Lighting using PBR.
  • Investigate a ShadowAtlas allocation strategy.

 

Already there are some pretty powerful features in there and there are two more milestones to go.  There is a full description of the other milestones in the blog post as well as complete descriptions (and justifications) for the tasks completed in milestone one.

 

I have to say, the Godot engine is improving at a shockingly awesome rate these days.  If you are new to Godot, do be sure to jump into the GameFromScratch tutorial series.

GameDev News

blog comments powered by Disqus

Month List

Popular Comments