Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 772 773 [774] 775 776 ... 795

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 818139 times)

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11595 on: March 03, 2020, 05:38:20 am »

If you're doing it on modern hardware, it's really easy. Just draw all the walls in OpenGL with 3D coordinates and you're done. Z-buffer takes care of the rest. If that's too slow then do some culling using said logic. But you still only need to draw the same sized-rectangles every time, since you turn on perspective drawing.

Here's an article on it the classic technique. For early hardware it's imperative that there's no over-draw, so you do in fact only draw the minimal exact pixels of that wall section where possible.
https://wiki.dungeoneye.net/index.php/Maze_rendering
« Last Edit: March 03, 2020, 05:56:58 am by Reelya »
Logged

delphonso

  • Bay Watcher
  • menaces with spikes of pine
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11596 on: March 03, 2020, 07:38:32 am »

Getting dependencies set up in C++ is pretty much always an onerous process, so don't worry if you find it difficult; just stick through it.

Thank god, it really felt like I was doing something wrong. Thanks for the advice, I'll work on PDCurses then. When I was futzing with Python ages ago, I used ncurses, which seems similar in its abilities.

-snip-

There's a lot here, and I don't understand all of it, but I appreciate the wealth of knowledge here and the advice.

I drafted up some goals for myself this evening - the next month will probably be spent fine-tuning my knowledge of the standard libraries and some of the stuff I'm not /very/ good at in C++ (like what Reelya mentioned with modules). Then I'll take a crack at PDCurses or maybe SDL if I'm feeling confident. Small, digestible chunks sounds like a good way to go about things.

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11597 on: March 03, 2020, 10:40:32 am »

Getting dependencies set up in C++ is pretty much always an onerous process, so don't worry if you find it difficult; just stick through it.

Thank god, it really felt like I was doing something wrong. Thanks for the advice, I'll work on PDCurses then. When I was futzing with Python ages ago, I used ncurses, which seems similar in its abilities.

-snip-

There's a lot here, and I don't understand all of it, but I appreciate the wealth of knowledge here and the advice.

Well boiling that down into some practical advice -

in C++ you have two main types of files, ,cpp files and .h files. Each cpp file is a separate compilable entity. The .h files are shared stuff.

You "include" the .h file in one or more cpp files so that both files have those definitions. But the downside is that if the .h file needs to change, then all .cpp files that include that .h file also need to change.

So if you have a class defined inside the .h file used by several .cpp modules, then any change at all to that class means all the modules need to be rebuilt, because they all include that code. The solution is to push as much of the internal details into one .cpp or another, then strip down the class in the .h file to the bare-bones "need to know" stuff.

For example, you might have a Terrain class for storing a terrain height map, and this also has information about rendering the terrain in it. You then put that in a .h file and #include it for every cpp file that needs to do anything with terrain. The problem is that any change to the class definition for Terrain now requires all dependent code to be recompiled. Which gets quite slow as the project grows.

So, you can now ask, why does each module need to know about the "Terrain Object" at all? That TerrainObject might have a "GetHeight(x,y)" method, and one cpp file calls it thus: "TerrainObject->GetHeight(PlayerX, PlayerY)". So, what you can do instead is just make a different .h file and put a function header in there "float TerrainGetHeight(float X, float Y)", which is then properly defined in another .cpp file. Then, that cpp file that used to have access to the entire TerrainObject, and thus was compile-dependent on it, now only knows about that one single function it needs. it no longer needs to know that there is such a thing as "TerrainObject", thus the dependency has been removed, and you can now have the Terrain module define the TerrainGetHeight function whichever way you like. The details are now hidden from the other cpp files.

This also helps with self-documentation and making the program simpler to understand. For each .cpp file, you make a matching .h file, and you can put at the start of it "extern" links for all functions it needs to be able to access from different modules. Then you could just look at the .h file for that module and know which specific bits from other modules it uses, rather than #including the entire other module and only guessing as to which features this module is using.
« Last Edit: March 03, 2020, 10:48:48 am by Reelya »
Logged

