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

Bind empty VAO to bufferless quad rendering #1734

Merged
merged 1 commit into from
Jan 2, 2025

Conversation

ZzzhHe
Copy link
Contributor

@ZzzhHe ZzzhHe commented Dec 27, 2024

Hey! 👋 resolve #1659

I've made some initial fixes for the bufferless quad VAO issue, but wanted to get some advice before finalizing:

  1. I tested my current code and noticed the VAO error was still there but occurred during shader validation in GlShaderProgram::use().

    This happens during program->update_uniforms(in); before geom->draw(); in GlRenderer::render().

  2. My current fix is binding the empty VAO in geometry.cpp, but I'm wondering:

  • Should we bind VAO before shader program validation?
  • Or should we handle/modify the validation error check in GlShaderProgram::use()?

appreciate your thoughts on the best approach!

@heinezen heinezen added area: renderer Concerns our graphics renderer lang: c++ Done in C++ code bugfix Restores intended behavior labels Dec 31, 2024
@heinezen
Copy link
Member

Hey thanks a lot!

I read through this while on the train today, so I have not tried the code out yet. But here are my thoughts on the approach:

Defining quad_vao for every GlGeometry class is likely too much as the member is useless for anything that is not a bufferless quad. Usually having std::optional variables is not a problem, but the game will instance a lot of GlGeometry objects over its runtime. Also, OpenGL only allows a certain number of vertex arrays to be defined I think. So it's worth to think about a better solution here.

Making the VAO static would be nice, but since we need the OpenGL context I doubt it's possible. I think the least dirty solution would be:

  1. Create a single VAO somewhere else (probably in the GlRenderer initialization)
  2. Bind it at the start of every render(..) call
  3. Keep the code in GlGeometry as-is, except for making a comment that a VAO needs to be bound in the switch statement branch for bufferless quad.

This ensures that a VAO is always bound during rendering and should also be much more storage/runtime efficient.

@heinezen
Copy link
Member

heinezen commented Dec 31, 2024

I tested my current code and noticed the VAO error was still there but occurred during shader validation in GlShaderProgram::use().

This happens during program->update_uniforms(in); before geom->draw(); in GlRenderer::render().

This is normal btw ;) OpenGL does not raise errors because they happen on the GPU. Hence, we only learn about them during validity checks when we explicitly request the error state. You can also see the error in "real time" in the logs if you enable OpenGL debug output (by starting with the --gl-debug CLI parameter).

@ZzzhHe
Copy link
Contributor Author

ZzzhHe commented Jan 1, 2025

Got it, thanks! Working on the updates now.

libopenage/renderer/opengl/geometry.h Outdated Show resolved Hide resolved
libopenage/renderer/opengl/geometry.cpp Outdated Show resolved Hide resolved
@@ -67,6 +68,8 @@ class GlRenderer final : public Renderer {

/// The main screen surface as a render target.
std::shared_ptr<GlRenderTarget> display;

std::shared_ptr<GlVertexArray> shared_quad_vao;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can make this member a unique_ptr I think, since it's only used by the GlRenderer class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I attempted to use unique_ptr, but encountered an issue since it requires the complete type definition. When I moved the include to the header file to replace forward declaration, it led to circular include dependencies. Did I do something wrong, or should I dive into the dependency cycle to fix it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you are right. I think you can change it back to shared_ptr.

I think the problem here is that unique_ptr only allows incomplete types under specific circumstances. I also didn't know the specifics for that :'D

std::unique_ptr may be constructed for an incomplete type T, such as to facilitate the use as a handle in the pImpl idiom. If the default deleter is used, T must be complete at the point in code where the deleter is invoked, which happens in the destructor, move assignment operator, and reset member function of std::unique_ptr. (In contrast, std::shared_ptr can't be constructed from a raw pointer to incomplete type, but can be destroyed where T is incomplete). Note that if T is a class template specialization, use of unique_ptr as an operand, e.g. !p requires T's parameters to be complete due to ADL.

https://en.cppreference.com/w/cpp/memory/unique_ptr

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I will change it back

libopenage/renderer/opengl/renderer.cpp Outdated Show resolved Hide resolved
libopenage/renderer/opengl/renderer.cpp Outdated Show resolved Hide resolved
libopenage/renderer/opengl/renderer.h Show resolved Hide resolved
@heinezen heinezen added the kevin-rebuild-pl0x instruct kevin to rebuild this pull request label Jan 2, 2025
@SFTbot SFTbot removed the kevin-rebuild-pl0x instruct kevin to rebuild this pull request label Jan 2, 2025
@heinezen heinezen force-pushed the opengl-bufferless-quad-vao branch from a8ac514 to 1bd9f28 Compare January 2, 2025 22:02
@heinezen heinezen force-pushed the opengl-bufferless-quad-vao branch from 1bd9f28 to 21fbaa9 Compare January 2, 2025 22:06
@heinezen heinezen enabled auto-merge January 2, 2025 22:07
@heinezen
Copy link
Member

heinezen commented Jan 2, 2025

Very good!

@heinezen heinezen merged commit fe60b2b into SFTtech:master Jan 2, 2025
13 checks passed
heinezen added a commit that referenced this pull request Jan 2, 2025
Bind empty VAO for bufferless quad rendering
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: renderer Concerns our graphics renderer bugfix Restores intended behavior lang: c++ Done in C++ code
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

"GL_INVALID_OPERATION: Array object is not active" when rendering bufferless quad
3 participants