Between the OpenGL client and server, a lot of data type and color
conversion needs to happen. We are performing these conversions both in
`LibSoftGPU` and `LibGL`, which is not ideal. Additionally, some
concepts like the color, depth and stencil buffers should share their
logic but have separate implementations.
This is the first step towards generalizing our `LibSoftGPU` frame
buffer: a generalized `Typed3DBuffer` is introduced for arbitrary 3D
value storage and retrieval, and `Typed2DBuffer` wraps around it to
provide in an easy-to-use 2D pixel buffer. The color, depth and stencil
buffers are replaced by `Typed2DBuffer` and are now managed by the new
`FrameBuffer` class.
The `Image` class now uses multiple `Typed3DBuffer`s for layers and
mipmap levels. Additionally, the textures are now always stored as
BGRA8888, only converting between formats when reading or writing
pixels.
Ideally this refactor should have no functional changes, but some
graphical glitches in Grim Fandango seem to be fixed and most OpenGL
ports get an FPS boost on my machine. :^)
We check for primitive support in `glEnd()`, so we do not need to
preemptively reject the mode in `glBegin()`. This allows `glBegin()` to
be invoked with `GL_POINTS`, for example.
Each of the material faces is copied member by member then the copied
material state is passed by `const&` to another function, then
destroyed.
This is changed to simply passing the material state directly without
copying.
There is a loop over the lights in which each light state is copied
member by member then the copied light state is passed by `const&` to
another function, then destroyed.
This is changed to simply passing the light state directly without
copying.
The constant value for GL_DECAL is 0x2101 instead of 0x2102.
This was tripping up Half-Life when making the water texture
transparent when under water. The Half-Life port uses its own OpenGL
header, meaning this error wasn't hidden by us.
Previously we only had a single current texture coordinate, set by
the glTexCoord family of functions. Since we now can have multiple
texture coordinates we track a vector of current texture coordinates
and set the requested one in glMultiTexCoord(). glTexCoord() Always sets
the first texture coordinate.
We now have one set of texture coordinates per texture unit.
Texture coordinate generation and texture coordinate assignment is
currently only stubbed. This will be rectified in another commit.
This is the equivalent of glActiveTexture() before it got promoted to
the OpenGL core specification. It is needed by glquake to enable the
multitexturing render path.
LibGL will now generate the GL extension string in the constructor and
refer to it later on when the string is queried via glGetString().
Currently we only check whether the device supports non-power-of-two
textures and add GL_ARB_texture_non_power_of_two to the supported
extensions in that case.
This implements an 8-bit front stencil buffer. Stencil operations are
SIMD optimized. LibGL changes include:
* New `glStencilMask` and `glStencilMaskSeparate` functions
* New context parameter `GL_STENCIL_CLEAR_VALUE`
Implements support for `glRasterPos` and updating the raster position's
window coordinates through `glBitmap`. The input for `glRasterPos` is
an object position that needs to go through the same vertex
transformations as our regular triangles.
When `GL_COLOR_MATERIAL` is enabled, specific material parameters can
be overwritten by the current color per-vertex during the lighting
calculations. Which parameter is controlled by `glColorMaterial`.
Also move the lighting calculations _before_ clipping, because the spec
says so. As a result, we interpolate the resulting vertex color instead
of the input color.
Required by Xash3D for the r_showtextures command, where it shows every
allocated texture on screen.
Description of glIsTexture from the spec:
"glIsTexture returns GL_TRUE if texture is currently the name of a
texture. If texture is zero, or is a non-zero value that is not
currently the name of a texture, or if an error occurs, glIsTexture
returns GL_FALSE.
A name returned by glGenTextures, but not yet associated with a texture
by calling glBindTexture, is not the name of a texture."
https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glIsTexture.xhtml
Required by Xash3D, which forgoes glGenTexture and implements its own
texture generator. It expects glBindTexture to pick up on this though.
The strategy here is to keep texture_object null if we don't find the
texture in the allocation textures map, as it will then both generate
and set the texture in the allocated textures map using the texture
name passed to us, then bind it.
Xash3D requires this otherwise it will crash with a jump to nullptr,
but it doesn't use it for anything interesting and just sets a default
value of ~0 during initialization.
According to the OpenGL spec, invoking functions without an active
context results in undefined behavior. Since ScummVM seems to be the
only port having issues with our behavior, patch their code instead.