Is the profiler lying/can GL use previous binds/will...

Jones
Unregistered
 
Post: #16
LongJumper Wrote:I'm confused. Are you trying to to bind two textures and then draw them both onto the same geometry?

If that is the case, you will need to use multitexturing, which is not the same as:
glBindTexture(1)
glBindTexture(2)
draw()

No, I am using 3D texturing. This means I am stacking the two images and choosing which depth value to use when drawing. In the end it means you can do something like this:

Code:
glBindTexture(GL_TEXTURE_3D, myTex);

glBegin(GL_QUADS);

glTexCoord3f(0.0, 0.0, 0.0); // Top left of top texture.
drawVertex();

glTexCoord3f(1.0, 1.0, 1.0); // Bottom right of next texture down.
drawVertex();

glEnd();

The end result would be a blend going from the top left to the bottom right, spanning both textures. It's very cool. Smile

However, I'm having some difficult problems with it. Namely: It's not working and I can't track down the problem. Rasp

EDIT: Got you a pic. Those are my two images, blending properly in my *other* project. I'm trying to get them to work on my terrain.

[Image: 3d_tex.png]
Quote this message in a reply
Member
Posts: 87
Joined: 2006.08
Post: #17
Jones Wrote:No, I am using 3D texturing. This means I am stacking the two images and choosing which depth value to use when drawing. In the end it means you can do something like this:

You should _really_ be doing this via multitexturing, and not with 3D textures. Performance is likely to be significantly better, it'll expand to further effects easier, and you won't run into mipmapping issues.

Furthermore, multitexturing is has much wider hardware support than 3D texturing.
Quote this message in a reply
Jones
Unregistered
 
Post: #18
Frogblast Wrote:You should _really_ be doing this via multitexturing, and not with 3D textures. Performance is likely to be significantly better, it'll expand to further effects easier, and you won't run into mipmapping issues.

Furthermore, multitexturing is has much wider hardware support than 3D texturing.

Multi-texturing, you say? Hmm. I'll look into it. I've never really done any of it before, but it sounds like it'll be fun to learn. I'll sift through some of the references at NeHe.

Any tips you'd like to give on the subject?
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #19
Multitexturing in this case is only really easy to do with 2 textures, and you can only reliably get up to 3 or 4 if you're creative. (4 max, though, unless you don't want to support any NVidia cards. Rasp) However, with terrain, you can use 3D textures for almost any number of layers. If you have 8 different terrain layers, for instance, it would be impossible to do with multitexturing on anything but on the Radeon 9600 or later. (and no NVidia cards) However, it would be a simple matter with 3D textures. I can't say anything on performance, though, especially since there doesn't seem to be much information in general on the internet about 3D textures.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #20
akb825 Wrote:If you have 8 different terrain layers, for instance, it would be impossible to do with multitexturing on anything but on the Radeon 9600 or later. (and no NVidia cards)

Kinda misleading -- NVidia only exposes four texture units through the fixed-function pipeline, but they support many more via shaders.
Quote this message in a reply
Jones
Unregistered
 
Post: #21
And it would seem that multitexturing is an extension, whereas 3D textures have been in the core since 1.3 (or was it .4? Wacko ).

I'll stick with that I'm doing for now, but I will investigate Multi-Texturing as it seems it is necessary for bump-mapping. Another 3D feature I've always loved in games.
Quote this message in a reply
Jones
Unregistered
 
Post: #22
No success yet, my Construct3DTexture builds texture units that I can't even get to work on simple 4-vertex quads, let alone my massive terrain.

I'm gonna post the source code here. I hate doing this because it makes me feel like I'm giving up and asking you guys to solve my problems for me (Sad), but I'm stumped. Perhaps you can spot something. Annoyed

I'll try to help here by explaining how stuff works. Each 'TEXTURE' item has OpenGL compatible values that could be used at any time to re-bind the texture to another GL unit. The pixels item is a pointer to the array of data. (Which *is* kept around inside the 'TEXTURE'.

The arguments of the function are fairly self-explanatory. Depth is number of textures being passed in. '*target' is the destined GLuint. (For the texture.)

