In earlier versions, DrawPatternedCircle was a fairly complicated function.
Nowadays, it just copies pixels in memory, bounded by a circle. Since we
need to convert our surfaces to a format GTK+ can use anyway, combine that
step with the circle boundaries. Also use a cairo surface instead of a
GdkPixbuf. Cairo uses almost the same pixel format, except for
premultiplied alpha. Ignore this for now.
Specifically, GtkGrid. For most cases, this is an increase in lines of
code, but the landscape tools dialog can now be done with just three layout
widgets.
While at it, use a toolbar and move the mode buttons into it, too.
9e771ac moved the Win32 ClearInput implementation into SetInputFunctions,
but broke at least GTK while doing that. 9a7d57c0d2 fixed the assertion
failure in GTK that resulted, but failed to restore the removal of the old
completions.
Fix this by folding ClearInput into SetInputFunctions in all implementations.
This reverts commit 790219ac7e.
This commit broke support for Mac OS X since Apple only supports OpenGL 3.0
with a core profile, not a compatibility profile. Revert this commit
temporarily for the 7.0 release, until we port all OpenGL usage to the core
profile with 8.0.
This fixes#1495.
This would crash for me when starting a game in developer's mode. Not sure if this is the best place for the fix. Maybe there is some other underlying issue. ck?
In doing so, refactor the way C4FoWDrawStrategy works slightly. Get rid of
immediate mode OpenGL, and instead populate a vertex array and an index array
as vertices are added to the draw strategy. Then render everything as
triangles.
The actual rendering is then performed in C4DrawStrategy::End(). It passes
the accumulated vertices to the GL. Also get rid of the notion of multiple
passes in C4DrawStrategy. Instead, C4DrawStrategy::End() can simply just draw
the bunch of vertices multiple times. This allows us to do the vertex
generation and GPU upload only once, instead of repeating it for every pass.
This allows the strategy to keep some state between invocations. I want to
use this in order to store a VBO in the draw strategy, and to avoid having
to re-create the VBO for every rendering.
We are already using VBOs for meshes, so we can rely on them being available.
VBOs are shared between contexts, so #1195 is not an issue, either. However,
keep the workaround in place for the VAO, which is not shared between
contexts.
I don't expect much of a performance benefit from this, but it works toward
removal of legacy OpenGL usage. Note that we are already using VBOs for
meshes, so this does not require any functionality that we don't require
already.
Changing the mesh material to something that does not use alpha blending
restores the originial face order. This caused a crash for meshes with
Completion below 1, since all original faces were copied, but the buffer
in the mesh instance was only large enough to hold the number of faces of
the incompleted mesh. To fix this, simply run the standard
select-faces-for-a-given-completion-value procedure.
This probably enlarges the maximum landscape height for borderbound objects.
The "infinity" constant +1000000 is larger than the biggest C4Fixed, so
would have been truncated to 16960.
The DynamiteBox sets the PictureTransformation to a degenerate matrix, to
prevent it from being rendered. Exit early in this case, since we are not
going to render anything anyway, and avoid the assertion when inverting the
matrix.
I think C4Game::InitKeyboard relies on the callback targets outliving the
keybindings and every other class is prepared to be deleted before
C4KeyboardInput::Clear(), so needs to hold a ref to the keybinding to
delete that in its destructor.
C4KeyBinding is the class that is used for that, and it sets the reference
count to 1 in the constructor, to represent the reference held in the
owning class.
On the other hand, C4CustomKey gets immediately forgotten by C4Game and the
only reference is held in the keymap.
To prevent this from happening again, make the C4CustomKey constructors
protected and C4Game a friend of the class.
Also remove an unused C4CustomKey constructor.
Replace the hardcoded VAI_ constants with that. The VAI constants are now
moved to C4DrawGL as C4SSA_ constants, similar to the C4SSU ones. This allows
to introduce other attributes to replace vertex positions, normals, colors
and texture coordinates with attributes in later commits. This, in turn, is
needed because the built-in attributes are no longer available in the OpenGL
core profile.
Also, while at it, cleanup C4Shader a bit. Use std::vector<> instead of
maintaining an own array of uniform names. Delete the vertex and fragment
objects after the full shader program has been linked. Make sure that
C4Shader::Init keeps the old program in place if the new one cannot be
compiled or linked.
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...
For some reason, the C4TexRef constructor first uploaded a set of nulled
texture data, just to be replaced by the actual image data when Unlock()
is called. Skip the unnecessary step and instead just reserve the video
memory in the constructor.
This also fixes objects which previously jumped out of the water continuously, by adding an extra check to also capture faster moving objects. It could be made speed dependent, but that seems to be overkill for the situation.
The only use of C4RTF in its final moments was parsing out plain text
from RTF files anyway, so why even go to all the trouble instead of just
storing plain text in the beginning?
This was used to name snapshot releases of the Network2 branch, and has
seen almost no use since.
C4ENGINEINFO(LONG) was a duplicate of C4ENGINENAME and C4ENGINECAPTION.
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.
In order to avoid duplication, PlatformAbstraction.h has to be included at
the start of every source file, so that various headers can rely on it
being there. To avoid confusion, always rely on that, instead of sometimes
randomly including it or parts of it again.
Video recording and playback only worked on Windows, and recording only
handled video, not game audio. As such, it was of fairly limited use,
and there's lots of software available these days that handle both.
GUI_Multiple windows are supposed to be updated from the root window in a full refresh. However, they also had the "dirty" flag set (that is only used for non GUI_Multiple windows after the initial startup), but they did not unset it when updating.
So they were first updated with the correct parent width (full screen) and then, because of the dirty flag, were updated again like a non GUI_Multiple window with the parent's size. That was incorrect. Only another update would then fix it again (because the "dirty" flag would then have been unset).
If the user switched away from OC while it was loading, there was
probably a reason for that. We'll no longer assume we're the most
important app in the world and steal the focus away from whatever the
user was doing.
It's still pretty useless because nobody cares in the slightest about
which extensions are available and which ones aren't, but at least now
it doesn't throw an unintelligible list of numbers at you.
In the game initialization code, we're setting the thread locale to the
user's default locale. This is bad when generating shader code because
it may lead to floats being written with commas instead of dots for the
decimal separator, which in turn confuses the GLSL compiler (because it
parses the comma as the comma operator). So now we just temporarily set
the C locale while generating shader code.
In a surprising touch, using shaders to affect pretty much every pixel
that gets drawn on screen means there is little reason for code to ask
the renderer if it knows about shaders.
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.
Otherwise, when starting the next scenario, random spots would be initially
re-lighted. That's not necessarily a problem, but unnecessary work, and it
triggered the assertion in C4FowAmbient::UpdateFromLandscape if the relight
was scheduled for a region that's outside of the landscape boundaries of the
second scenario.
Instead, compute the projection, modelview and normal matrices explictly
and upload them as shader uniforms. This is one step towards using the
OpenGL 3 core profile.
Translate() used to select the script which it checked for translations
before actually looking up the string key. Change it so if the object
the context of which it was called in doesn't have a matching
translation, the string table of the script containing the call is used
instead.
Hardly anyone ever tests the headless build, because it requires you to
run CMake a second time with -DUSE_CONSOLE=On. So now it's an included
project which you'll get whether you want it or not.
I'm well aware that this could be solved more nicely, and that we could
be splitting unchanged files out into a separate support library, but
that's left for a later date.
Another piece of code that hasn't been tested in ages, gone. The default
puncher address was still pointing to clonk.de, which I'm very certain
isn't providing UDP hole punching services anymore.
Instead of a bespoke hole punching implementation we should use a STUN
lib.
It was almost never appropriate (played underground etc.), could not be turned off and was very repetitive. Mountain scenarios with lots of wind may activate the sound.
A playlist change would reset SCounter and eventually cause all songs to be non-eligable.
Since playlists can now select differently sized subsets, the old way of selecting random songs without too much repetition no longer works. Rewrite to use a more robust algorithm.
Getting the error summary written to the log/console automatically may
be useful for general game usage, but when testing Aul we just end up
with thousands of useless messages in the output. Let the caller log the
message if it's really desired.
Also move all object sounds to global Sound.ocg so they are still played.
This is to prevent naming collisions. All sounds are moved because otherwise all scripts would have to be adjusted. Also, the distinction between sounds in definitions and sounds in Sound.ocg was rather arbitrary.
It will also ensure most sounds are reloaded when sound is turned off temporarily, although that should better be fixed properly.
Deserializing players neglected to turn an enumerated proplist back into
a live one. This would explode later during player initialization when
someone didn't check that the deserialized value was a real, live
proplist.
None of these functions require access to any state of C4Landscape, and
they've only been used from within C4Landscape.cpp, so don't need to be
part of the header.
When clearing parts of the landscape, solid masks must be disabled
beforehand because we don't want to remove the actual solid mask itself.
Theoretically we should also temp remove solid masks before DigFree,
ShakeFree, and all of the other landscape modifiers, just in case
someone overrides the Vehicle material with stupid values.
Pressing the Alt key enters the menu modal loop, which takes control of
the thread that everything happens on. As a quick fix, we'll suppress
this loop for simple Alt key presses, but this will still happen when
the system menu gets opened by Alt+Space or clicking the icon in the
window's title bar.
A more permanent solution would be to detach the message loop from
everything else, by having rendering etc. run in a separate background
thread.
* Show max one message per second per client
* Do not show ready message locally
* Fix observer flag reset by ready state change
* Reflect ready state change in client list immediately
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.
Using memset to initialize non-POD types doesn't work. Or rather, it may
work right now, but will fail when somebody adds a member that relies on
its constructor doing something (like for example any STL container).
Either way it's undefined behavior and needs to go. Furthermore, using
it to reinitialize an object also prevents any dtors from doing their
work when needed.
A new helper function InplaceReconstruct will take an object of nothrow-
default-constructible type, and call the dtor to properly clean up
before placement-new reconstructing the object in the same location.
This is still bad design, but unfortunately removing the Default/Clear
functions from every object currently using them is a herculean task.
The problem comes from the fact that the landscape texture can be larger
than the actual landscape, and that for the last row or column of pixels
drawn at the edge of the landscape, the shader might access a texel that's
beyond the landscape boundaries, at least as part of its interpolation
when accessing a texture.
This patch fixes this by always making the landscape surface the same size
as the landscape, and then GL_CLAMP_TO_EDGE behaviour will prevent access to
pixels beyond the edge of the landscape. Modern hardware should handle
NPOT textures just fine, and they are already used in other places in Clonk.
If this becomes a problem and needs to be reverted, we could instead upload
the "real" landscape size to the shader, and clamp the texture coordinates
there to make sure to not read beyond the actually filled landscape surface.
Before, material normal bias was calculated only from a column/row of pixels right
next to the pixel in question. This sometimes led to "lines" appearing in edge cases.
The new code modified this approach to look at a whole rectangle instead, which
gives a *lot* smoother results and is only marginally more expensive.
Removing solidmasks temporarily as part of the relighting procedure caused
a landscape update which modified the list of to-be-relighted regions that
is currently being iterated over. This could cause relighting of a region in
which solidmasks have not been removed, leading to vehicle pixels in the
landscape surface used by the landscape shader, which show up pink on the
screen.
Fixed this by introducing C4Landscape::_SetPix2Tmp, which changes a pixel
without causing relighting (or material count updates), and use that when
temporarily removing or putting solidmasks. This should also avoid unnecessary
computations (relighting, material count updates) when updating the landscape
or moving objects with solidmasks.
Instead of Y - Hgt > LandscapeHeight (or, equivalently, Y > LandscapeHeight + Hgt), it was checked for Y + Hgt > LandscapeHeight, which would remove objects too early.
The minimum GTK version is now GTK+ 3.4, which is available since 2012.
It's part of Ubuntu LTS 12.04, and so should be available on any halfway
modern linux distribution.
This should allow getting rid of using deprecated GTK+ API much easier.
Using (0,0,0) violates normalisation assumptions, which shifts the weight
between landscape and texture normals quite massively. The new normal
code should represent a "flat" texture properly.
This gets closer to what they are representing.
More precise would be fg_mask_if_bg_is_sky and fg_mask_of_bg_is_not_sky. But fg_mask and bg_mask were terribly misleading, because sky background didn't mean the material was "in front".
Previously it was checked after adding an element. Long elements would thus be in the same row as the other elements even if they wouldn't fit. Not long elements get their own row.
Not only is FMOD neither free (libre) nor free (gratis), the version we
support(ed) is also impossible to legally obtain anymore. So there's no
reason we should keep code around that (pretends to) support a library
nobody can use or test.
Try to load the whole data in one go instead of re-allocating a vector every
8K bytes. This otherwise results in a lot of reallocations for O(MB)
(uncompressed) sound data.
This speeds up engine initialization by about a second for me.
* Renamed from material shapes to textures shapes
* No per-texture, so the same material can use different shapes with different textures
* Load a shape image instead of text file with vector components
* Allow texture sizes that are not multiple of the map zoom
* Add minimum overlap parameter to draw shapes only when the given overlap is reached.
The solution is slightly hacky and not entirely stable, but for fine-
tuning this functionality is essential.
While I was at it, also reduced refresh interval so it doesn't have a
chance to lag the game.
It looks like sometimes graphics drivers don't report the correct number for
maximum uniforms, since the workaround was enabled even though Newton
confirmed disabling the workaround worked just fine on his GPU. Therefore,
don't listen to what the graphics driver is saying but just try to compile the
shader, and fall back to the workaround if the compilation fails.
This implements the proposal made in the forum for "shiny" materials -
material can now determine the angle at which the most light is reflected.
Shiny materials might set this lower to approximate a "reflection" effect,
and increase the "spottiness" at the same time. To compensate for the
lack of brightness without light, "emittance" can be used.
Not sure this is the most elegant way to model this - the "proper" way
here would be to have emittance, shading and specular as three separate
light parameters instead of molding one into the other and using the third
to compensate.
Furthermore, this reorganises shaders in a major way: We reduce the
number of shader files down to three, pushing a number of possible
configurations into preprocessor. I believe this should be easier to
understand, which for the moment trumps theoretical extensibility
benefits.
* There was an off-by-one-error causing a blank line at the screen upper screen border.
* Remove ApplyGamma. It is always applied because Gamma is just part of the drawing shaders now.
* Save by copying rows instead of pixels for whole map screenshots.
NO_OWNER means the message will be visible for noone (can f.e. be used to hide a ui window). nil means the message won't have visibility restrictions. This is probably what the scripter expects.
Previously, a value of "nil" would have been read as 0. So not setting the Player property and setting it to nil would mean two different things.
Definitions should be only in .ocd files. Although it might be nice e.g. to have mesh material directly in the scenario instead of in a .ocd subfolder, the engine tried to load the map image files as potential textures. It was also undocumented behavior.
We already require support for std::unique_ptr, which itself requires
support for rvalue references. As such, we know we can use rvalue
references, and thus don't have to keep carrying dead code around.
This reverts commit 8ef1f908cc. This seems to be
a performance bottleneck on some graphics cards and/or drivers. Clonkonaut
reports issues with a Radeon HD 7800.
This feature is not vital since textures can always be drawn such that they
tile properly at 512x512. While that particular problem with the Radeon card
could probably be worked around, it's just not worth it.
This will allow better graphics for the clouds movement when wrapping the landscape.
There is some potential for weird behavior; e.g. objects hidden just out of view outside the landscape. But we don't have any goals like Clonk Rage gold mine where you would have to find that nugget lying hidden in that place. Besides, the current behavior of just removing stuff even though it was just halfway out is worse.
When switching dialogs in editor mode, the (paint) tools dialog wouldn't
be properly cleared, instead only destroying the dialog window. Thus,
the next time it would be used, it'd try painting onto a device context
which did no longer correspond to any existing window, which made OpenGL
sad.
It would be set by state and then immediately reset in Default(). This had the effect that if you used the color picker on sky before ever selecting a background material, the wrong background would be used.
A texture array is conceptionally what should be used in this case. One
advantage of this is that we don't have to generate mipmaps ourselves but can
let the graphics driver take care of it. Same for selection of the mipmap
level. This would even allow to choose different mipmap levels for different
textures.
This is a somewhat experimental change since it makes OpenGL 3.0 a hard
requirement for OpenClonk. I expect that this is fine, but if this causes
failures during landscape creation on common hardware/drivers we should
revisit.