1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 19:38:12 +00:00

LibGL: Implement glBindTexture()

Textures are now initialized with a nullptr upon generation.
They are only actually created once they are bound to a target.
Currently only the GL_TEXTURE_2D target is supported.
The software rasterizer now allows rendering with or without
a bound TEXTURE_2D.
This commit is contained in:
Stephan Unverwerth 2021-05-30 00:15:51 +02:00 committed by Linus Groh
parent fde0045ebe
commit 755393e684
8 changed files with 85 additions and 4 deletions

View file

@ -313,7 +313,12 @@ void SoftwareGLContext::gl_end()
}
// FIXME: Change this when we have texture units/multi-texturing
m_rasterizer.submit_triangle(triangle, *static_ptr_cast<Texture2D>(m_allocated_textures.find(1)->value));
if (m_bound_texture_2d == 0) {
m_rasterizer.submit_triangle(triangle);
} else {
auto it = m_allocated_textures.find(m_bound_texture_2d);
m_rasterizer.submit_triangle(triangle, *static_ptr_cast<Texture2D>(it->value));
}
}
triangle_list.clear();
@ -663,11 +668,11 @@ void SoftwareGLContext::gl_gen_textures(GLsizei n, GLuint* textures)
m_name_allocator.allocate(n, textures);
// Let's allocate a new texture for each texture name
// Initialize all texture names with a nullptr
for (auto i = 0; i < n; i++) {
GLuint name = textures[i];
m_allocated_textures.set(name, adopt_ref(*new Texture2D()));
m_allocated_textures.set(name, nullptr);
}
}
@ -678,10 +683,13 @@ void SoftwareGLContext::gl_delete_textures(GLsizei n, const GLuint* textures)
m_name_allocator.free(n, textures);
// Let's allocate a new texture for each texture name
for (auto i = 0; i < n; i++) {
GLuint name = textures[i];
// unbind texture if it is currently bound
if (m_bound_texture_2d == name)
m_bound_texture_2d = 0;
m_allocated_textures.remove(name);
}
}
@ -693,6 +701,9 @@ void SoftwareGLContext::gl_tex_image_2d(GLenum target, GLint level, GLint intern
// We only support GL_TEXTURE_2D for now
RETURN_WITH_ERROR_IF(target != GL_TEXTURE_2D, GL_INVALID_ENUM);
// Check if there is actually a texture bound
RETURN_WITH_ERROR_IF(target == GL_TEXTURE_2D && m_bound_texture_2d == 0, GL_INVALID_OPERATION);
// We only support symbolic constants for now
RETURN_WITH_ERROR_IF(!(internal_format == GL_RGB || internal_format == GL_RGBA), GL_INVALID_ENUM);
RETURN_WITH_ERROR_IF(type != GL_UNSIGNED_BYTE, GL_INVALID_VALUE);
@ -1226,6 +1237,55 @@ void SoftwareGLContext::gl_read_pixels(GLint x, GLint y, GLsizei width, GLsizei
}
}
void SoftwareGLContext::gl_bind_texture(GLenum target, GLuint texture)
{
RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION);
// FIXME: We only support GL_TEXTURE_2D for now
RETURN_WITH_ERROR_IF(target != GL_TEXTURE_2D, GL_INVALID_ENUM);
if (texture == 0) {
switch (target) {
case GL_TEXTURE_2D:
m_bound_texture_2d = 0;
return;
default:
VERIFY_NOT_REACHED();
return;
}
}
auto it = m_allocated_textures.find(texture);
// The texture name does not exist
RETURN_WITH_ERROR_IF(it == m_allocated_textures.end(), GL_INVALID_VALUE);
auto texture_object = it->value;
// Binding a texture to a different target than it was first bound is an invalid operation
// FIXME: We only support GL_TEXTURE_2D for now
RETURN_WITH_ERROR_IF(target == GL_TEXTURE_2D && !texture_object.is_null() && !texture_object->is_texture_2d(), GL_INVALID_OPERATION);
if (!texture_object) {
// This is the first time the texture is bound. Allocate an actual texture object
switch (target) {
case GL_TEXTURE_2D:
texture_object = adopt_ref(*new Texture2D());
break;
default:
VERIFY_NOT_REACHED();
break;
}
m_allocated_textures.set(texture, texture_object);
}
switch (target) {
case GL_TEXTURE_2D:
m_bound_texture_2d = texture;
break;
}
}
void SoftwareGLContext::present()
{
m_rasterizer.blit_to(*m_frontbuffer);