The amazing triangle drawer!

Truecolor ZDoom with extra features and some unofficial/beta GZDoom features.
[Home] [Download] [Git builds (Win)] [Git builds (Mac)] [Libs (Win)] [Repo] [Bugs&Suggestions]

Moderators: Rachael, dpJudas

User avatar
Rachael
Developer
Developer
Posts: 3639
Joined: Sat May 13, 2006 10:30

Re: The amazing triangle drawer!

Post by Rachael »

If it's nicely commented I'll be able to pick it up a lot more quickly. :)

Also - what do you need help with right now?
dpJudas
Developer
Developer
Posts: 798
Joined: Sat Jul 23, 2016 7:53

Re: The amazing triangle drawer!

Post by dpJudas »

Let's see. The first goal is to make it render vanilla Doom and Doom 2. I'm aware of the following issues:

1) There are some cases where the texture coordinates on walls are wrong. For example, in E3M1 the first door looks wrong, and when you open it the sides of the door sector moves up along with the door when they should stay put.
2) The code deciding if a wall is a sky or not is not entirely correct. In E1M8 the sides of the lift to the bosses gets detected as a sky. Same thing happens in Map11 where the revenant is hiding. There are probably more places.
3) Wall sprites are missing.
4) Fixed light is not being applied. To fix this one requires another draw variant that can draw without diminishing light though.
5) Render styles are missing (add, sub, revsub, etc.). Requires more draw variants.
6) Translation support. Yet more draw variants.
7) Clip sprites to their subsector.
8 ) Particles are missing.
9) Support for vid_hw2d being off.

4-6 requires me to first hook up the other blending modes to the drawer codegen. But once that is done something still needs to decide which render style then to use and pass in the correct parameters. Getting all those details right will require a lot of knowledge about how ZDoom works from a modding perspective.

7 is about the way I handle translucent stuff. The renderer uses a two pass method where it first renders all the solid parts (walls and flats). Then it renders the translucent stuff (sprites, masked walls). Instead of using a zbuffer I've opted for a method where the solid pass outputs a second buffer with info about which subsector each pixel belongs to. This acts as a kind of zbuffer, but where its the subsector that acts as the depth. However, this requires sprites to be clipped to the boundaries of the subsector. I'm not doing that right now and the result is that you can sometimes see sprites overlap stuff or pop out of existence in the worst case scenarios.

Beyond Doom and Doom 2 there's these additional goodies:

1) Water (fake sector or whatever it is called)
2) Mirrors
3) Camtextures
4) Portals
5) 3D floors
6) Probably more..

I'll try add some description of the algorithms used for culling and clipping as I refactor it into multiple files and classes. :)
Last edited by dpJudas on Tue Nov 15, 2016 12:35, edited 1 time in total.
User avatar
Rachael
Developer
Developer
Posts: 3639
Joined: Sat May 13, 2006 10:30

Re: The amazing triangle drawer!

Post by Rachael »

Unfortunately I don't have immediate fixes for any of this - but I do have a few ideas that you might juggle with to see if anything fits. It might not. I'm hoping this will give you some inspiration, though ... keep in mind this is without knowing exactly how your code works right now, so sorry in advance... >_<

1) Fixing this requires some familiarity with UDMF. The best thing I can suggest is familiarize yourself with GZDoomBuilder and play around with it. Also, it might be worth picking Graf's brains on this one. I don't know if he uses tris or quads for the OpenGL renderer, but it's worth asking how he picks texture coordinates for every surface. (Of course, this may all be information from ZDoomGL, but I am sure he's played around with it at some point considering it's been refactored at least twice now...) Basically what it comes down to is deciding the starting and ending XY points of every surface - the code available for this may be buried somewhere deep in GZDoom - and you may or may not be able to function-call it directly, rather than having to copy-paste or rewrite it. If you want me to look at this can you point me to the exact point in your code where you decide your tex XY coordinates?

