Age | Commit message (Collapse) | Author |
|
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.
|
|
We were storing the radians but never using that value in the GPU. We
now directly use the degrees value.
|
|
Same type, but more consistent with the rest of LibSoftGPU and LibGL.
|
|
If there's less than 3 vertices, we cannot do triangle strip otherwise
we will go out-of-bounds of the vertices vector.
Required for Half-Life, which sometimes submits 0 vertices for triangle
strip when drawing the electric disks around the pillars in Xen.
|
|
We now perform per vertex lighting during the Transform and Lighting
stage of the pipeline before the triangles are sent off to be
rasterized.
|
|
As well as Vertex Positions, the normals also need to be transformed
into eye-space so that lighting can be applied correctly.
|
|
This was currently only set in the OpenGL context, as the previous
architecture did all of the transformation in LibGL before passing the
transformed triangles onto the rasterizer. As this has now changed, and
we require the vertex data to be in eye-space before we can apply
lighting, we need to pass this flag along as well via the GPU options.
|
|
Most of the T&L stuff is, like on an actual GPU, now done inside of
LibSoftGPU. As such, it no longer makes sense to have specific values
like the scene ambient color inside of LibGL as part of the GL context.
These have now been moved into LibSoftGPU and use the same pattern as
the render options to set/get.
|
|
These two functions have been turned from stubs into actually doing
something. They now set the correspondingmaterial data member based on
the value passed into the `pname`argument.
Co-authored-by: Stephan Unverwerth <s.unverwerth@serenityos.org>
|
|
This implements the `glLightf{v}` family of functions used to set
lighting parameters per light in the GL. It also fixes an incorrect
prototype for the user exposed version of `glLightf{v}` in which
`params` was not marked as `const`.
|
|
This is required to allow lighting to work properly in the GL. We
currently have the maximum number of lights in the software GL context
set to 8, as this is the minimum that OpenGL mandates according to the
spec.
|
|
Previously, we were expecting triangles and quads to consist of
complete sets of vertices. However, a more common behavior is to ignore
all vertices that do not make up a full primitive. For example, OpenGL
specifies for `GL_QUADS`:
"The total number of vertices between Begin and End is 4n + k, where
0 ≤ k ≤ 3; if k is not zero, the final k vertices are ignored."
This changes the behavior of `Device::draw_primitives()` to both return
early if no full set of vertices was provided, and to ignore any
additional vertices that are not part of a full set.
|
|
This implements the `glViewport` API call, the coordinate
transformation and the `GL_VIEWPORT` context parameter.
|
|
The name `scissor_box_to_window_coordinates` was wildy inaccurate since
we are actually transforming window coordinates into whatever the
coordinate space of the backing bitmap is.
|
|
This adds a half pixel offset to the edge value calculation in order to
sample the triangle at pixel centers. This is in line with actual OpenGL
rasterization rules and generates correctly interpolated vertex
attributes including texture coordinates.
|
|
This previously assigned 1 to any divisor that was 0 which was a bit
confusing
|
|
With the RASTERIZER_BLOCK_SIZE gone we can now render to any size, even
odd ones. We have to be careful to not generate out of bounds accesses
when calculating the render target and depth buffer pointers. Thus we
check the coverage mask and generate nullptrs for pixels that will not
be updated. This also masks out pixels that would touch the triangle but
are outside the render target/scissor rect bounds.
|
|
|
|
|
|
Since the alpha blend configuration should not change between most calls
of draw_primitives it makes no sense to reinitialize the blend factors
for every rasterized triangle.
The alpha blend factors are now set up whenever the device config
changes. The blend factors are stored in struct AlphaBlendFactors.
|
|
This adds member functions Device::rasterize_triangle() and
Device::shade_fragments(). They were free standing functions/lambdas
previously which led to a lot of parameters being passed around.
|
|
Functions to_rgba32 and to_vec4 now process 4 color values at the same
time.
Co-authored-by: Jesse Buhagiar <jooster669@gmail.com>
|
|
|
|
This adds a counter to the debug overlay that displays the average
percentage of SIMD lane utilization.
This number represents the number of pixels that were output for each
quad. A utilization of 100% means that all 4 SIMD lanes were used and
no pixels were masked out before being written to the color buffer.
|
|
|
|
Where possible the sampler will wrap texture coordinates using a bitwise
and instead of a modulus. This speeds up the calculation quite a bit.
|
|
|
|
|
|
Adds functions to expand Vector{2,3,4} to their SIMD equivalent.
|
|
|
|
This snaps vertices to 1/32 of a pixel before rasterization resulting
in smoother movement and less floaty appearance of moving triangles.
This also reduces the severity of the artifacts in the glquake port.
5 bits should allow up to 1024x1024 render targets. Anything larger
needs a different implementation.
|
|
|
|
|
|
This displays statistics regarding frame timings and number of pixels
rendered.
Timings are based on the time between draw_debug_overlay() invocations.
This measures actual number of frames presented to the user vs. wall
clock time so this also includes everything the app might do besides
rendering.
Triangles are counted after clipping. This number might actually be
higher than the number of triangles coming from LibGL.
Pixels are counted after the initial scissor and coverage test. Pixels
rejected here are not counted. Shaded pixels is the percentage of all
pixels that made it to the shading stage. Blended pixels is the
percentage of shaded pixels that were alpha blended to the color buffer.
Overdraw measures how many pixels were shaded vs. how many pixels the
render target has. e.g. a 640x480 render target has 307200 pixels. If
exactly that many pixels are shaded the overdraw number will read 0%.
614400 shaded pixels will read as an overdraw of 100%.
Sampler calls is simply the number of times sampler.sample_2d() was
called.
|
|
|
|
Texture coordinate generation is the concept of automatically
generating vertex texture coordinates instead of using the provided
coordinates (i.e. `glTexCoord`).
This commit implements support for:
* The `GL_TEXTURE_GEN_Q/R/S/T` capabilities
* The `GL_OBJECT_LINEAR`, `GL_EYE_LINEAR`, `GL_SPHERE_MAP`,
`GL_REFLECTION_MAP` and `GL_NORMAL_MAP` modes
* Object and eye plane coefficients (write-only at the moment)
This changeset allows Tux Racer to render its terrain :^)
|
|
Now that we calculate and store eye coordinates for each vertex, we
should use their `z` values for the fragment depth used in further fog
calculations.
This fixes the fog in Tux Racer :^)
|
|
This follows the OpenGL 1.5 spec much more closely. We need to store
the eye coordinates especially, since they are used in texture
coordinate generation and fog fragment depth calculation.
|
|
|
|
|
|
|
|
Fog only affects the RGB channels according to the spec.
|
|
* LibGL now supports the `GL_NORMALIZE` capability
* LibSoftGPU transforms and normalizes the vertices' normals
Normals are heavily used in texture coordinate generation, to be
implemented in a future commit.
|
|
For Tux Racer on my machine, this function would account for 15% of
samples. After this change, that drops down to 9%.
|
|
In the OpenGL fixed function pipeline, alpha testing should happen
before depth testing and writing. Since the tests are basically boolean
ANDs, we can reorder them however we like to improve performance and as
such, we perform early depth testing and delay the more expensive alpha
testing until we know which pixels to test.
However, we were already writing to the depth buffer during the depth
test, even if the alpha test fails later on. Depth writing should only
happen if depth testing _and_ writing is enabled.
This change introduces depth staging, deferring the depth write until
we are absolutely sure we should do so.
|
|
This was breaking the fuzzer build becaues the function is not used
if the `CLAMP_DEPRECATED_BEHAVIOR` constexpr is not `true` during
compile time.
|
|
According to the Khronos FAQ on texture edge sampling, the `GL_CLAMP`
option was never implemented in hardware and as such, it was
deprecated. A lot of applications and games depend on `GL_CLAMP` not
really meaning `GL_CLAMP` but `GL_CLAMP_TO_EDGE`, so we introduce an
option to toggle this behavior at compile-time.
|
|
According to the documentation, we should switch around vertices every
other triangle to prevent front-face culling from removing them.
This allows Tux in Tux Racer to render correctly.
|
|
Adds a method `copy_texels()` to class `Image` that copies a rect of
texels from source image to destination.
|
|
This adds a method `info()` to SoftGPU that returns the name of the
hardware vendor and device name, as well as the number of texture untis.
LibGL uses the returned texture unit count to initialize its internal
texture unit array.
|