Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

laztrezort

Member Since 20 May 2009
Offline Last Active May 16 2013 08:00 PM
-----

#5026178 Sprite batching and other sprite rendering techniques

Posted by laztrezort on 27 January 2013 - 02:45 PM

Just call glBufferSubData once when a batch is ready to be drawn, specifying the count or whatever parameter it is to set the amount of data to upload, and only draw the number of vertices (or indices if using draw elements) you need for the current batch.

The index buffer can be predifined, and will not change.

Here is some C#-ish pseudocode from a project of mine that outlines what I do:
spriteVertex[] vertices = new spriteVertex[BATCHSIZE * 4];
int[] indices = new int[BATCHSIZE * 6];

MakeBuffers(ref vertBufferID, ref indBufferID, ref vaoID);

// fill the buffer with default (0s) on creation
glBufferData(BufferTarget.ArrayBuffer, sizeof(spriteVertex) * vertices.Length, vertices);

// fill index buffer with pre-calc'd values
PreCalcIndexBuffer();

...

class TileBatch
{
  public void Begin(Texture2D texture)
  {
    currentSprite = 0;
    currentTexture = texture;
  }

  public void Draw(Rect dest, Rect src, Color color)
  {
    // if we are out of room, flush (draw) the current batch
    if(currentSprite > BATCHSIZE)
    {
      flush();
      currentSprite = 0;
    }

    // calc all the vertex attributes for this sprite and store them in our CPU array
    int vertStart = currentSprite * 4;
    vertices[vertStart].position.X = dest.X;
    vertices[vertStart].texcoord.X = src.X;
    ...
    vertices[vertStart + 3].position.Y = destRect.Bottom;
    vertices[vertStart + 3].texcoord.Y = src.Bottom;
    
    currentSprite++;
  }

  public void End()
  {
    Flush();
  }

  private void Flush()
  {
    // set program uniforms and state
    shaderProgram.Texture = currentTexture;
    shaderProgram.mvpMatrix = currentMVP;
    ...

    int numberToDraw = currentSprite;

    BindVAO();
    
    // upload our CPU vertex data to GPU
    glBufferSubData(BufferTarget.ArrayBuffer, 0, sizeof(SpriteVertex) * numberToDraw, vertices);
    
    // draw the appropriate number of sprites
    DrawElements(BeginMode.Triangles, numberToDraw);
  }
}

In use:
MyBatch.Begin(myTexture);

MyBatch.Draw(Rect(0,0,32,32), Rect(50,50,32,32), Color.White);
MyBatch.Draw(...)
...

MyBatch.End();



#5025676 Sprite batching and other sprite rendering techniques

Posted by laztrezort on 25 January 2013 - 11:43 PM

The simplest(?) batching method that I understand is using a GL_STREAM_DRAW VBO that gets the vertex data of all sprites with a glBufferData call each frame, possibly using an additional GL_STATIC_DRAW VBO with all the sprites that I know are static and persistent.

Pretty much, just process and store the vertices CPU side until ready to draw. Then send the proper state and the vertices to the buffer and draw.

Use glBufferSubData though - from what I understand, glBufferData destroys & re-creates the buffer each time with an overhead cost.

Would sprite batching be significantly more performant than my unit-quad VBO approach?

Probably - reducing the number of separate draw calls is generally a very effective optimization. If you are having performance issues, this would definitately be the first thing to try.

With a simple batch similar to above, written in C# and using OpenTK, and without any real optimization, I can easily get many thousands of sprites on the screen each frame with plenty of both CPU & GPU to spare for other tasks.


#5024148 Dungeon generation method

Posted by laztrezort on 21 January 2013 - 08:32 PM

Just spit-balling here:

Looking at your example, it looks like a rectangle based generation (BSP tree or other) - but with random regions (leaf nodes) joined together. Perhaps you can get the same affect with a second pass over a BSP generated dungeon, joining random regions (within size constraints)?

Also, I'm not really sure if this is applicable here, but it might be worth experimenting with: http://doryen.eptalys.net/articles/dungeon-morphing

Perhaps you could "lerp" a type of pseudo-random noise with a BSP dungeon to get something like this.


