Horde3D

Next-Generation Graphics Engine
It is currently 21.11.2024, 23:45

All times are UTC + 1 hour




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Texture generation
PostPosted: 08.07.2008, 11:36 
Offline

Joined: 03.07.2008, 01:23
Posts: 50
I want a single texture to contain multiple areas that are combined in a shader to produce a fragment color.

You can see what I mean from:
http://www.fourcc.org/source/YUV420P-OpenGL-GLSLang.c

A really easy to understand pic is at:
http://en.wikipedia.org/wiki/Image:Yuv420.svg

In that example there are three textures, I guess. But I would like to use just one that has several textures embedded. To do this, I would have to upload them to the texture one by one.

Obviously it's better to do in a shader than to calculate the whole texture to RGB format in software, copying memory first to an internal buffer and only then uploading it to Horde3D all at once. Better yet, the different (signle byte) components are originally contiguous in memory, so using an RGBA texture would cause some difficulties and be very slow as well.

However the update resource function only allows updating of the whole buffer at once, e.g. it has no indices that could be used to determine the updated subtexture/rectangle. I know there is a gl-function allowing this (glTexSubImage or something), there is just no way to pass parameters to use it.

Also it is only possible to create RGBA (or, 4 component) textures dynamically, which is actually not what I would like to do.

I think it is a really neat engine otherwise, but everything dynamic is very hard to do. The engine is IMO overly restrictive in its input formats, only allowing static content for no apparent reason. Maybe the situation should be enhanced by new or enhanced utility functions, everything dynamic in mind.

Also for example I'm somewhat disappointed to find out it's not apparently possible to create grayscale textures even statically, though from the documentation I get the impression that "up to 4 components" are supported.


Top
 Profile  
Reply with quote  
 Post subject: Re: Texture generation
PostPosted: 08.07.2008, 18:23 
Offline

Joined: 03.07.2008, 01:23
Posts: 50
I actually tried changing the engine code to allow for 1 component textures. It seems to be working just by converting the "int format = (comps==4) ? GL_RGBA : GL_RGB" to a switch statement (in a few places) and letting it pass through the related checks.

However then I noticed a thing that to me looks like an anomaly. Don't know if it matters, but in "RendererBase::updateTexture2D" the format ended up to be either GL_BGRA or GL_BGR, whereas in "RendererBase::uploadTexture2D" it was either GL_RGBA or GL_RGB. Seems maybe a bit inconsistent? I don't know if it matters at all. However GL_LUMINANCE ang GL_LUMINANCE_ALPHA work with the same type parameter (GL_UNSIGNED_BYTE), so is there any specific reason why they shouldn't be allowed? They are generally very useful in all kinds of maps, such as heightmaps.

I haven't tested anything with GL_LUMINANCE_ALPHA but it should work just as well as GL_RGBA, shouldn't it?

I also modified my local version to have another "createTexture2D" (I named it "createTexture2DExt") that allows specifying the component amount dynamically. I know this is probably not a good solution, but I think it *should* be customizable.


Top
 Profile  
Reply with quote  
 Post subject: Re: Texture generation
PostPosted: 08.07.2008, 21:59 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
cantele wrote:
However then I noticed a thing that to me looks like an anomaly. Don't know if it matters, but in "RendererBase::updateTexture2D" the format ended up to be either GL_BGRA or GL_BGR, whereas in "RendererBase::uploadTexture2D" it was either GL_RGBA or GL_RGB. Seems maybe a bit inconsistent? I don't know if it matters at all. However GL_LUMINANCE ang GL_LUMINANCE_ALPHA work with the same type parameter (GL_UNSIGNED_BYTE), so is there any specific reason why they shouldn't be allowed? They are generally very useful in all kinds of maps, such as heightmaps.

BGRA is the native format of the graphics hardware, so it is faster to use that for dynamic updates. The reason that it is not used in uploadTexture2D is that our image library outputs data in RGBA format and so we don't need to convert it.

I'm aware that there are still some handy functions like the ones you mention missing but usually these are very easy to add. For me it was always more important to make the concepts in a way that adding new functionality is easy rather than implementing every single feature I could think of :)


Top
 Profile  
Reply with quote  
 Post subject: Re: Texture generation
PostPosted: 09.07.2008, 11:31 
Offline

Joined: 03.07.2008, 01:23
Posts: 50
I think there should be some general mechanism of passing all the possible parameters that can be given in XML, dynamically. I.e. there should be a set of 'handy creation' functions, that take a parameter struct (maybe of some base class) that you can just fill in, with e.g. texture parameters.


Top
 Profile  
Reply with quote  
 Post subject: Re: Texture generation
PostPosted: 09.07.2008, 11:35 
Offline
Tool Developer

