Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multitexture #80

Merged
merged 18 commits into from
Nov 7, 2024
Merged

Multitexture #80

merged 18 commits into from
Nov 7, 2024

Conversation

mardy
Copy link
Collaborator

@mardy mardy commented Nov 6, 2024

Here's another big one. Better review it commit by commit.

mardy and others added 18 commits November 5, 2024 23:12
These types are useful in a couple of more places.
This commit does not really implement multi-texturing, but only the
handling of texture coordinates up to (and including) passing them to
the GX pipe.
Since this is the first TEV stage, we can avoid using a precious
register (of which we have only three: GX_TEVREG{0,1,2}) and store the
current color in GX_TEVPREV, which is otherwise meaningless for the
first stage.
Further simplify the rendering of non-lit objects: instead of storing
the constant color (in the case when the color is not given as vertex
data) in a TEV register, store it as material color: this allows us to
simplify the code a bit, because then we can hardcode both the color
channel, and set the TEV input to be the raster color.

Incidentally, we also remove an unused call to GX_SetChanCtrl(), because
we are not using the GX_COLOR1A1 channel (we have just a color channel
in this case).
Since the implementation of GL_COMBINE is quite verbose, move the
texture setup code to a separate file (texture_unit.c).
We implement most of the GL_COMBINE functions, but due to hardware
limitations we cannot support the cases where more than one operand is
complemented (by "complemented" we mean the expression "1 - value");
these *could* be implemented using more stages, but let's not go into
that road for now.

The functions GL_DOT3_RGB and GL_DOT3_RGBA are not implemented, and
likely will never be, since the TEV does not provide a way to offset all
color operands by -0.5.

Note that for the time being the texture coordinate generation is
hardcoded to work on the first texture unit only; we'll fix it in
another commit, as this one is already white big.
This structure is not only going to hold the texture environment, but
all other parameters related to a texture unit, such as coordinate
generation and matrices.
Implement the matrix operations on the texture matrix stack, but the
matrices themselves are not used yet.

Note that in order to keep the state.h compatible with C++ (more
precisely, to allow a C++ file use the inline function
current_tex_matrix() defined in utils.h) we have to mode the declaration
of the OgxTextureUnit struct outside of the glstateparams structure,
otherwise we can access it only using a namespace, from C++.
With this commit we actually use the texture matrices and pass them to
the GPU. Doing this, we "break" the functionality of the
dirty_texture_gen bit, in the sense that we rebuild the texture
generation matrices regardless of whether the dirty flag is set. We
might bring this optimization back later, but while refactoring it's
safer to always recompute the transformation.
This is according to the OpenGL spec. We completely ge rid of the dirty
flag, because until we come up with some rules about the texture matrix
allocated on GX for each texture unit, matrix slots are allocated
dynamically and there's really nothing to cache there.
They only transform two coordinates. Using them as a 3x4 matrix causes
an additional normalization operation at the end, which can lead to
wrong results when the matrix third row is not that of an identity
matrix.
The two operations are not mutually exclusive: first, go through the
texture coordinate generation (if disabled, then the identity matrix is
applied to the vertex texture coordinates), and then the texture matrix
is applied to the result.

The mechanism provided by the GX_SetTexCoordGen2() function seems to fix
well in this case, since it allows for two texture matrices to be
applied one after the other: we use the first one for texture
coordinate generation, the second for the texture transformation matrix.
Should this turn out to be a bad idea, we could pre-multiply the two
matrices in software.
There's no point in doing that, since GX already provides an index
hardcoded to the identity matrix.
There's no reason why we should use GX_PNMTX3; on the contrary, it's
easier if we start reserving the GPU resources starting from the
extremes of the range, so that the range of the available resources will
be contiguous.
When we know that we are on the first TEV stage, we can safely use
GX_TEVPREV to pass constants to the TEV. These frees up GX_TEVREG{0,1,2}
for other uses.
Ensure that arrays are filled sequentially, because we are not allowed
to skip any GX_VA_TEX* elements.
Add a stack of structures holding the number of used GPU resources; this
is simpler than passing parameters around, and in any instant we can
know the allocation status.
At the moment the *_end members are not used, but they will come handy
once we implement some kind of shader support.
These functions are part of OpenGL 1.3, but were available on older
versions too, via the GL_ARB_multitexture extension.
@WinterMute WinterMute merged commit 0fdbb5b into devkitPro:master Nov 7, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants