Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
The Glumslinger
Sep 24, 2008

Coach Nagy, you want me to throw to WHAT side of the field?


Hair Elf

The Cheshire Cat posted:

I did the same thing!

And it seems like the orbs are it. He said it was just a demo basically so I don't think there's supposed to be a lot of "game" there yet. It's a really cool concept though; taking advantage of the fact that scale is arbitrary in 3D modelling, you can do things like putting an entire, functional town on the head of a pin that you could pick up and carry around with you, or shrink down and interact with the town itself as if it was completely normal sized. Then just shrink down even more to find even more details that aren't evident at larger sizes. It's like the video game version of diving into a fractal.

You mentioned that you were worried about performance because of the complexity of objects in the scene - maybe you need some really rigorous LoD scaling? There's no point in fully rendering a whole maze that's only going to be visible as a single pixel on the screen, so you could maybe have it start dropping polygons as your relative size compared to an object changes? I've never used Unity so I'm not sure what kind of power you actually have to do that sort of thing, but to me that would be the key issue for performance. If you don't have any kind of scaling, you're just going to waste a ton of time rendering microscopic polygons.

Pretty much the main reason why I posted here. Yeah, that is basically the #1 technical concern for the project that we foresee. We shouldn't be rendering things when the player is way too large to deal with them.

We know we have a UDK license through the school, and they could probably get us other reasonably priced licenses, but we really have no clue what to use at this point.

Adbot
ADBOT LOVES YOU

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Tw1tchy posted:

Thanks for the help. I'll read through all that soon when I get the time. Also what I'd be using it for would be a tile-based game, so would all the stuff in it still be completely fine for what I need to do? And does it mention what libraries to use for netcode; because that's still a big problem of mine.
If you're doing a low-traffic game, and especially if you're just starting out, you might want to use a TCP connection. Winsock is the Windows API for sockets (network IO) and you can find the documentation for it pretty readily.

TCP basically lets you "listen" on a port number on one machine, connect to it via another, and then just send data back and forth which is guaranteed to arrive and arrive in order as long as the connection stays up.

Performance-sensitive games will usually use UDP instead, which doesn't handle negotiation and doesn't guarantee that data will arrive in order or at all, but doesn't stall and request resends when something goes wrong. i.e. Quake 3 doesn't care if you lose a world update packet if you've already received a more recent one, so it isn't going to stall the game and ask for a resend.

The Cheshire Cat
Jun 10, 2008

Fun Shoe

ShinAli posted:

Really digging SFML, should've used it instead of SDL in my project.

Is there any docs that talk about how an engine should be structured now and days? I wrote mine up as a basic tree to depict my scene graph but adding things like Bullet physics and a deferred rendering pipeline got real hacky for me (granted it is my first game engine). I just want to keep things under the hood and not require any man handling of lower level stuff.

Not trying to create an engine for the hell of it, I have another person working on it whom is not as skilled as me and would work faster with a decent interface.

Honestly, as someone who's been seriously stalled on trying to get his own project started because of this mindset, I'm going to say just go with what works rather than trying to find what's correct. Your engine might be "hacky", but do you know how you would implement those features in a more elegant manner the next time you want to build a game engine? Then you can just make use of that knowledge then (or rebuild your current engine from the ground up, but I don't recommend that since it's easy to get trapped in a constant cycle of re-creating your engine and never actually making the GAME).

If you want to keep things under the hood, you could probably create a sort of interface class whose only function is to serve as a shorthand API for your friend to use without having to deal with any of the nuts and bolts of how the engine handles things. For example, if you want to say, add a new entity to the game world, instead of requiring your designer to actually manipulate the scene graph in order to insert it properly into the tree, you can write an addEntity() method for your API that will just take in some entity data produced by the user and then insert it all automatically. The actual structure of the back end really shouldn't matter, since everything your designer is doing will be high level. They shouldn't be worrying about the rendering pipeline or anything like that, they should be thinking about entities and game actions, and just plugging them into the interface through the methods you've written. You could even produce special classes to handle game objects in a more "human readable" format, whose sole purpose would be to be passed in as arguments to the API, which will then convert them into objects the game engine understands.

It all really depends how complicated your project is, but my main point is that so long as your game works, don't worry too much about HOW it works. If you need someone else to be able to use your engine, it's a lot easier to produce an API that acts as a human-friendly interface layer than it is to try to structure your engine in a way that's human-friendly.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

The Cheshire Cat posted:

Honestly, as someone who's been seriously stalled on trying to get his own project started because of this mindset, I'm going to say just go with what works rather than trying to find what's correct. Your engine might be "hacky", but do you know how you would implement those features in a more elegant manner the next time you want to build a game engine? Then you can just make use of that knowledge then (or rebuild your current engine from the ground up, but I don't recommend that since it's easy to get trapped in a constant cycle of re-creating your engine and never actually making the GAME).

This is very important. Recently I've been working on something that's actually going somewhere, and the strategy I've been taking is to alternate between refactoring and adding features. Some of the refactoring is to clean up the messier parts of the new features, and some of it is in preparation of the next feature. But the important part is that you don't go back and rewrite old code that works. Code that works should never be rewritten, only refactored. If it looks bad but you can't think of a way to make it better you can put it off until later.

Another important thing is to not worry too much about what you are going to be adding in the future. It just leads to analysis paralysis, especially when adding new classes. You can add things when you need them, even if it does require a bit of refactoring.

speng31b
May 8, 2010
Probation
Can't post for 4 hours!

crazylakerfan posted:

At this point, my biggest concern about Unity isn't its power, but that I have heard a lot of people have had trouble with version control on unity projects, and version control is something that we definitely plan to use. Right now, we are basically just trying to decide what we should should pursue for making it.

Honestly I can't speak to the version control problems (which are a well-documented shortcoming of free version Unity), but in terms of dynamic level loading/resizing, you shouldn't find any limitation imposed by Unity. You will have to get someone comfortable enough in the scripting layer to implement a lot of that functionality through script as opposed to kludging around with the editor, but the Unity API absolutely supports it.

Princess Kakorin
Nov 4, 2010

A real Japanese Princess
Does anyone know of a way to get information from a sound file, such as the current BPM, or the volume of the bass and treble?

I've been looking around, wanting to make a game similar to Geometry wars, except it generates bullet patterns based off of how fast the music currently is, how loud the bass is vs the treble, etc etc.
I've looked around, but I couldn't find any information. I don't even think that such information is stored in .oggs or .mp3s?

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?
It isn't. You will probably have to do a fast fourier transform and then extract the information you want from the results, which still isn't easy.

ynohtna
Feb 16, 2007

backwoods compatible
Illegal Hen
An alternative to learning and implementing all the required audio analysis and feature extraction math would be to use the Echonest's track analysis API.

Princess Kakorin
Nov 4, 2010

A real Japanese Princess

ynohtna posted:

An alternative to learning and implementing all the required audio analysis and feature extraction math would be to use the Echonest's track analysis API.

Cool, I figured it wouldn't bee easy. Balls.

ShinAli
May 2, 2003

The Kid better watch his step.

The Cheshire Cat posted:

Honestly, as someone who's been seriously stalled on trying to get his own project started because of this mindset, I'm going to say just go with what works rather than trying to find what's correct.

I guess you're right. Only reason it took me so long to get started on graphics/games/etc was my mindset trying to understand everything about them before I could get started. It's just messy code unsettles me.

I'll go through and refactor/clean up stuff before I start adding on more things.

The Cheshire Cat
Jun 10, 2008

Fun Shoe

ShinAli posted:

I guess you're right. Only reason it took me so long to get started on graphics/games/etc was my mindset trying to understand everything about them before I could get started. It's just messy code unsettles me.

I'll go through and refactor/clean up stuff before I start adding on more things.

I'm still working through this, though I've actually forced myself to start making a game even though I haven't worked out exactly how I want the engine to work.

I think the trouble with trying to come up with the perfect engine is that you're essentially trying to design the entire game before you design the game; the effort is redundant because that's what you're doing when you're writing the code anyway. Sure, knowing you want a particular feature can help you integrate it more elegantly, but you've got the source code and if you need to gut it to make something work, well, you can do that (assuming of course the feature absolutely cannot be made to work in a less work-intensive fashion).

It's better to just get started and build momentum rather than stressing over ever detail; once you actually have momentum it's a lot easier to just go in and make changes. A non-game related example; at work I was putting together a program that saved its data to a file by just using a made up file type and serializing the data to the drive, but ended up replacing the entire thing with an XML interface, so data can be read in any text editor instead of requiring my program. Sure it would have been nice to have gone with XML initially, but I really didn't find it that much work to make the switch, since I'd already done so much ELSE on the project that it seemed really quick by comparison. Being able to see progress is a lot more motivating than having the "perfect" design, and any mistakes you DO make, you can avoid in the future. It's not as if this is the last thing you will ever code.

