-
Notifications
You must be signed in to change notification settings - Fork 130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for negative gamma-correction levels #1121
Conversation
Given that with this implementation all gamma values will get a new meaning, we could just as well introduce a new config variable, e.g. |
Indeed, that's was I thinking. I've learned this trick while working on CRL, which is also using extended gamma levels and screen size, while I was trying to preserve compatibility with DOS version of default.cfg file. Let it be |
Fine with me. |
Since there are a lot of gamma levels now, such message is critically needed.
All done now and ready to be reviewed. |
src/doom/r_data.c
Outdated
|
||
// [crispy] intermediate gamma levels | ||
if (!gamma2table) | ||
if (!gamma2table_set) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer if you could make this static in I_SetGammaTable()
and move that check there, so that it's safe to call this function whenever deemed necessary, but the tables are only calculated once in any case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, fixed in 3873123. I got a bit confused of calling I_SetGammaTable()
between palleted and true color render, but this approach solves it properly, thanks for fresh look!
src/i_video.c
Outdated
@@ -986,6 +986,14 @@ void I_SetGammaTable (void) | |||
void I_SetPalette (byte *doompalette) | |||
{ | |||
int i; | |||
static boolean gamma2table_set = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for being pedantic, but somehow I don't like the fact that I_SetPalette()
has to check each time if the gamma values have already been calculated. They should be calculated once as early as possible and then be taken as granted. They replace static values after all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was primary reason of confusion. My initial idea was to put I_SetPalette()
to I_InitGraphics()
below this line and then do not make any farther calls to I_SetGammaTable()
at all. And it's working fine for palleted render, for true color, however, I'm starting to get black screen.
I don't understand why. Such call to I_SetGammaTable()
is not limited to #ifndef CRISPY_TRUECOLOR
, and gamma values are must be set. What else missing then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fabiangreffrath, allow me please to clarify about last commit c51afc8:
- For palleted render it seems to be correct: we defining gamma tables right before applying palette. It's "calculate first, draw second" logics.
- For true color... It's just disgusting. It does not feels to be the right place for calling
I_SetGammaTable()
, but this is the only way I was able to make it work w/o extra checks. Even ifI_SetGammaTable()
is moved outside of#ifndef CRISPY_TRUECOLOR
macroses inI_InitGraphics()
, it simply doesn't work, matters no where exactly it is placed. I'm completelly out of ideas why -gamma2table
does not seems to be affected byCRISPY_TRUECOLOR
in any ways and it's not palette related thing. So what could it be then? Kaboom! 🤯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, your fix is all fine. Let me try to explain why. 😉
In the non-truecolor case, I_SetGammaTable()
is called from I_InitGraphics()
right before PLAYPAL
is loaded and applied to screenbuffer->format->palette
. This is the first time the gamma table is actually used in this case.
As you can see in src/doom/d_main.c
, I_InitGraphics()
is called rather late. Very late, actually, in the never-returning D_DoomLoop()
, right before entering the D_RunFrame()
loop. That is, everything else in this game is already initialized before the graphics are set up, which in turn is the earliest situation in which the gamma tables is used. But only in the non-truecolor case!
Let's stay in src/doom/d_main.c
and have a look at the single large D_DoomMain()
function. You'll see that it calls a lot of initialization stuff, among these R_Init
, before it calls D_DoomLoop()
in the last line of that function. This means that R_Init()
and thus R_InitColormaps()
is always called before I_InitGraphics()
and so the gamma table is never set up at that point.
Now, why does it make a difference for truecolor and non-truecolor rendering? Because in the case of the palette renderer, we just load the colormaps
from the COLORMAP
lump and be done with it. However, for the truecolor renderer we need to calculate the colormaps
entries and have to take the current gamma level into account. That's why this function will calculate an all-black colormap
if the gamma table hasn't been calculated before. And so, it's perfectly right to call I_SetGammaTable()
right before R_InitColormaps()
in the truecolor case and much later during I_InitGraphics()
in the non-truecolor case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for this not explanation, but whole guide, a road map. I was walking this path strictly forward, while small close look backward was needed. True color's if (!gamma2table)
was a small beacon which led to the right path, and this whole complicated structure of calls was the real reason behind confusion.
So yeah, I_InitGraphics()
is called after R_Init()
, it is clear now. This is also making next perfectly clear: we need to get rid #ifndef CRISPY_TRUECOLOR
macros and make both renders happy. How? Simple! We need exactly one call for I_SetGammaTable()
right before R_InitColormaps()
but without any marcoses. True color render wants it right there, and palleted render will be ready for it when it will be calling I_InitGraphics()
.
The only personal nitpick is having I_
upper level function in the in R_
lower level function, but it have to be I_
as it placed in upper level and it's shared for all four games. Not really nice, but makes sense for understanding where I_SetGammaTable()
is located.
We can simplify even farther by having exactly one call for I_SetGammaTable()
, but then it should be placed in int main()
function which is a-b-s-o-l-u-t-e-l-y no go, it simply doesn't belong there matters no how simple it is!
@@ -732,6 +732,8 @@ void R_InitColormaps (void) | |||
void R_InitData (void) | |||
{ | |||
R_InitTextures (); | |||
// [crispy] Initialize and generate gamma-correction levels. | |||
I_SetGammaTable(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have to make small clarification here. I_SetGammaTable()
is called slightly earlier than in other games, as D_IntroTick()
calls right below seems to be using gfx drawing functions. Such earlier call should be safe, but forgive me, I don't want to dig into Strife code deeper, it's simply not my game...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thank you!
So be it then. 🤗 I'm absolutely sure everyone will like this, even if it wasn't requested often. Next on the list:
|
Thanks for this, I'm looking forward to your plans! |
A carbon copy of implementation from Woof, names came from there as well.
Few thoughts:
OFF
level by default.