In OpenGL, texture coordinates can have up to 4 values. This change
will help with easy application of texture coordinate matrix
transformations in the future.
Additionally, correct the initial value for texture coordinates to
`{ 0.f, 0.f, 0.f, 1.f}`.
Before, `SoftwareRasterizer` was iterating over all 32 possible texture
units for each fragment and checking each if they're bound to a texture.
After this change, an intrusive list containing only texture units with
bound textures is passed to the rasterizer. In GLQuake, this results in
a performance improvement of ~30% (from 12 to 16 FPS in the first demo)
on my machine.
If an unsupported drawing mode was configured, `glEnd` would not reach
the line where `m_in_draw_state` was set to `false`. This caused all
subsequent invocations to `glBegin` to fail.
The `glGet*` family of functions requires that all parameters of
different types are transparently converted into each other. For
example, you can request a boolean parameter as a float or a list of
double values as an integer. It might be considered bad practice to
request parameters through the wrongly-typed function, but to be spec-
compliant we need to implement this.
Introduce a new `::get_context_parameter()` to obtain a parameter
value, which is then converted to the right type by the respective
`::gl_get_*()` functions.
As stated in the manual:
glDeleteTextures silently ignores 0's and names that do not
correspond to existing textures.
If we do not skip these 0 names, they end up as invalid free texture
names in our name allocator.
These enums are used to indicate byte-alignment when reading from and
to textures. The `GL_UNPACK_ROW_LENGTH` value was reimplemented to
support overriding the source data row width.
This now verifies that width and height are a power of 2. The previous
check was nonsensical, probably because it was written against a spec
with improper text formatting, turning 2^x into 2*x :^)
Prior to version 1.1 OpenGL only allowed the numbers 1,2,3 and 4 to be
used as internal texture formats. Symbolic constants were introduced
first with the EXT_texture extension and then later adopted into the
core profile.
This controls how fetched texels are combined with the color that was
produced by a preceding texture unit or with the vertex color if it is
the first texture unit.
Currently only a small subset of possible combine modes is implemented
as required by glquake.
This sets the length of a row for the image to be transferred. This
value is measured in pixels. When a rectangle with a width less than
this value is transferred the remaining pixels of this row are skipped.
Currently just sets the renderer option for what polygon mode we
want the rasterizer to draw in. GLQuake only uses `GL_FRONT_AND_BACK`
with `GL_FILL` )which implies both back and front facing triangles
are to be filled completely by the rasterizer), so keeping this as
a small stub is perfectly fine for now.
This brings `glGetFloatv` more inline with the other `glGet`
functions. We should prevent crashing in the driver as much as
possible and instead let the application deal with the generated
GL error.
Since we operate in screen space where y points down we need to reverse
what is considered clock wise and what is considered counter clockwise.
The rasterizer always expects triangles with a consistent winding order
thus swap 2 vertices if necessary to reverse the winding before passing
the triangle on to the rasterization stage.