2) There is only one surface that gets culled when two nearby sectors have a sky: that's the upper texture. Lower texture is always renderered no matter what. If either the front or back sectors do not have a sky on the ceiling, you do not cull this surface away. And if either the floor of the back or front sectors have a sky at all, even if both do, the lower texture always stays.

3) Very low priority. In fact, I would work on this way last past even getting fog working. ;)

4) "Fixed" light?

5 & 6) Internally ZDoom marks everything as "0" that should be fully transparent. Other than that, how are your drawers working for the triangle renderer? Are you using the r_draw_rgba stuff or did you write new ones?

7) Yes, I have seen the sprites having this behavior you are describing. For this I would make a simple linked binary tree that simply adds and sorts each sprite that is to be rendered by its distance from the camera. How much does it hurt performance to dynamically allocate and destroy said trees every frame? If it's bad you could probably just create a static array (I doubt there will ever be more than 512 per subsector, for example) and have it index-linked and sorted, instead.

8.) Should be able to just render them alongside sprites. ;) You can use the same linked table to sort them.

9) Lower priority, if we get the GL framebuffer working on Linux.

Then your other stuff -

1 & 5) Basically these are just 3D sectors. What I would do is render them along with their tagged sector counterparts, going in order from ceiling to current y-view and then from floor to current y-view. Worry only about the sector surfaces first - and then worry about the fake sector's walls later.

2 & 4) Mirrors are basically portals. Remember this basic formula for mirrors and everything kind of falls into place: DestX = MirrorX * 2 - ViewX. This goes for angle translations as well as planar translations. X applies to Y as well.

6) Fog I think is the most complicated - I'd bounce ideas off of Graf for this one, too. The biggest trouble you'll run into is that if you are far away from a fog sector but can see it clearly, the sector will still fog as if everything between it and you was fully fogged at the same level. What you kind of have to do is finesse it by walking sector-by-sector from the viewer's point to the fog sector's point and calculate the exact fog distances between each entry and departure point. Or you could just say fuck it and let distance attenuation take care of it. ;)
dpJudas
Developer
Developer
Posts: 798
Joined: Sat Jul 23, 2016 7:53

Re: The amazing triangle drawer!

Post by dpJudas »

Sorry, I probably should been more clear that I wasn't so much seeking advice on how I could do it myself, but more what things could use work. I do appreciate the input, of course. A few comments on what you wrote:
Eruanna wrote:Texture coordinate stuff
It is mostly a question of fixing the logic picking the vertical coordinate (i.e. checking the unpegged flags correctly and such). You're right that it might help looking at the same function in the GL part and see how it calculates it. The way it draws the wall itself is fine.
Eruanna wrote:There is only one surface that gets culled when two nearby sectors have a sky: that's the upper texture.
Hmm, it does follow the rule as you describe it. Maybe the problem is instead with the way it "floodfills" the ceiling at those locations. Either way, there's sky some few select places that shouldn't be having it. :)
Eruanna wrote:4) "Fixed" light?
The old software renderer divided light on a surface into three categories: attenuation by distance to camera (diminishing light), fixed light that is always the same no matter the distance (i.e. imp fireballs, some sectors), and globally fixed light (night vision, invulnerability). Right now it renders everything as the first one.
Eruanna wrote:Other than that, how are your drawers working for the triangle renderer? Are you using the r_draw_rgba stuff or did you write new ones?
The poly renderer only uses the r_poly* files. The drawers are completely new. I found nothing worth keeping in the old renderer. ;)
Eruanna wrote:7) Yes, I have seen the sprites having this behavior you are describing. For this I would make a simple linked binary tree that simply adds and sorts each sprite that is to be rendered by its distance from the camera. How much does it hurt performance to dynamically allocate and destroy said trees every frame? If it's bad you could probably just create a static array (I doubt there will ever be more than 512 per subsector, for example) and have it index-linked and sorted, instead.
All the std::vector variables are reused between frames and only allocates new memory if the lists grow larger than they've ever been before. Thus, after a frame or two, they reach a situation where they don't need allocate any more memory.