itisnotlogical

  • Bay Watcher
  • might be dat boi
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11598 on: March 03, 2020, 11:57:25 am »

If you're doing it on modern hardware, it's really easy. Just draw all the walls in OpenGL with 3D coordinates and you're done. Z-buffer takes care of the rest. If that's too slow then do some culling using said logic. But you still only need to draw the same sized-rectangles every time, since you turn on perspective drawing.

Here's an article on it the classic technique. For early hardware it's imperative that there's no over-draw, so you do in fact only draw the minimal exact pixels of that wall section where possible.
https://wiki.dungeoneye.net/index.php/Maze_rendering

The point of my project is to do it with sprites, as they would have done back then; I can just use any 3D game engine if I wanted to use true 3D rendering. Indeed, I've made a number of prototypes similar to what you describe in Unity.

The page you linked is helpful though, in that it shows an example of a game that has correct perspective but evenly-sized facing walls; a lot of the difficulty in my method arises from the fact that further positions are highly distorted by the one-point perspective, necessitating new art and new coordinates for those positions.
Logged
This game is Curtain Fire Shooting Game.
Girls do their best now and are preparing. Please watch warmly until it is ready.

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #11599 on: March 03, 2020, 12:06:25 pm »

I want to simulate an aircraft's wake turbulence in Unity.

Basically I'm looking to have up to 100 aircraft objects each dynamically generate a colored vortex (like a tornado or funnel shape) in Unity. The vortex must grow as it ages, it must be affected by gravity, and it must have some kind of transparent gradient so it looks like the wide end of the vortex is fading away. It must be parameterized so I can mess with the shape and adjust the rate of growth, descent, and decay.


I'm kinda looking into vortex geometry right now. I can probably figure out the math to parameterize this on my own if I was doing it in Matlab or something, but where do I begin with generating complicated shapes like this in Unity? It doesn't need to be
« Last Edit: March 03, 2020, 12:13:46 pm by Parsely »
Logged

Telgin

  • Bay Watcher
  • Professional Programmer
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11600 on: March 03, 2020, 01:00:22 pm »

Unity probably has some way to dynamically generate geometry, possibly from a particle generator, but worst case scenario you could build a static mesh with the number of vertices you want and then use a vertex shader with the appropriate parameters passed in to deform it.  Calculating the parameters might be a little tricky though, so something like a particle generator might be better.  I'm fairly sure it could be done like that in Unreal at least, including the spread and gravity effects over time.
Logged
Through pain, I find wisdom.

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #11601 on: March 03, 2020, 08:57:54 pm »

Thanks so much Telgin, just that term "particle generator" has been so extremely helpful in my research, it looks like Unity actually makes something like this EXTREMELY easy!! I'm so excited to try this out now, it looks like it has everything I need! :)
Logged

itisnotlogical

  • Bay Watcher
  • might be dat boi
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11602 on: March 03, 2020, 10:07:35 pm »

If you're doing it on modern hardware, it's really easy. Just draw all the walls in OpenGL with 3D coordinates and you're done. Z-buffer takes care of the rest. If that's too slow then do some culling using said logic. But you still only need to draw the same sized-rectangles every time, since you turn on perspective drawing.

Here's an article on it the classic technique. For early hardware it's imperative that there's no over-draw, so you do in fact only draw the minimal exact pixels of that wall section where possible.
https://wiki.dungeoneye.net/index.php/Maze_rendering

The point of my project is to do it with sprites, as they would have done back then; I can just use any 3D game engine if I wanted to use true 3D rendering. Indeed, I've made a number of prototypes similar to what you describe in Unity.

The page you linked is helpful though, in that it shows an example of a game that has correct perspective but evenly-sized facing walls; a lot of the difficulty in my method arises from the fact that further positions are highly distorted by the one-point perspective, necessitating new art and new coordinates for those positions.

I retract my earlier statement. By God, this is a chore. I know I could make it work if I just kept grinding at it, but I really don't want to. It seemed so simple when I was mocking it up in GIMP...