The TEX_RESULT_COMP3D struct has only two items. 'tex_used_count' which is the number of textures that were successfully bound. 'tex_used' is an array of fixed size (128 ints). It works like this:

Joe-Bloe passes in three textures. The middle one is bad, so the struct contents would be sorta like this:

tex_used_count = 2
tex_used = {1, 0, 1, 0, 0, 0, 0, 0, ... etc }

A one indicates that the texture item <place of n> *was* used. I know, they could be shorts or chars to save memory but I stuck with ints, and frankly, it's no important right now.

If you are reading this code and you get to the part where there is an if loop that checks to branch *with* mipmapping or *without* you can ignore the option that confirms mipmapping. It is not being used to test right now. (If you *do* spot something wrong with it though, please, speak out.)

RAYNE_ITL_TEX_FILTER_GL_TRANS is quite simply an array to convert Rayne (which is what I nicknamed the engine) texture filter values to OpenGL ones. I hope the rest is reasonably clear, I commented a lot, but I know some of my comments are less than useful.

I also know the code is not very efficient, but I'll fix that once the rest is actually working. Thanks for any insight you can offer.

Code:
//    Returns a 3D OpenGL texture unit based on TEXTURE arrays.
    TEX_RESULT_COMP3D Construct3DTexture(    GLuint *target, GLsizei depth,
                                            TEXTURE *texs    ) {
        //    Result.
        TEX_RESULT_COMP3D out_t;
        out_t.tex_used_count = 0;    //    Zero this by default.
        for (int zt = 0; zt < 128; zt++) {
            out_t.tex_used[zt] = 0;
        }
        
        //    Check depth.
        if (depth == 0) {
            out_t.tex_used_count = -1;
            return(out_t);
        }
        
        //    Allocate a list for building the texture.
        int numberToUse = 0;
        int useThese[128];
        for (int z = 0; z < 128; z++) {    //    Zero this array.
            useThese[z] = 0;
        }
        /*int *useThese;
        useThese = (int*)new int[depth];
        if (useThese == NULL) {
            out_t.tex_used_count = -1;
            return(out_t);        //    Not enough memory.
        }*/
        
        
        //    First check if any of the textures are null.
        for (int tc = 0; tc < depth; tc++) {
            
            if (texs[tc].pixels == NULL) {    //    No good.
                //    Ignore this one.
                useThese[tc] = 0;
            }
            else {                            //    Useful.
                
                useThese[tc] = 1;
                
                numberToUse++;    //    We have another good one.
            }
        }
        
        //    Any good ones at all?
        if (numberToUse == 0) {
            //delete useThese;
            out_t.tex_used_count = -1;
            return(out_t);
        }
        
        //    Declare some texture properties.
        GLsizei t1_width = 0;
        GLsizei t1_height = 0;
        GLint t1_components = 0;
        GLenum t1_format;
        GLenum t1_type;
        GLubyte *tex_dat;
        
        TexFilter t_filt;
        
        int gotItHere = -1;    //    Negative one by default.
        bool gotOne = FALSE;
        
        //    Now get the first valid one in the list.
        for (int fc = 0; (fc < depth) || (!gotOne); fc++) {
            
            if (useThese[fc] == 1) {    //    Good one.
            
                t1_width = texs[fc].width;
                t1_height = texs[fc].height;
                t1_components = texs[fc].components;
                t1_format = texs[fc].format;
                t1_type = texs[fc].type;
                t_filt = texs[fc].filter_r;
                
                gotItHere = fc;
                gotOne = TRUE;    //    Don't bother getting the next.
            }
            else {
                //    Bad, do nothing.
            }
        }
        
        //    Alright, at this point we find out which ones are good.
        for (int cc = gotItHere; cc < depth; cc++) {
        
            if (    (texs[cc].width != t1_width) || (texs[cc].height != t1_height) ||
                    (texs[cc].components != t1_components) || (texs[cc].format != t1_format) ||
                    (texs[cc].type != t1_type)    )
            {
                //    It's not a match, chuck it.
                useThese[cc] = 0;
                numberToUse--;
            
            }
            else {
                //    It's a keeper, do nothing.
            }
        
        }
        
        //    At this point we have a list of all the textures which can be combined to form the stack.
        //    Let's alloc some memory.
        tex_dat = (GLubyte*)new GLubyte[numberToUse * t1_width * t1_height * t1_components];
        
        //    And check our allocation.
        if (tex_dat == NULL) {
            out_t.tex_used_count = -1;
            //delete useThese;
            return(out_t);
        }
        
        int imgs_counted = 0;    //    This will count how many images.
        int img_dat_incr = t1_width * t1_height * t1_components;    //    How many bytes per image?
        
        //    Combine all available data.
        for (int mc = 0; mc < depth; mc++) {
        
            if (useThese[mc] == 1) {    //    Yes to process.
            
                
                //    Copy the image into this array.
                for (int bc = 0; bc < img_dat_incr; bc++) {
                    //    Each image size * the images counted + the bytes of this image.
                    tex_dat[(img_dat_incr * imgs_counted) + bc] = texs[mc].pixels[bc];
                }
                
                //    Update the images counted.
                imgs_counted++;
                
                
            }
            else {
                //    No to process, do nothing.
            }
        
        }
        
        //    Tell GL to make some room for this texture.
        glGenTextures(1, target);
        glBindTexture(GL_TEXTURE_3D, *(target));
        
        std::cout << "Construct3DTexture: Asked OpenGL to generate and bind texture unit." << std::cout;
        std::cout << "Construct3DTexture: Last OpenGL Error: " << glGetError() << std::endl;
        std::cout << "Construct3DTexture: GL Texture unit value: " << target << std::endl;
        
        //    These are fixed.
        glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);    //    Clamp is neccessary
        glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);    //    for 3d texturing,
        glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);    //    over repeat.
        
        //    Mipmap it?
        if (t_filt > 1) {
            
            //    These are variable.
            //    The second is not, because it has a limit of detail.
            glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, RAYNE_ITL_TEX_FILTER_GL_TRANS[t_filt]);
            glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, RAYNE_ITL_TEX_FILTER_GL_TRANS[1]);
        
            //    Use GLU to send the data to GL.
            gluBuild3DMipmaps(    GL_TEXTURE_3D, t1_components, t1_width, t1_height,
                                numberToUse, t1_format, t1_type,
                                tex_dat    );
        
        }
        
        //    Don't mipmap it?
        else {
            
            //    These are variable.
            glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, RAYNE_ITL_TEX_FILTER_GL_TRANS[t_filt]);
            glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, RAYNE_ITL_TEX_FILTER_GL_TRANS[t_filt]);
            
            //    Send the data to GL directly.
            glTexImage3D(    GL_TEXTURE_3D, 0, t1_components, t1_width, t1_height, numberToUse, 0,
                            t1_format, t1_type, tex_dat    );
            
            std::cout << "Construct3DTexture: Asked OpenGL to construct 3D texture." << std::cout;
            std::cout << "Construct3DTexture: Last OpenGL Error: " << glGetError() << std::endl;
            
        }
        
        //    Sort this out.
        //    By that I mean make some results for the user.
        out_t.tex_used_count = numberToUse;
        
        int o_count = 0;
        
        for (int rc = 0; rc < depth; rc++) {
            if (useThese[rc] == 1) {
                out_t.tex_used[o_count] = rc;
                o_count++;
            }
            else {
                //    Nothing.
            }
        }
        
        //    Done.
        delete tex_dat;
        return(out_t);    //    Returns how many were valid.
    }

