0

I have 6 squares made up of 2 trangles, each of which is supposed to have a different texture mapped onto it. Instead, each texture is having the last binded texture on it instead of its own. Heres my drawView and setView:

- (void)drawView:(GLView*)view 
{
    glBindTexture(GL_TEXTURE_2D, texture[0]);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);


    static const Vertex3D vertices[] = {
        {0,0, 1}, //TL
        { 1024,0, 1}, //TR
        {0,-1024, 1}, //BL
        { 1024.0f, -1024.0f, 1}  //BR
    };


    static const GLfloat texCoords[] = {
        0.0, 1.0,
        1.0, 1.0,
        0.0, 0.0,
        1.0, 0.0
    };

    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

}

- (void)setupView:(GLView*)view {   
    // Bind the number of textures we need.
    glGenTextures(1, &texture[0]);
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_GENERATE_MIPMAP,GL_TRUE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glLoadIdentity();


    NSString *path = [[NSBundle mainBundle] pathForResource:filename ofType:@"jpg"];
    NSData *texData = [[NSData alloc] initWithContentsOfFile:path];
    UIImage *image = [[UIImage alloc] initWithData:texData];

    if (image == nil)
        NSLog(@"Do real error checking here");

    GLuint width = CGImageGetWidth(image.CGImage);
    GLuint height = CGImageGetHeight(image.CGImage);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    void *imageData = malloc( height * width * 4 );
    CGContextRef context = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );

    // Flip the Y-axis
    CGContextTranslateCTM (context, 0, height);
    CGContextScaleCTM (context, 1.0, -1.0);

    CGColorSpaceRelease( colorSpace );
    CGContextClearRect( context, CGRectMake( 0, 0, width, height ) );
    CGContextDrawImage( context, CGRectMake( 0, 0, width, height ), image.CGImage );

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

    CGContextRelease(context);

    free(imageData);


}
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
jfisk
  • 6,125
  • 20
  • 77
  • 113
  • I can't see anything obviously wrong with that; can you log the values stored to texture[0] by glGenTextures, as a diagnostic step? – Tommy Jan 04 '12 at 15:07
  • NSLog(@"texture[0] = %d",texture[0]); yields 0 each time – jfisk Jan 04 '12 at 18:05
  • Well that's obviously an issue. I don't see how `glTexImage2D` can function at all without a working context so are you sure by some route you're not inadvertently getting to `glDeleteTextures` — or possibly you've got some sort of threading issue, especially re: the necesssary `glFlush`es stipulated by the documentation for `EAGLSharegroup`? – Tommy Jan 04 '12 at 18:36
  • Im going to strip my code down to a more simple example to figure out exactly what the problem is. It is getting a working context and theres no mention of glDeleteTextures – jfisk Jan 04 '12 at 18:49
  • Ive figured out the issue, the filename variable that is the name of the texture to be loaded gets set in every instance of the class to be filename from the most recent instance. http://stackoverflow.com/questions/8737138/how-is-the-variable-filename-here-changing – jfisk Jan 05 '12 at 03:13

2 Answers2

0

You're always using texture[0], so you will indeed get the same texture every time. You need to pass the id of the texture you want to glBindTexture ().

user1118321
  • 25,567
  • 4
  • 55
  • 86
  • my logic was that every instance of this class would have its own texture[0] since thats defined in the header file, why isnt that so here? – jfisk Jan 04 '12 at 06:50
  • I guess I'm confused - do you have more than 1 view? And does each view draw a square? – user1118321 Jan 04 '12 at 17:22
  • I have 1 view, with 6 classes that are children of UIViewController with each responsible of drawing a textured square – jfisk Jan 04 '12 at 17:47
  • Having 6 UIViewControllers controlling a single view is not a good design. (In fact, I'm not even sure it can work.) I suggest you do some re-architecting. I'd recommend having a single view with a single UIViewController. Since I don't know what you're doing with these quads, or what they represent, I can't say the best place for them, but it might be a good idea to have a model object which keeps track of them. Look up [Model View Controller](http://en.wikipedia.org/wiki/Model_view_controller) for more information on how to make this work effectively. – user1118321 Jan 04 '12 at 18:03
  • Any possibility the six classes are creating a unique `EAGLContext` each, inadvertently? – Tommy Jan 04 '12 at 18:37
  • @Tommy It's possible. I don't remember off the top of my head whether the view or controller creates the context. (I thought it was the view.) But without seeing what's being drawn, it's hard to say. – user1118321 Jan 04 '12 at 20:00
  • The GLView creates the context here, once i simplify the code hopefully things will be clearer – jfisk Jan 04 '12 at 21:13
0

I think the problem is related to the texture binding and in particular to this line:

glBindTexture(GL_TEXTURE_2D, texture[0]);

Double check that you use the right value of the gluint required for the texture binding.

Are you using shaders? In case double check it as well though it is most probably not the case.

I suggest to use texture atlas in order to not kill the overall engine's performances by binding every time a different texture in the GPU.

Maurizio Benedetti
  • 3,557
  • 19
  • 26
  • Each tile is its own instance with its own draw calls and setup calls, which is why im confused that they could be accessing the same texture[0] value. – jfisk Jan 04 '12 at 18:06
  • 1
    I suggest you to focus on that. Debug the value of the Texture[0] at each call. If they have all the same value (or zero) then the problem is there. Each bound texture has its own ID therefore you can easily identify if it is a binding problem. – Maurizio Benedetti Jan 04 '12 at 21:08