I think a lot of my woes resulted from the 16:9 aspect ratio. As you reach the edge of the screen, the perspective is distorted more than it would be in a small viewing window in a 4:3 game (the actual world view in Pool of Radiance is like 1/6 of the screen.) The only way to remedy this that I could think of, with my limited artistic skill, is to make facing walls ludicrously wide and side walls really short. Or, if I was really using my brain, I would mimic any dungeon crawl ever and make it so that the furthest walls are shrouded in darkness and not shown to the player.

But if I'm serious about continuing this line of experimentation--and I don't think I am--I would just do what Reelya said and render it with planes in 3D coordinate space. Authenticity be damned.
« Last Edit: March 03, 2020, 10:09:24 pm by itisnotlogical »
Logged
This game is Curtain Fire Shooting Game.
Girls do their best now and are preparing. Please watch warmly until it is ready.

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #11603 on: March 04, 2020, 02:10:04 am »

But if I'm serious about continuing this line of experimentation--and I don't think I am--I would just do what Reelya said and render it with planes in 3D coordinate space. Authenticity be damned.
This is a cool exercise tbh... But yeah unless you're gonna go whole hog and program and design the whole thing with an Amiga... Save yourself some time with the technical stuff and do that stuff the easy way, so you can spend more time focusing on the part that's most fun for you. If anything that route makes you more able to generate an experience that looks and feels really authentic.
Logged

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11604 on: March 04, 2020, 04:45:23 am »

This is just me brainstorming an easy way to do it.

First, have a "block buffer". Step 1 is to copy the block info into that buffer, automatically switching it based on direction. Now you no longer need to keep track of the facing, it's aligned by "front".

You then want to mark any non-visible blocks. So, make a 2D set of bitmasks (for example an array of 32 x 32 bit numbers, if you want the viewdist to be 32 blocks). 1 is "visible", 0 is "blocked". Start with the bitmasks all set to 1. Then, iterate through every block, starting from the front-to-back, and for each position you have another set of bitmasks that are pre-made, and have a 0 whether that block blocks another block. So for each block, you see if it's solid and if it hasn't already been marked as invisible, then if it is, you do a bitwise-& operation on that block's bitmask vs the current bitmask. Storing the "occlusion mask" for each position can be optimized by realizing you only need the occlusion mask for certain blocks and you only need to store info for rows that are behind it, and they can possibly be stored as mirrored too. If storing the bitmasks takes too much memory you can iterate through marking blocks using interpolation, but it will be slower.

The end result of the math operation above is a 2D bitmask which only holds visible blocks. Then, iterate from back to front and render all visible sides of visible blocks, using some basic checks for whether to draw sides or not - only draw a side if the block next to that is empty. For rendering sides, you could just make one default wedge-shaped image, then stretch or shrink it based on required length of the side, base on how far to the left or right it is.

Or, if the above is too much work consider this algorithm:

- take each vertical row of pixels. Ray-trace the first wall it hits, then draw a vertical row of pixels there, from the correct texture of the correct vertical length. Then just iterate for every column of pixels across the screen. Presto, all walls drawn, and zero over-draw. This works perfectly as long as the walls are all vertical. Of course, if you have objects inside a cell that are partially behind a wall then you need to also account for that. What you do is note each object inside each cell you passed through on the way to get there and draw them on top of the wall from back-to-front, one pixel slice at a time. So, this bit becomes a bit more work.
« Last Edit: March 04, 2020, 04:59:03 am by Reelya »
Logged

itisnotlogical

  • Bay Watcher
  • might be dat boi
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11605 on: March 04, 2020, 02:24:45 pm »

The first approach would work if I were making my game such that the dungeon is composed solely of occupied vs. not-occupied blocks; however, many older games were composed of grid spaces the player could occupy, bordered by infinitely-thin walls. Thus it is legal for a north-south wall to have no accompanying east-west wall at either end, and vice versa.

My problem wasn't really finding out whether I should draw a wall or not, nor with performance--I doubt any modern PC or even any smartphone would have a problem with 30-ish draw calls with very small textures. It was mathing out the pixel coordinates of where to begin and end drawing each wall that gave me a headache and made me not want to do it. Monogame has no "ray trace" ability in 2D as you suggest, and I'm not sure how that would even work if you don't have some screen-space representation of the world for it to hit in the first place.
« Last Edit: March 04, 2020, 02:31:42 pm by itisnotlogical »
Logged
This game is Curtain Fire Shooting Game.
Girls do their best now and are preparing. Please watch warmly until it is ready.

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11606 on: March 04, 2020, 04:01:50 pm »

The first approach can be fixed for the thin-walls issue by changing each bit from representing a block to representing a wall-facing. The efficient way is that for each occupiable cell you have a North wall and a West wall, so two bits. (separately, you can have a front-texture and back-texture specified for each wall segment, allowing you to have adjacent rooms painted differently).

Then the occlusion mask stores which wall-segments are blocked by each other wall segment. The nice part is that since you're just masking bits here you don't really need to have any complex code to deal with this issue in runtime.
« Last Edit: March 04, 2020, 04:06:08 pm by Reelya »
Logged

itisnotlogical

  • Bay Watcher
  • might be dat boi
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11607 on: March 04, 2020, 04:50:17 pm »

The first approach can be fixed for the thin-walls issue by changing each bit from representing a block to representing a wall-facing. The efficient way is that for each occupiable cell you have a North wall and a West wall, so two bits. (separately, you can have a front-texture and back-texture specified for each wall segment, allowing you to have adjacent rooms painted differently).

Ahhh. See, my map representation had the walls coming off of each grid corner rather than being attached to the adjacent space. It's a small semantic difference, but it would make visualizing the problem much simpler. It would also fix the problem I had whereby walls outside of the play area would technically be valid, as each vertex on the eastern edge could have an eastern wall coming off of it, and each southern vertex could have a southern wall coming off of it.
Logged
This game is Curtain Fire Shooting Game.
Girls do their best now and are preparing. Please watch warmly until it is ready.

Parsely

  • Bay Watcher
    • View Profile
    • My games!
Re: if self.isCoder(): post() #Programming Thread
« Reply #11608 on: March 09, 2020, 07:50:22 pm »

OK so I have one aircraft already in this Unity project that is the correct everything and it's my reference. I just procured a bunch of new a/c models, they are HUGE compared to the reference a/c.

I have a bunch of these a/c and I'd like to not spend a bunch of time experimenting with the scale component and eyeballing it. Is that the only way to get them looking correct? Ideally I want to actually convert these models to their real world units and then scale them all down to their real-life size but I'm not sure how I'd do that.

Also... Is this appropriate to ask about this stuff here since it's not exactly code? It looks like we don't really have a game dev, Unity, or 3D modeling help thread
« Last Edit: March 09, 2020, 07:55:09 pm by Parsely »
Logged

itisnotlogical

  • Bay Watcher
  • might be dat boi
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #11609 on: March 09, 2020, 09:38:17 pm »

OK so I have one aircraft already in this Unity project that is the correct everything and it's my reference. I just procured a bunch of new a/c models, they are HUGE compared to the reference a/c.

I have a bunch of these a/c and I'd like to not spend a bunch of time experimenting with the scale component and eyeballing it. Is that the only way to get them looking correct? Ideally I want to actually convert these models to their real world units and then scale them all down to their real-life size but I'm not sure how I'd do that.

The best way is to open them in a 3D modelling package and scale them in there, such that you don't have to do any additional work in Unity to make them look right. Assuming you use Blender to scale them, you then want to "apply object transform" and check the "scale" box in the toolbox to the left of the 3D view. This will make it so that your model is the correct scale, no matter when or how you add it to the scene. Blender also has handy tools that tell you the bounding-box dimensions of the selected model.

If you really want to, Unity has an "import scale" option that you can set per model. But I genuinely have no idea why anybody would use this, given that there are a multitude of better ways to change a models' size both in and out of Unity. It must have just been included for the sake of completeness.
Logged
This game is Curtain Fire Shooting Game.
Girls do their best now and are preparing. Please watch warmly until it is ready.
Pages: 1 ... 772 773 [774] 775 776 ... 795