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

Initial OpenGL 2.0 support #99

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open

Initial OpenGL 2.0 support #99

wants to merge 22 commits into from

Conversation

mardy
Copy link
Collaborator

@mardy mardy commented Jan 25, 2025

This is built on top of #98, so it must be merged only after it.

Introduces support for OpenGL 2.0+ (at the moment only OpenGL 2.0 APIs have been added, but I plan to support later versions as well) and the programmable pipeline.

The trick to implement shaders on the GameCube/Wii is to register a set of callbacks that need to be called:

  1. When shaders are compiled
  2. When the GLSL program gets executed

In the first case, the callback carries a hash (computed via the murmurhash3 algorithm) of the shader source code, which can be used by the developer to identify the shader. At this point the client can inform opengx of the list of attributes and uniform variables used in the program, so that opengx can bind them with the provided variables and vertex arrays. When a geometry is to be drawn, opengx calls another callback, where the client should setup the GPU (mostly, the transformation matrices and the TEV) to simulate the same graphical output that would be obtained executing the shader.

The included example (the famous glgears) can be built by adding -DBUILD_EXAMPLES to the cmake command line (it can also be built for the desktop, which helps in verifying its correctness). It's not totally trivial, in that is uses vertex colouring and lighting. The example shows how the original program just needs to be minimally modified to make a function call at startup time, which registers the callbacks implemented in a separate source file (which can be conditionally built for the console only).

Documentation is not provided yet, because the API provided to application developers is not considered final yet. Also, it does not include any function implement texturing.

This can be safely merged, but it might be not being worth making a release until we add a texturing example too.

https://vkvideo.ru/video7200355_456239312

mardy added 20 commits January 16, 2025 17:51
The logic for putting return or break in the getter code is the
following: if the current getter can lookup the value, it should return
immediately after storing it into the output variable; otherwise, we
should "break" from the switch, and then there should be a fallback code
to delegate the operation to a different getter.

This fixes gluBuild2DMipmaps(), which calls

    glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);

and was broken by commit 94b3aab.
As a matter of fact, we already had a couple of structs for holding
drawing parameters, but with this commit we unify them into a single one
and use it more consistently.

The DrawMode struct was also renamed with the "Ogx" prefix.
And anyway that check looks wrong, in that it affected only the vertex
array, and not the other attributes as well.
The pointer is already implemented in the `for` loop. This bug went
unnoticed because in most cases the SameTypeVertexReader is used
instead.
Do not prepare the vertex attribute readers in advance. Instead, just
store the client data in the state and build the readers just at the
time when they are needed (like in glDrawArrays() and glDrawElements).
Keep a "dirty" flag to avoid rebuilding them if the input data has not
changed.

This refactoring is a small step toward supporting arbitrary vertex
attributes (needed for OpenGL 2.0+) and also allows implementing the
getter methods more easily (see next commit).

We also fix glInterleavedArrays(), which got broken at some point.
Add a symbol to host the list of OpenGL 2.0 functions; in functions.c we
weakly define it as an empty array, but this symbol will be shadowed by
the strong symbol we'll define in the new shader implementation, if
OpenGL 2.0 is used.
This will depend on whether the client actually uses any OpenGL 2.0
functionality.
Rework the existing internal function so that it can be used with
matrices passed by the client. This function will be declared in a
public header used by clients who need to write their own shaders
(OpenGL >= 2.0).
Part of this API will be made public in some later commit to allow
it to be used by developers writing shader replacements. For this goal,
a more flexible API is introduced, where vertex attribute arrays can be
added from a OgxVertexAttribArray structure provided by the client.
As the comment was saying, these objects are just for optimization
purposes and do not really belong to the global state variable. Add a
function to array.h so that other parts of the code can retrieve them if
needed, and move the actual variables as static variables in array.c.
Instead of keeping named variables, store all readers into one array.
This helps in simplifying a bit the code.
These are in the public domain.
This is not yet complete and is likely to be buggy in many aspects, but
it allows running a non totally trivial example (the famous glgears),
which will be added in a later commit.

Among the known limitations:
- The API exposed to the client developer for implementing the shaders
  is not finalized.
- Texturing is not yet implemented.
In this way the examples (and any other binary we should add to the
project) will automatically gain an include path to the src/directoy
when building against opengx. This will allow them to find the
"opengx.h" file.
@mardy mardy mentioned this pull request Jan 27, 2025
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.

1 participant