About sorting by distance, the GL BSP tree already guarantees that they are sorted. Only within the subsector is there any need for further sorting (which it is already doing). I will probably have to create some pictures of how the subsector gbuffer looks like to really explain properly how I ensure the correct depth clipping. Otherwise it gets too abstract.
User avatar
Rachael
Developer
Developer
Posts: 3639
Joined: Sat May 13, 2006 10:30

Re: The amazing triangle drawer!

Post by Rachael »

dpJudas wrote:Sorry, I probably should been more clear that I wasn't so much seeking advice on how I could do it myself, but more what things could use work. I do appreciate the input, of course. A few comments on what you wrote:
Sorry about that. Still - it is for my own benefit, also. :) At least then I have some idea of what to do, here.
dpJudas wrote:
Eruanna wrote:Texture coordinate stuff
It is mostly a question of fixing the logic picking the vertical coordinate (i.e. checking the unpegged flags correctly and such). You're right that it might help looking at the same function in the GL part and see how it calculates it. The way it draws the wall itself is fine.
One thing to keep in mind - GZDoom determines texture coordinates by 0.0 to 1.0 where 1.0 is the right-most (or bottom-most) part of the texture.
dpJudas wrote:
Eruanna wrote:There is only one surface that gets culled when two nearby sectors have a sky: that's the upper texture.
Hmm, it does follow the rule as you describe it. Maybe the problem is instead with the way it "floodfills" the ceiling at those locations. Either way, there's sky some few select places that shouldn't be having it. :)
Ah. Well I did notice that - I thought that it was being overzealous on how to choose the areas for the sky.
dpJudas wrote:
Eruanna wrote:4) "Fixed" light?
The old software renderer divided light on a surface into three categories: attenuation by distance to camera (diminishing light), fixed light that is always the same no matter the distance (i.e. imp fireballs, some sectors), and globally fixed light (night vision, invulnerability). Right now it renders everything as the first one.
I can work on this, after I do some things in Paranoic. This one isn't too hard for me.
dpJudas wrote:
Eruanna wrote:Other than that, how are your drawers working for the triangle renderer? Are you using the r_draw_rgba stuff or did you write new ones?
The poly renderer only uses the r_poly* files. The drawers are completely new. I found nothing worth keeping in the old renderer. ;)
Cool. I hope your code is easier to understand than Carmack's. ;)

I will not put down Carmack. He's a genius. I think he just made this code without ever considering he'd be releasing it in the future for others. If he knew he'd be releasing the source I think he'd have made it very much differently.

Nevertheless if I can understand the new poly drawers it might make it easier for me to make new ones to help out with this problem - or even better, add parameters to the existing ones to have different drawing "modes".
dpJudas wrote:About sorting by distance, the GL BSP tree already guarantees that they are sorted. Only within the subsector is there any need for further sorting (which it is already doing). I will probably have to create some pictures of how the subsector gbuffer looks like to really explain properly how I ensure the correct depth clipping. Otherwise it gets too abstract.
Fair enough.
dpJudas
Developer
Developer
Posts: 798
Joined: Sat Jul 23, 2016 7:53

Re: The amazing triangle drawer!

Post by dpJudas »

Eruanna wrote:One thing to keep in mind - GZDoom determines texture coordinates by 0.0 to 1.0 where 1.0 is the right-most (or bottom-most) part of the texture.
The poly renderer does the same thing. No midtextures or other weirdness. :)
Eruanna wrote:I can work on this, after I do some things in Paranoic. This one isn't too hard for me.
Excellent! It is probably a good starting task to get acquainted with the code.
Eruanna wrote:I will not put down Carmack. He's a genius. I think he just made this code without ever considering he'd be releasing it in the future for others. If he knew he'd be releasing the source I think he'd have made it very much differently.
The original Doom codebase is pretty typical for that age. Massive use of static variables because the computers had very little memory and their compilers were of low quality. Add to that C is a very simple language where your options are limited. Those things considered, the original code isn't that bad. But ZDoom should have refactored it, and in its current stage there's very little left worth reusing.