EDIT: (Thought I'd add...) The 3D texture looks fine in the profiler, but the app can't use it. I remember TommorowPlusX having some trouble with the profiler showing something working when it wasn't. If I remember correctly it had to do with 3D texturing too. Is something like happening now?

'Jones Smile
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #23
OneSadCookie Wrote:Kinda misleading -- NVidia only exposes four texture units through the fixed-function pipeline, but they support many more via shaders.
That is true, but if you were looking for compatibility, you wouldn't want to rely on pixel shaders. Wink

BTW, according to the man page of glTexImage3D, it's available since OpenGL 1.2. Multitexturing was introduced as an extension in as early as 1.1, but then rolled into the core in 1.3.

Edit: oh, and before you consider bump mapping, you're going to have to learn about shaders. Smile (it's not just some magical setting you can turn on) As to your current problem, what does it look like when it breaks?
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #24
you dont need shaders to do bump mapping.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #25
akb825 Wrote:However, with terrain, you can use 3D textures for almost any number of layers.

Sure, as long as you don't use mipmapping.

Quote:If you have 8 different terrain layers, for instance, it would be impossible to do with multitexturing on anything but on the Radeon 9600 or later.

You can draw an infinite number of layers on any video card. Just break them into (layers/MAX_TEXTURE_UNITS) passes, blending each pass. This is how everybody did it before multitexturing existed.
Quote this message in a reply
Jones
Unregistered
 
