The FoW renderer would try drawing to texture coordinates one pixel
too high (i.e. if the texture was 256 pixels high, it would draw to
pixels with 1 <= y <= 256 instead of 0..255).
Surfaces are initially created in locked state, and only when unlocked the
memory buffer with the surface data is uploaded to the GPU. The FoW code
however never unlocks the surface but instead operates on the OpenGL texture
directly. To fix this, introduce a new flag for C4Surface to create it in an
unlocked state.
This is not a memory leak in the traditional sense as a pointer to the buffer
is still available and is being freed when the surface is being destructed
at the end of the game. However, during the game there might be several
megabytes allocated that are never used.
I'm not really sold by this Lock/Unlock mechanism. Instead, there should
simply be a function to obtain the current texture data, and a function to
upload new texture data. That's for another time though...
Code outside of C4FoWRegion should not care about the internals of the
class. Therefore, we remove direct access to the backing surface (and
secondary buffer surface) and replace it instead with accessors that
return those few values that are required by outside code.
There are only a couple of error values worth considering, so we can just
write out own function for it. Disable error checking in C4FoWRegion.cpp as
well, since we have the --debug-opengl flag now.
This should allow us to get rid of the GLU dependency soon.
The C++ standard library comes with perfectly fine implementations of
these functions, so there's no point in reimplementing them just for the
hell of it.
This is now a "mix" between the original and the alternate drawing
strategy, hopefully combining its strength. In detail:
1. Intensity of light sources aren't added together anymore. Instead,
the brightest light source decides end brightness pre-smoothing.
2. For smoothing, we update normals more quickly than brightness. This is
the main change relative to the first "alternate" version. Actually
quite embarassing that I didn't think of this solution before %)
This is still a tad busier than what we have currently, simply due to
normals changing around more quickly. On the plus side, Clonk faces
shouldn't go dark anymore while walking, so that's something.
Color value is now uint32_t, removed superfluous conversion to unsigned value, simplification in the shader.
Open: C4DP_Last and number of drawing passes
The color of object lights can now be changed. This includes the following changes:
- added light test scenario, based on DarkCastle, with some lights,
- new functions SetLightColor() and GetLightColor() with C4Script documentation,
- third drawing pass for rendering the light color, the drawing passes are now referenced by enum,
- the blending of light from multiple colored light sources works correctly with alpha blending,
- light color value affects the intensity of the light,
- alpha blending of the light depends on color value and lightness. This means that brighter (= more value) and lighter (= more whiteish) light will be preferred in blending over other lights,
- the object light color is rendered to the lower half of the fow light texture now,
- the shader accesses the brightness/direction information and color information correctly,
The patch was created from the following commits:
dab898a SetLightColor()
f57286e Color texture experiment
d0702f5 Dynamic color
fa14cdf Light test scenario
f99203d Alternate lights
474bade Bugfixes
3113698 Brightness handled better
516fb21 GetLightColor
1d91ec9 Improvements
3cfbf6c Documentation
95ec185 Improvements: Light Shader
a63bffc Scope of alpha
20c7ca0 Improvement: C4FoWLight
17d9123 Undo code style
d79411b Cleaner code
(cherry picked from commit 36dec610e36860b88417e91ce727250673bc2ec2)
Conflicts:
src/landscape/fow/C4FoWRegion.cpp, merged
Several rendering changes have resulted in a non-rendering build that
failed to build from source. Dummy out all of these functions to make it
work again.
This should improve cache coherency by having all surface tiles adjacent
instead of strewn across the heap. This will also remove an indirection
in the common case of only using one tile.
With this change, an additional rectangle is stored in C4FoWRegion that
represents the area covered by the viewport in fractional floating point
coordinates. This allows the light texture to be created for an arbitrary
portion of the landscape, and the coordinate transformations for the
shaders will still work.
Also, since the additional rectangle uses floating point precision, the
computed coordinate transformations do now give the exact same result as for
the landscape pixel-by-pixel, and there should not be any offsets left.
I also hope that this change improves or fixes the single-pixel-lines of sky
that are sometimes seen at the edges of the viewport.
There were two problems with the previous transforms:
1) For inverting the Y axis for the ambient map, the total height of the
output window is needed, not only the viewport region.
2) The Y offset to only use the part of the light texture that is being
rendered to was not applied.
In order to keep the transformations more readable, a new lightweight class
C4FragTransform has been introduced which can only handle translations
and scales in x and y.
Now we use the shader to do a proper blend - this avoids some artefacts
that were visible before. Also after some hair-pulling the coordinate
transformation now seems to be more correct than before. Maybe even
with zoom. We'll see.
* added some class and method documentation, removed some superfluous comments like
void C4FoW::Update(C4Rect r)
{
// Update all lights
...
* added ASK comments that need clarification before proper documentation