As for Carmack, I think he's a little bit overrated tbh. He became famous because he's the incarnation of every teenage developer's dream: coding the coolest game engine in town. But if you look at his career, he has consistently missed the mark ever since the release of Doom and Quake. He was wrong about going polygon exclusive in Quake (ugliest shotgun ever!), wrong about how to sell game engines, wrong about shadow casting in Doom 3, wrong about mega textures in rage. When Romero and Hall left id software they lost the part that knew how to make a fun game. Not that Carmack isn't an excellent developer, but I like the personality and style of Romero much more.
Eruanna wrote:Nevertheless if I can understand the new poly drawers it might make it easier for me to make new ones to help out with this problem - or even better, add parameters to the existing ones to have different drawing "modes".
Adding the missing modes is probably easiest for me to do, because I should be able to grab the stuff we need there out of the old drawers. Of course, you're welcome to ask as many questions as you'd like and welcome to give it a try adding a missing mode too. :)
User avatar
Rachael
Developer
Developer
Posts: 3639
Joined: Sat May 13, 2006 10:30

Re: The amazing triangle drawer!

Post by Rachael »

dpJudas wrote:Adding the missing modes is probably easiest for me to do, because I should be able to grab the stuff we need there out of the old drawers. Of course, you're welcome to ask as many questions as you'd like and welcome to give it a try adding a missing mode too. :)
I was going to make them from scratch and create a special mod to compare them.

You probably already did something like this - but if you didn't...

Code: Select all

bind kp/ "toggle r_newrenderer"
;)
dpJudas
Developer
Developer
Posts: 798
Joined: Sat Jul 23, 2016 7:53

Re: The amazing triangle drawer!

Post by dpJudas »

Ah yes, making a map that helps test all the different render styles would be very useful indeed. :)
User avatar
Gez
Developer
Developer
Posts: 1399
Joined: Mon Oct 22, 2007 16:47

Re: The amazing triangle drawer!

Post by Gez »

dpJudas wrote: As for Carmack, I think he's a little bit overrated tbh. He became famous because he's the incarnation of every teenage developer's dream: coding the coolest game engine in town. But if you look at his career, he has consistently missed the mark ever since the release of Doom and Quake. He was wrong about going polygon exclusive in Quake (ugliest shotgun ever!), wrong about how to sell game engines, wrong about shadow casting in Doom 3, wrong about mega textures in rage. When Romero and Hall left id software they lost the part that knew how to make a fun game. Not that Carmack isn't an excellent developer, but I like the personality and style of Romero much more.
All of them have their flaws and have missed the mark more often than not after the glory days of Wolf 3D, Doom and Quake. Those three games were a perfect storm, everything coming up together in an addictive whole despite being made by people who had no idea what they were doing.

It's kind of like being a smart kid at school, were you ace everything without trying in the first few years, then coast along still getting above average grades in the next few years despite still never studying or doing your homework, and then finally catching up with stuff that's hard to do for you and you never acquired the discipline to overcome your hurdles because it hadn't seemed necessary before.
User avatar
Rachael
Developer
Developer
Posts: 3639
Joined: Sat May 13, 2006 10:30

Re: The amazing triangle drawer!

Post by Rachael »

That actually happened to me. I aced everything in college - except math. And math is something I am usually good at - but when it came to College Algebra, I really had to study hard for it.

Amazingly - as much as I struggled in that class, I passed with a >100% grade.
dpJudas
Developer
Developer
Posts: 798
Joined: Sat Jul 23, 2016 7:53

Re: The amazing triangle drawer!

Post by dpJudas »

@Gez: I'm not sure I will go as far as saying they had no idea what they were doing, but I do agree with your general analysis of the whole thing.

@Eruanna: Math is a thing that gets crazy difficult if you first fall behind. The way everything you learn in math builds on stuff you learned earlier, if you miss just one thing every bit that builds on top of it gets much more difficult to learn.
Locked

Return to “QZDoom”