#5016995 Small Novice Dev Group looking for advice.

Posted by laztrezort on 03 January 2013 - 12:17 AM

My opinion:

C# (and later, XNA) would be a fine place to start. Between the tools, the language and the amount of info available, C# is fairly enjoyable to work with. XNA itself also lends itself to relatively quick development.

I do not know of any specific beginner books (see below for a link), but generally it is advised to ignore all those "Learn XXX in YYY days" types of fast-track books - get the basics of the language down first. No need to jump straight into graphics, maths etc. before learning general programming concepts and a bit about the specific syntax & usage of C# itself. Your first game(s) will likely be text-based and very simple.

There is a huge amount of info, tutorials and sample code available for C# and XNA, which will come in handy as you progress.

And, of course this site is also a great resource, there are some very helpful people here. Here you might find a starting point for beginner books ideas: http://www.gamedev.net/topic/626106-c-books/

There are many other "getting started in C#" threads here if you poke around some.

It sounds like you have realistic goals, which will help greatly in not becomming discouraged too soon. So you are already on the right track.

Good luck!


#5009300 creating random rectangles to cover a grid

Posted by laztrezort on 10 December 2012 - 09:50 PM

The simplest way I can think of (that I've personally used in the past) is to use Binary Space Partition - where you split the rectangle down recusively until you have the desired number of sub rectangles.

This describes the method as used in procedurally generating a 2d dungeon:
http://roguebasin.roguelikedevelopment.org/index.php?title=Basic_BSP_Dungeon_generation


#4980942 C# List<T>.Find

Posted by laztrezort on 17 September 2012 - 10:56 AM

Wild guess, but do you have the required using statements?

using System.Collections.Generic;
using System.Linq;



#4980161 What is the optimal way to store a tile based world in an array?

Posted by laztrezort on 14 September 2012 - 02:10 PM

What I have done in the past, is store an identifier in each cell, which can be used to lookup data about that terrain type from a database of terrain types.  Then use the terrain data to draw, check movement, or whatever else.

Something like this (pseudocode):

class Tile
{
	 int TerrainIndex;
	 ...
}
...
class TerrainType
{
	 Image image;
	 bool IsWalkable;
	 ...
}
...
List<TerrainType> TerrainTypes...
...
DrawTile(Cell cell)
{
	 Image img = TerrainTypes[cell.TerrainIndex];
	 Renderer.DrawImage(img);
}

Thinking of cells as "just data" in this way should eliminate the need for switch cases or messy inheritance.  This also allows you to keep the terrain data separate from implentation, say in a text file, that can be tweaked outside of diving through layers of code.

Differentiate between "static" and "dynamic" data.  Static data can go in the database, it will not change on a per-cell basis.  Dynamic data (state) can change from cell to cell, thus needs to be stored for each cell.  Example of possible static data:  movement blocking, sprite image, flags such as causes_damage or is_transparent, etc.  Examples of possible dynamic data:  per cell light level, damage level, etc.  There is no hard rule for which belongs where - it depends on the gameplay, how the rendering is set up, etc.


#4980039 floating point precision problem

Posted by laztrezort on 14 September 2012 - 07:03 AM

I was wondering if using decimal here would be preferable?


AFAIK, Decimal is used mainly for financial calculations - i.e. I believe it works best for base 10 numbers in a relatively limited range, and even it will not be infinitely precise of course.

Here is an article with some basic tips on using floating point: http://www.codeproje...int-Programming


#4979805 What are the most important things that should make me consider moving to C++?

Posted by laztrezort on 13 September 2012 - 12:48 PM

I'd agree with Telastyn, except for maybe adding "just for the sake of learning it" to the list.  Keep in mind that going from C# to C++ you will generally see a massive reduction in productivity.  This is even ignoring the time it will take to pick up C++.  The only time I have seriously gone back to use C++ in the last 6 or so years is when someone paid me to - and they paid me by the hour.

Going from XNA to DirectX, you will see yet another massive reduction in productivity.  This is not meant to discourage, but keep this in mind if your goal is to get a specific project finished, you will need to choose for yourself depending on what your goals are.


#4978470 The "best" OpenGL/.NET wrapper?

Posted by laztrezort on 09 September 2012 - 09:50 PM

As far as I know, there are only two viable choices, Tao and OpenTK.  Recently I threw together a minimal 2D rendering backend using OpenTK, at the same time learning (modern-ish) OpenGL.  Can't say I had any issues with the wrapper, although be aware there are newer nightly builds available.

I looked briefly at Tao, but it looked a bit too thin of wrapper for what I wanted, and doesn't look updated much anymore.

From the OpenTK homepage they claim it supports the latest versions of OpenGL, though I only used a small subset of OGL, and have so far only built/tested under Windows.


#4972882 Need Help Making a map

Posted by laztrezort on 23 August 2012 - 10:20 PM

To add to what SOTL said:

I had success years ago using a tile map editor called Mappy http://www.tilemap.co.uk/mappy.php with Allegro - there is even a "playback" library you can download that has a minimal tile engine built in.

Note that this was years ago, so I'm not sure which version of Allegro it works directly with, so YMMV.


#4967206 XNA Standalone executable or installer?

Posted by laztrezort on 07 August 2012 - 06:47 PM

So in other words you need the XNA 4.0 framework to run a program created in XNA?


Yes.  Here is a rundown of methods to distribute an XNA application: http://rbwhitaker.wi...-game-tutorials

Using ClickOnce (the fourth tutorial) is probably the easiest way to distribute an XNA game.

Edit:  to clarify, using ClickOnce will ensure that the end user has the necessary XNA libs and .NET libs, and downloading them if they do not.


#4966822 NPC dialogues : file or script?

Posted by laztrezort on 06 August 2012 - 03:25 PM

I would like to see an example in which writing a script is required (in lua for example), because I didn't found anything on the web..Most of examples I've read are writable in a simple XML format file! So when is suggested using scripting language? Ok, when the behaviour isn't static like NPC dialogue, but I can't figure that kind of situation!


You could store flags and/or condition keys with the XML file, so that certain dialog node is only produced if the attached flag/condition is true.  You can also store "magic" attributes to do hardcoded actions, such as "Open Store" or "Give Key to Dungeon".  You can insert special embedded strings into the dialog to control things such as "Pause Here" or "Ask for yes/no".

At some point, however, you will realize that you are basically re-inventing a scripting language, as the list of attributes and magic keys and embedded codes grows.  Animations, taking player items, healing the player, etc.  You may find that your design has become brittle, in that you now have to go back to the source code to change & add dialog logic, do a full re-compile etc to test.

At his point, it may be worth looking into leveraging full scripting, where all of the dialog logic is isolated into seperate scripts.  These scripts can be modified (sometimes during runtime!) during testing & debugging without having to change the main source code.

The tradeoff is the complexity of adding the scripting support, which isn't exactly trivial.

If you haven't already, plan out exactly what the extant of and logic of your dialog will be.  From your OP, if that is the extent of your dialog system, then it looks like you can just implement [Condition Flag][Dialog Node] nodes in a data file and call it day.


#4965540 What engine would be good to make 2d games?

Posted by laztrezort on 02 August 2012 - 08:51 AM

Unfortunately, this question can really only be answered by you, since it depends on many things, such as your comfort level and available time for learning programming, specific goals, type of 2d games you are interested in developing, etc.

However, to clarifty one point, you can definitely make 2d games in Unity - in fact, there is an entire tutorial available on their site for making a 2d platformer.  My suggestion is run through that tutorial and see what you think.


#4965534 2d lighting

Posted by laztrezort on 02 August 2012 - 08:41 AM

There a couple XNA libraries for dynamic lighting/shadows, one is Krypton http://krypton.codeplex.com/ I only know of its existance, I've never personally used it.

Here is an article describing one technique: http://www.gamedev.n...t-shadows-r2032

Here's another technique using XNA and shaders: http://www.catalinzi...mic-2d-shadows/

I thought there used to be another good article on 2d lighting on this site, it was a bit older but may have been useful, unfortunately I can't seem to find it.




PARTNERS