Post: #26
akb825 Wrote:Edit: oh, and before you consider bump mapping, you're going to have to learn about shaders. Smile (it's not just some magical setting you can turn on) As to your current problem, what does it look like when it breaks?

I know about the difficulties of bump-mapping. Over at NeHe they use something like 6 different texture units to accomplish it. Wacko Can't wait!

Take a look at this sample code:

Code:
    glBindTexture(GL_TEXTURE_3D, other);
    
    glBegin(GL_QUADS);
    
        glTexCoord3f(0.0, 0.0, 0.0);
        glVertex2i(0, 0);
        
        glTexCoord3f(1.0, 0.0, 5.0);
        glVertex2i(256, 0);
        
        glTexCoord3f(1.0, 1.0, 5.0);
        glVertex2i(256, 256);
        
        glTexCoord3f(0.0, 1.0, 0.0);
        glVertex2i(0, 256);
    
    glEnd();
    
    glFlush();
    glutSwapBuffers();

That results in:

http://homepage.mac.com/gareth.cross/stu...result.png

On the terrain it's the same, but of course, on a terrain. Rasp
Quote this message in a reply
Jones
Unregistered
 
Post: #27
Um guys... promise me you won't slap me...

You'd be amazed at what forgetting to but glEnable(GL_TEXTURE_3D) can do to a program with 3D textures. Blush Blush Blush <triple-plus-embarrassment>

Sorry guys. Sad

It ain't perfect yet though...

[Image: jagged.png]

JAGGIES! Rasp
Quote this message in a reply
Jones
Unregistered
 
Post: #28
Hey wow, I invented a super cool effect Rasp (Not really.)

[Image: lines_stuff.png]

Lines! I remember that that game "Tribes" would do the same thing if you enabled OpenGL acceleration. I see why now. It actually looks pretty sweet, in my opinion. Very 'techno nature'.

You'll notice there is more grass than rock. This is because, like arreksu said, you cannot mipmap 3D textures. It only uses rock if you're close to it. But it's still sweet.

Thanks all for your help!
Quote this message in a reply
Jones
Unregistered
 
Post: #29
Check out this glow effect I get with linear-non-mipmapped filtering.

[Image: more_lines_weird.gif]

And I still get lines too, funny. I think I'll need to dynamically switch between GL_REPEAT and GL_CLAMP. Shock
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #30
arekkusu Wrote:Sure, as long as you don't use mipmapping.
What's wrong with mipmapping? I though TomorrowPusX was able to get it working.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  OpenGL profiler 3.2 - 0.0 Frame Rate? kelvin 0 2,523 Mar 3, 2006 01:21 AM
Last Post: kelvin
  OpenGL Profiler Nick 15 6,624 Mar 29, 2005 06:56 PM
Last Post: Nick
  OpenGL Profiler, or, "where did all my files go?" sealfin 2 2,752 Sep 3, 2004 12:19 AM
Last Post: sealfin
  OpenGL profiler &amp; display lists MattDiamond 9 4,281 Sep 1, 2003 08:07 PM
Last Post: MattDiamond
  OpenGL profiler LongJumper 11 4,396 Apr 4, 2003 08:18 PM
Last Post: Fenris