Joined: 13.11.2007, 11:07
Posts: 1150
Location: Germany
If you push a tga header in front of your texture data you can use the already existing addResource/loadResource methods


Top
 Profile  
Reply with quote  
 Post subject: Re: Texture generation
PostPosted: 09.07.2008, 14:55 
Offline

Joined: 03.07.2008, 01:23
Posts: 50
Thanks for the suggestion. :arrow: However it's very costly to be copying memory around in every frame. I want to use my existing (three) buffers that each happen to be gray scale.

Two solutions are currently (minus gray scale) possible:
Make three textures, with some added utility functions. Means I have to copy memory, to add the header.
Make one texture with the header, copying the buffers into it.

Preferable solutions:
Make three textures, without copying anything.
Make one texture, uploading subtextures separately, without copying anything.

If I have to copy memory, I will make one texture and this I have already working. However I'm confused whether I have to use this custom "allowance" of gray scale, or whether it could be really included in SVN because I don't see why it would break existing code. It seems I have to use custom utility functions anyway.

Regarding the utility functions, which would be the correct way: Writing an extension, or wait until something is implemented? (Or help implementing it?)


Top
 Profile  
Reply with quote  
 Post subject: Re: Texture generation
PostPosted: 10.07.2008, 12:40 
Offline

Joined: 03.07.2008, 01:23
Posts: 50
Anyway, because I happened to make this change already locally, I will post a patch to allow for it. It will not cover the needed utility functions for dynamic stuff because they're not that well thought out. But I cannot see how this could otherwise be thought out any better, other than by caching more of the texture data.

The patch includes the change also for texture cubes. I haven't tested them. I also haven't tested LUMINANCE_ALPHA, but I imagine if any other alpha case works, it should too.

Code:
Index: egRendererBase.cpp
===================================================================
--- egRendererBase.cpp  (revision 38)
+++ egRendererBase.cpp  (working copy)
@@ -189,7 +189,23 @@
                glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering ? GL_LINEAR : GL_NEAREST );
        }
 
-       int format = (comps == 4) ? GL_RGBA : GL_RGB;
+       int format=0;
+       switch (comps)
+       {
+               case 1:
+                       format=GL_LUMINANCE;
+                       break;
+               case 2:
+                       format=GL_LUMINANCE_ALPHA;
+                       break;
+               case 3:
+                       format=GL_RGB;
+                       break;
+               case 4:
+                       format=GL_RGBA;
+                       break;
+       }
+
        int type = hdr ? GL_FLOAT : GL_UNSIGNED_BYTE;
        int internalFormat;
        if( Modules::config().texCompression && allowCompression )
@@ -218,7 +234,22 @@
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering ? GL_LINEAR : GL_NEAREST );
        glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE );
 
-       int format = (comps == 4) ? GL_BGRA : GL_BGR;
+       int format=0;
+       switch (comps)
+       {
+               case 1:
+                       format=GL_LUMINANCE;
+                       break;
+               case 2:
+                       format=GL_LUMINANCE_ALPHA;
+                       break;
+               case 3:
+                       format=GL_BGR; // This is reversed because it's native graphics hardware format.
+                       break;
+               case 4:
+                       format=GL_BGRA; // This is reversed because it's native graphics hardware format.
+                       break;
+       }
        glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels );
 }
 
@@ -249,7 +280,23 @@
                glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, filtering ? GL_LINEAR : GL_NEAREST );
        }
 
-       int format = (comps == 4) ? GL_RGBA : GL_RGB;
+       int format=0;
+       switch (comps)
+       {
+               case 1:
+                       format=GL_LUMINANCE;
+                       break;
+               case 2:
+                       format=GL_LUMINANCE_ALPHA;
+                       break;
+               case 3:
+                       format=GL_RGB;
+                       break;
+               case 4:
+                       format=GL_RGBA;
+                       break;
+       }
+
        int type = hdr ? GL_FLOAT : GL_UNSIGNED_BYTE;
        int internalFormat;
        if( Modules::config().texCompression && allowCompression )
Index: egTextures.cpp
===================================================================
--- egTextures.cpp      (revision 38)
+++ egTextures.cpp      (working copy)
@@ -249,7 +275,7 @@
                Modules::log().writeWarning( "Texture2D resource '%s': Texture size was changed to match POT", _name.c_str() );
 
        // Check color depth
-       if( _comps != 3 && _comps != 4 )
+       if( _comps < 1 || _comps > 4 )
                return raiseError( "Invalid color depth" );
 
        // Upload texture
@@ -394,7 +420,7 @@
                return raiseError( "Invalid image format (" + ImageLoader::getErrorString() + ")" );
 
        // Check color depth
-       if( _comps != 3 && _comps != 4 )
+       if( _comps < 1 || _comps > 4 )
                return raiseError( "Invalid color depth" );
 
        // Check image size



Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group