Vietnom nom nom
Oct 24, 2000
Forum Veteran

Princess Kakorin posted:

Does anyone know of a way to get information from a sound file, such as the current BPM, or the volume of the bass and treble?

I've been looking around, wanting to make a game similar to Geometry wars, except it generates bullet patterns based off of how fast the music currently is, how loud the bass is vs the treble, etc etc.
I've looked around, but I couldn't find any information. I don't even think that such information is stored in .oggs or .mp3s?

Seems like Unity 3D is the answer for everything these days...

http://unity3d.com/support/documentation/ScriptReference/AudioSource.GetSpectrumData.html

http://unity3d.com/support/documentation/ScriptReference/FFTWindow.html

Some youtube examples:

http://www.youtube.com/watch?v=3Rd8WBT2IZY
http://www.youtube.com/watch?v=zvciEKEjuXI
http://www.youtube.com/watch?v=fqQJTddKefo

dangerz
Jan 12, 2005

when i move you move, just like that
Anyone know of a way to get a unique integer for a Vector3 position? I was using index = x + (y * size) + (z * size * size) but that isn't as unique as I thought it'd be.

The reasoning is that I have a Dictionary<Vector3,int> that stores a list of all visible cubes. I was thinking of changing it to Dictionary<int,int> since that takes a lot less memory, but I can't think of a good way to convert a Vector3 position to a unique integer.

Paniolo
Oct 9, 2007

Heads will roll.
If you're asking whether or not there's a way of representing a 96-bit value in a 32-bit value without precision loss or collisions the answer is no. On the other hand since you're talking about a list of cubes maybe you don't need that much precision and could just, say, pack three 10-bit values into the 32-bit integer?

code:
// will cause x, y and z to wrap around when they reach 1024 (10-bit precision)
int hash = ((x & 1023) << 20) + ((y & 1023) << 10) + (z & 1023);
int x = hash >> 20;
int y = (hash >> 10) & 1023;
int z = hash & 1023;
(edited because my first response misinterpreted your question)

I just stumbled across a post you made on reddit which links to your blog where you explained the situation in a lot more detail. So it sounds like you're storing the absolute position of each block, and with a very large, streaming world, that's going to cause problems because you really can't afford the precision loss.

