summaryrefslogtreecommitdiff
path: root/engine/src/renderer/opengl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/renderer/opengl.rs')
-rw-r--r--engine/src/renderer/opengl.rs55
1 files changed, 41 insertions, 14 deletions
diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs
index 11a4ca9..dc8e561 100644
--- a/engine/src/renderer/opengl.rs
+++ b/engine/src/renderer/opengl.rs
@@ -61,7 +61,7 @@ use opengl_bindings::{ContextWithFns, CurrentContextWithFns};
use safer_ffi::layout::ReprC;
use zerocopy::{Immutable, IntoBytes};
-use crate::asset::{Assets, Id as AssetId};
+use crate::asset::{Assets, Handle as AssetHandle};
use crate::data_types::dimens::Dimens;
use crate::image::{ColorType as ImageColorType, Image};
use crate::matrix::Matrix;
@@ -100,6 +100,7 @@ use crate::shader::{
use crate::texture::{
Filtering as TextureFiltering,
Properties as TextureProperties,
+ Texture,
Wrapping as TextureWrapping,
};
use crate::vector::{Vec2, Vec3};
@@ -898,17 +899,11 @@ fn handle_commands(
continue;
};
- let Some(texture) = assets.get(&texture_asset) else {
- tracing::error!("Texture asset is not loaded",);
- continue;
- };
-
if let Err(err) = create_texture_object(
curr_gl_ctx,
&mut renderer_object_store,
- texture_asset.id(),
- &texture.image,
- &texture.properties,
+ &assets,
+ &texture_asset,
) {
tracing::error!("Failed to create texture object: {err}");
}
@@ -1058,12 +1053,11 @@ fn handle_commands(
fn create_texture_object(
curr_gl_ctx: &CurrentContextWithFns<'_>,
renderer_object_store: &mut RendererObjectStore,
- texture_image_asset_id: AssetId,
- image: &Image,
- texture_properties: &TextureProperties,
+ assets: &Assets,
+ texture_asset: &AssetHandle<Texture>,
) -> Result<(), GlTextureGenerateError>
{
- let object_id = RendererObjectId::Asset(texture_image_asset_id);
+ let object_id = RendererObjectId::Asset(texture_asset.id());
if renderer_object_store.contains_with_id(&object_id) {
tracing::error!(
@@ -1073,10 +1067,43 @@ fn create_texture_object(
return Ok(());
}
+ let Some(texture) = assets.get(&texture_asset) else {
+ tracing::error!("Texture asset is not loaded",);
+ return Ok(());
+ };
+
+ let texture_image = match texture.image.color_type() {
+ ImageColorType::Rgb8 if (texture.image.dimensions().width * 3) % 4 != 0 => {
+ // The texture will be corrupted if the alignment of each horizontal line of
+ // the texture pixel array is not multiple of 4.
+ //
+ // Read more about this at
+ // wikis.khronos.org/opengl/Common_Mistakes#Texture_upload_and_pixel_reads
+ //
+ // To prevent this, the image is converted to RGBA8. RGBA8 images have a pixel
+ // size of 4 bytes so they cannot have any alignment problems
+
+ tracing::warn!(
+ texture_asset = %assets
+ .get_label(&texture_asset)
+ .expect("Not possible"),
+ concat!(
+ "Converting texture image from RGB8 to RGBA8 to prevent alignment ",
+ "problems. This conversion may be slow. Consider changing the ",
+ "texture image's pixel format to RGBA8"
+ )
+ );
+
+ &texture.image.to_rgba8()
+ }
+ _ => &texture.image,
+ };
+
renderer_object_store.insert(
object_id,
RendererObject::from_raw(
- create_gl_texture(curr_gl_ctx, image, texture_properties)?.into_raw(),
+ create_gl_texture(curr_gl_ctx, texture_image, &texture.properties)?
+ .into_raw(),
RendererObjectKind::Texture,
),
);