So here's my suggestion: construct the index out of four 8-bit values. The first is going to be a key into an array of active chunks. The other three will be the block's local offset within that chunk. That allows you 256x256x256 addressing space within a chunk, and a maximum of 256 actively loaded chunks at a time. You can fudge those values around a bit (for example, 6-bit offsets for a maximum of 64x64x64 chunks, giving you a maximum of 14x14 active chunks. Or you can lower the precision for the y offset only.

Paniolo fucked around with this message at 03:29 on Apr 30, 2011

PDP-1
Oct 12, 2004

It's a beautiful day in the neighborhood.
Assuming you are still working on your cube world project you could take each chunk's base index, divide each part by the size of a chunk, and then pack that result together as your dictionary lookup for the whole chunk at once. If you have 32x32x32 size chunks it'd reduce the number of bits you need to store one chunk by 5 in each direction. The chunk based at (0,0,0) maps to 0, the chunk based at 32,0,0 maps to 1, etc.

Also, you likely don't need the same number of bits in the vertical and horizontal directions. You could take Paniolo's packing scheme and just use 8 bits in the vertical direction and 12 bits in each horizontal direction and pack the result into a uint instead of an int. That'd give you 4096x4096x256 chunks which would expand back into a 131072x131072x256 space for 32x32x32 element chunks. That's infinite enough for a game.

e: In re-reading your post I think I may have misunderstood what you are doing. If you have a dictionary of all visible cubes then this idea might not work. I assumed that you were trying to track all visible chunks where a chunk contained a range of cubes like 32x32x32.

Drawing only the visible cubes minimizes overdraw but you'll have to reconstruct your whole vertex/index list each frame. Drawing by chunks incurs a bit of overdraw penalty but you can also pre-calculate the vertex/index list of each chunk and have a minimal number of Chunk[x,y,z].Draw() calls per frame. Eating a bit of overdraw in favor of fewer Draw calls may prove to be more efficient depending on the size of your chunks.

e2: To use the chuck drawing idea, you'd likely want to pass the base location of each chunk into your vertex shader and do the offset calculation there. The more I write the more I realize I'm imposing my own assumptions about your data structures onto the problem and I should most likely shut up until I know more.

PDP-1 fucked around with this message at 04:11 on Apr 30, 2011

dangerz
Jan 12, 2005

when i move you move, just like that

Paniolo posted:

If you're asking whether or not there's a way of representing a 96-bit value in a 32-bit value without precision loss or collisions the answer is no. On the other hand since you're talking about a list of cubes maybe you don't need that much precision and could just, say, pack three 10-bit values into the 32-bit integer?

code:
// will cause x, y and z to wrap around when they reach 1024 (10-bit precision)
int hash = ((x & 1023) << 20) + ((y & 1023) << 10) + (z & 1023);
int x = hash >> 20;
int y = (hash >> 10) & 1023;
int z = hash & 1023;
(edited because my first response misinterpreted your question)

I just stumbled across a post you made on reddit which links to your blog where you explained the situation in a lot more detail. So it sounds like you're storing the absolute position of each block, and with a very large, streaming world, that's going to cause problems because you really can't afford the precision loss.

So here's my suggestion: construct the index out of four 8-bit values. The first is going to be a key into an array of active chunks. The other three will be the block's local offset within that chunk. That allows you 256x256x256 addressing space within a chunk, and a maximum of 256 actively loaded chunks at a time. You can fudge those values around a bit (for example, 6-bit offsets for a maximum of 64x64x64 chunks, giving you a maximum of 14x14 active chunks. Or you can lower the precision for the y offset only.
The cube dictionary is already local to each chunk.

I took what you guys said + what someone mentioned on reddit + what I had already implemented and found a solution that worked.

Each chunk has its own Dictionary of cubes local to itself. All cube lookups go through a single method that takes a Vector3. That method takes the Vector3, figures out which chunk the cube is in and then returns the cube from that specific chunk (if it exists).

My mistake before was that there's no need to store the global position for each cube. I switched it so I only stored the local position relative to the chunk position. This made it so the formula (loc.X + (loc.Y * 256) + (loc.Z * 16)) worked and didn't collide since it was limited to 16x128x16 (my chunk size). Transforming that back into a Vector3 position is simply this:

int y = index / 256;
index -= (short)(y * 256);
int z = index / 16;
index -= (short)(z * 16);
int x = index;

So long story short, I greatly reduced my memory footprint. A 29x29 chunk world (Minecraft's version of far) used to take me ~500megs of ram. Now it takes me 300megs.

Thanks for leading me in the right direction.

Vino
Aug 11, 2010
I'm putting together a bundle. I want to bundle a few indie games together and have a sale. I'm looking for games that are:

1. FUN
2. Quirky/Different
3. < $20
4. > $0
5. PC Downloadable
6. Not too popular
7. Appeals to the core audience
8. Indie
9. No DRM

If your game or a game that you know fits this description, please contact me, jorge@lunarworkshop.com

Pfhreak
Jan 30, 2004

Frog Blast The Vent Core!

dangerz posted:

So long story short, I greatly reduced my memory footprint. A 29x29 chunk world (Minecraft's version of far) used to take me ~500megs of ram. Now it takes me 300megs.


500 Megabytes of ram? For this? 300 megabytes of ram just for a single chunk? Correct me if I'm wrong, but that seems absurdly high. That dictionary for a 16x16x128 chunk should be 64Kb, tops.

Am I misunderstanding things here? You want an index into this dictionary that uses only a single short that can be translated back into local coordinates. That's 4 bits for the x axis, 4 bits for the z axis, and 8 bits for the y axis. Multiply that by the number of blocks in the chunk (32,768) and you should be at 64Kb. 16 * 16 * 128 * 16 bits

Paniolo
Oct 9, 2007

Heads will roll.

Pfhreak posted:

500 Megabytes of ram? For this? 300 megabytes of ram just for a single chunk? Correct me if I'm wrong, but that seems absurdly high. That dictionary for a 16x16x128 chunk should be 64Kb, tops.

Am I misunderstanding things here? You want an index into this dictionary that uses only a single short that can be translated back into local coordinates. That's 4 bits for the x axis, 4 bits for the z axis, and 8 bits for the y axis. Multiply that by the number of blocks in the chunk (32,768) and you should be at 64Kb. 16 * 16 * 128 * 16 bits

Uh, he said world not chunk.

Pfhreak
Jan 30, 2004

Frog Blast The Vent Core!

Paniolo posted:

Uh, he said world not chunk.

Apparently I am illiterate.

Edit: Though I still don't know what he's doing with 300 megs of ram for a 29x29 world...

Pfhreak fucked around with this message at 01:30 on May 2, 2011

Scaevolus
Apr 16, 2007

dangerz posted:

The cube dictionary is already local to each chunk.

Is there any reason why you're using a dictionary rather than an array?

Paniolo
Oct 9, 2007

Heads will roll.

Pfhreak posted:

Apparently I am illiterate.

Edit: Though I still don't know what he's doing with 300 megs of ram for a 29x29 world...

I think you are illiterate, because he said 29x29 chunks. :P

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Paniolo posted:

I think you are illiterate, because he said 29x29 chunks. :P
He said a 29x29 chunk world. Which would be a 29x29 world, made of that many chunks.

And from an earlier post, each chunk is 16x128x16, so that gives a grand total of 464x128x464 blocks, which is 27 million blocks. I can see how that could be 300 MB of ram. That's only something like 12 bytes per block.

dangerz
Jan 12, 2005

when i move you move, just like that

Scaevolus posted:

Is there any reason why you're using a dictionary rather than an array?

Dictionary let's me do a fast key lookup (o(1)) and iteration through the whole thing.

Array has a fast iteration but not a fast lookup. I'm def open to suggestions if you have a better idea.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip
If dict is ordered it's a balanced BST rather than a hash and thus doesn't have constant-time lookup

Scaevolus
Apr 16, 2007

dangerz posted:

Dictionary let's me do a fast key lookup (o(1)) and iteration through the whole thing.

Array has a fast iteration but not a fast lookup. I'm def open to suggestions if you have a better idea.
How many entries are in the dictionaries? Is it not 16 * 16 * 128?

dangerz
Jan 12, 2005

when i move you move, just like that

Scaevolus posted:

How many entries are in the dictionaries? Is it not 16 * 16 * 128?
Not always, no. I have a single Dictionary<int16,bool> that stores cubes that are visible due to the world algorithm saying they should be there. The second Dictionary only stores cubes that have visible faces.

That way when I need to modify the chunk (add/delete cubes) and rebuild the vertex buffer, I only have to go through the buffer with the visible faces to save the time.

Pfhreak
Jan 30, 2004

Frog Blast The Vent Core!

Paniolo posted:

I think you are illiterate, because he said 29x29 chunks. :P

Right, I got that.

(16*16*128)*29*29*16bits = ~52Megabytes. My actual illiteracy comes not in misunderstanding his world size, but in misunderstanding that he was storing more than just the dictionary of blocks.

Now I'm curious about what other information is being stored for each block. :D Don't misunderstand my intent, I'm more curious than critical.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

Otto Skorzeny posted:

If dict is ordered it's a balanced BST rather than a hash and thus doesn't have constant-time lookup

http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

quote:

The Dictionary<TKey, TValue> generic class provides a mapping from a set of keys to a set of values. Each addition to the dictionary consists of a value and its associated key. Retrieving a value by using its key is very fast, close to O(1), because the Dictionary<TKey, TValue> class is implemented as a hash table.

dangerz
Jan 12, 2005

when i move you move, just like that

Pfhreak posted:

Right, I got that.

(16*16*128)*29*29*16bits = ~52Megabytes. My actual illiteracy comes not in misunderstanding his world size, but in misunderstanding that he was storing more than just the dictionary of blocks.

Now I'm curious about what other information is being stored for each block. :D Don't misunderstand my intent, I'm more curious than critical.
This is all that's stored for each block:

public byte visibleFaces;
public byte type;

visibleFaces is a listing of the visible faces.
type is the texture/cube type (sand, dirt, grass, etc.)

Each chunk has this:

public Vector3 position;
public Dictionary<Vector3, cube> allCubes;
public Dictionary<Int16, bool> allCubesLookup;
public bool changed;
public SerializableDictionary<Vector3, chunkChange> changes;

position is the chunks world position.
allCubes is a listing of all cubes with visible faces.
allCubesLookup is a listing of all cubes that are available to the world. If a cube doesn't have any visible faces, it still has a listing here so I don't have to re-run the perlin noise algorithm.
changed is a flag that tells me whether the chunk has changes in it (cubes added/deleted).
changes is a serializable dictionary with a list of changes.

I'm sure there's stuff I can be doing differently. Besides iPhone games, I've never written games before and I've definitely never written a 3d game before so all this is new to me.

edit: Updated to my new cube format.

dangerz fucked around with this message at 02:09 on May 4, 2011

Paniolo
Oct 9, 2007

Heads will roll.
Well, plus your vertex buffers. That's where the majority of your RAM usage is coming from I'd wager, although if you're able to use geometry shaders, or with clever use of instancing, you can basically eliminate the need to store any vertices.

dangerz
Jan 12, 2005

when i move you move, just like that

Paniolo posted:

Well, plus your vertex buffers. That's where the majority of your RAM usage is coming from I'd wager, although if you're able to use geometry shaders, or with clever use of instancing, you can basically eliminate the need to store any vertices.
Ya.. I think I'm not using them correctly though. Each chunk has its own vertex buffer that's pushed onto the GPU as soon as it's generated. So say I do a run of a 41x41 world, that's 1681 vertex buffers. I could combine them so it's 2 chunks per vb, but then if I add/delete a cube I'm refreshing 2 chunks instead of 1 and that takes longer.

PDP-1
Oct 12, 2004

It's a beautiful day in the neighborhood.
Watching you guys mess around with cube worlds has inspired me to try making one too. I wrote up a Perlin noise generator and marching cubes algorithm last night, hopefully within a few days I'll have a pretty screenshot to show off.

One problem has been bugging me though - the marching cubes algorithm returns a pile of individual triangles that are unconnected to each other. How do you calculate good vertex normals from that data?

The simple but lovely way to do it would be to calculate one normal for each triangle and use that same normal vector for each vertex. The triangles wouldn't blend nicely into their neighbors and identical normal vector info would be stored three times per triangle. Is there some slick way to do this or is the only option to do a brute-force reduction of vertices/index values that are shared between neighboring cubes?

Also, are you guys doing anything to try to covert the pile of triangles into any kind of triangle strips?

Paniolo
Oct 9, 2007

Heads will roll.

PDP-1 posted:

Watching you guys mess around with cube worlds has inspired me to try making one too. I wrote up a Perlin noise generator and marching cubes algorithm last night, hopefully within a few days I'll have a pretty screenshot to show off.

One problem has been bugging me though - the marching cubes algorithm returns a pile of individual triangles that are unconnected to each other. How do you calculate good vertex normals from that data?

The simple but lovely way to do it would be to calculate one normal for each triangle and use that same normal vector for each vertex. The triangles wouldn't blend nicely into their neighbors and identical normal vector info would be stored three times per triangle. Is there some slick way to do this or is the only option to do a brute-force reduction of vertices/index values that are shared between neighboring cubes?

Also, are you guys doing anything to try to covert the pile of triangles into any kind of triangle strips?

Are you doing a cube world or doing marching cubes, because marching cubes doesn't produce a blocky Mine-craft style world, but smooth meshes.

Here is the code to calculate normals from my marching cubes geometry shader:

code:
// gCellCount is the number of cells in each dimension, gMapSize is the size of the voxel map in each dimension
float3 normalOffset = gCellCount / gMapSize;
float d = Density(v.pos),
      dx = Density(float3(v.pos.x + normalOffset.x, v.pos.y, v.pos.z)),
      dy = Density(float3(v.pos.x, v.pos.y + normalOffset.y, v.pos.z)),
      dz = Density(float3(v.pos.x, v.pos.y, v.pos.z + normalOffset.z));
v.normal = normalize(float3(dx - d, dy - d, dz - d));
As I'm doing it on the GPU via stream out, there's really no way of doing a simplification pass to coalesce identical vertices and use indexing.

PDP-1
Oct 12, 2004

It's a beautiful day in the neighborhood.

Paniolo posted:

Are you doing a cube world or doing marching cubes, because marching cubes doesn't produce a blocky Mine-craft style world, but smooth meshes.

It's a marching cube world, not a Minecraft style block world. My generation steps look like:

1) Fill a 3D array with Perlin noise, scaled to (0.0, 1.0)
2) Run marching cubes on that noise, treating everything above 0.5 as solid and everything below as empty space.
3) Draw the output of the marching cubes algorithm for any blocks within the view frustum.
(4?) Depending on how hard step (3) hammers the graphics card or memory I might also try to coalesce vertices and stripify into triangle strips. Hopefully it won't be needed.

So far I have steps (1) and (2) done and it generates a 32x32x32 block in about 20ms. The blocks can be generated out of order so I hope to just queue up a bunch of MakeBlock() tasks on a background thread and get the visible part of the world to generate in < 1 second. Fingers crossed.

Paniolo posted:

Here is the code to calculate normals from my marching cubes geometry shader:

If I read this right, you're generating normals by looking at the derivative of the Perlin density function. That makes sense, I'll have to take a look at doing that in my own code. Thanks for the tip.

dangerz
Jan 12, 2005

when i move you move, just like that
Do you guys have any screenshots of what you've done?

Paniolo
Oct 9, 2007

Heads will roll.

dangerz posted:

Do you guys have any screenshots of what you've done?

I've posted it before but this is a video of my voxel-world project. I'm currently working on reimplementing it to run on the GPU for an outdoor streaming world. GPU marching cubes is several orders of magnitude faster than CPU marching cubes, but memory is the bigger issue.

Unboxing Day
Nov 4, 2003

I'm not actually well versed in C++ or SDL_Mixer, but I'm asking this question anyway on behalf on the Doom community. Put simply, nobody writing Doom source ports can seem to figure out how to control normal sound volume and MIDI sound volume independently using SDL_Mixer on Windows Vista or 7. I'll let James Haley, author of Eternity Engine, put it in his own words:

quote:

Seems the concept of independent volume for native MIDI doesn't exist under Windows Vista or 7, as using MIDI volume sliders in any application that has them (including most games that use SDL_mixer) also affects the volume of digital sound output. This makes attempting to adjust the relative volume of music for comfort impossible.

Has anybody found any workarounds for this? I'm guessing it's unlikely given how Microsoft seems to have skimped throughout the OS on any way to control the volume of individual sound devices separately.

I've heard of various workarounds all involving a Timidity driver, but this requires the user go above and beyond simply installing the game on his system. The only port that I know of that definitively fixes this issue is ZDoom, but it uses the GPL-incompatible FModEx and is thus not a suitable solution.

If you want some code to look at, Chocolate Doom is perhaps the easiest Doom source port to grok and you can grab its source here:

https://chocolate-doom.svn.sourceforge.net/svnroot/chocolate-doom/trunk/chocolate-doom/

Any suggestions on other open-source sound and music libraries would be welcome as well.

Unboxing Day fucked around with this message at 04:47 on May 3, 2011

PDP-1
Oct 12, 2004

It's a beautiful day in the neighborhood.

dangerz posted:

Do you guys have any screenshots of what you've done?

I only got started on it yesterday and tacked on a very unoptimized viewer tonight so I could see what things look like when I mess with the Perlin noise parameters. It only generates single blocks right now, so still a long way to go.

It's a pretty much just a lovely modern art generator right now.



Hopefully stuff will start looking better once there is more than one block shown at a time and the normals are generated from the Perlin noise derivatives.

Adbot
ADBOT LOVES YOU

Screeb
Dec 28, 2004

status: jiggled

dangerz posted:

This is all that's stored for each block:

public int cubeId;
public Vector3 position;
public List<Int16> visible;
public Int16 type;

cubeId is the cube's id in the pool.
position is its world position.
visible is a listing of the visible faces.
type is the texture/cube type (sand, dirt, grass, etc.)

This is pretty space-inefficient. Why do you need a cube ID? Can you perhaps make it implicit? Position shouldn't need to be stored as a Vector3 - can't you just figure out its position when you need it, given its index value which the chunk holds? You don't need a list of 16 bit integers to store face visibility. Just use a single byte, and set and test the visibility using bitwise operations (so "top is visible" = first bit set to 1, etc). You may be able to get away with storing the type as a byte too, if you don't think you'll need more than 256 types of block.

I made my own Minecraft-alike last year - my blocks take up 3 bytes each at the moment (excluding the vertex buffers of course).

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply