Search code examples
iosopengl-estexturesglkit

How can I apply different textures to different objects using GLKit?


I am displaying 3 objects with the help of GLKit. However, when I am applying textures to these objects, only one texture is being used for all three.

The code I am using is as follows:

- (void)setUpGL{


    NSLog(@"i : %d, %d, %d",i,j,k);
    firstPlayerScore = 0;
    secondPlayerScore = 0;
    staticBall = YES;
    isSecondPlayer = NO;

    self.boxPhysicsObjects = [NSMutableArray array];
    self.spherePhysicsObjects = [NSMutableArray array];
    self.immovableBoxPhysicsObjects = [NSMutableArray array];
    self.cylinderPhysicsObjects = [NSMutableArray array];
    self.secondPlayerCylinderPhysicsObjects = [NSMutableArray array];
    self.sphereArray = [NSMutableArray array];

    GLKView *view = (GLKView *)self.view;
    NSAssert([view isKindOfClass:[GLKView class]],@"View controller's view is not a GLKView");

    view.drawableDepthFormat = GLKViewDrawableDepthFormat16;
    view.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    [EAGLContext setCurrentContext:view.context];

    self.baseEffect = [[GLKBaseEffect alloc] init];

    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);

    //glGenBuffers(1, &_vertexBuffer);
    //glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    //glBufferData(GL_ARRAY_BUFFER, (i+j)*sizeof(float), sphereVerts, GL_STATIC_DRAW);

    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

    self.baseEffect.light0.enabled = GL_TRUE;
    self.baseEffect.light0.ambientColor = GLKVector4Make(0.7f, 0.7f, 0.7f, 1.0f);


    [self addImmovableBoxPhysicsObjects];
    [self addRandomPhysicsSphereObject];
    //[self addFirstPlayerCylinderObject];
    //[self addSecondPlayerCylinderObject];
    //[self scheduleAddRandomPhysicsSphereObject:nil];

}


- (void)addRandomPhysicsObject{
   if(random() % 2 == 0)
   {
      [self addRandomPhysicsBoxObject];
   }
   else
   {
      [self addRandomPhysicsSphereObject];
   }
}

- (void)setUpBox{

    CGImageRef image = [[UIImage imageNamed:@"outUV2.PNG"] CGImage];
    textureInfo1 = [GLKTextureLoader textureWithCGImage:image options:nil error:NULL];
    self.baseEffect.texture2d0.name = textureInfo1.name;
    self.baseEffect.texture2d0.enabled = YES;

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer( GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), final_meshVerts);

    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), final_meshNormals);

    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), final_meshTexCoords);

    //glDisableVertexAttribArray(GLKVertexAttribTexCoord0);

}

- (void)drawPhysicsBoxObjects{

    //self.baseEffect.texture2d0.target = textureInfo1.target;

    PAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

    GLKMatrix4 savedModelviewMatrix = self.baseEffect.transform.modelviewMatrix;

    for(PPhysicsObject *currentObject in self.boxPhysicsObjects){
        self.baseEffect.transform.modelviewMatrix =
        GLKMatrix4Multiply(savedModelviewMatrix,[appDelegate physicsTransformForObject:currentObject]);

        [self.baseEffect prepareToDraw];

        glDrawArrays(GL_TRIANGLES, 0, final_meshNumVerts);
    }

    self.baseEffect.light0.diffuseColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f);// Alpha

    for(PPhysicsObject *currentObject in self.immovableBoxPhysicsObjects){
        self.baseEffect.transform.modelviewMatrix = GLKMatrix4Multiply(savedModelviewMatrix, [appDelegate physicsTransformForObject:currentObject]);
        [self.baseEffect prepareToDraw];

        glDrawArrays(GL_TRIANGLES,0, final_meshNumVerts);
    }

    self.baseEffect.transform.modelviewMatrix = savedModelviewMatrix;
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
    static float a = 0;
    a = a+0.1;
    //NSLog(@"a : %f",a);
    self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeLookAt(
                                                                     0, 9.8, 10.0, // Eye position
                                                                     0.0, 1.0, 0.0,  // Look-at position
                                                                     0.0, 1.0, 0.0); // Up direction

    const GLfloat  aspectRatio = (GLfloat)view.drawableWidth / (GLfloat)view.drawableHeight;

   self.baseEffect.transform.projectionMatrix =
   GLKMatrix4MakePerspective(GLKMathDegreesToRadians(35.0f),aspectRatio,0.2f,200.0f); // Far arbitrarily far enough to contain scene

   self.baseEffect.light0.position = GLKVector4Make(0.6f, 1.0f, 0.4f, 0.0f);

   [self.baseEffect prepareToDraw];

   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    [self drawPhysicsSphereObjects];
    [self drawPhysicsBoxObjects];
    //[self drawPhysicsCylinderObjects];
}

- (void)addRandomPhysicsSphereObject{
    PAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

    PPhysicsObject *anObject = nil;

    if([self.spherePhysicsObjects count] < PMAX_NUMBER_BLOCKS)
    {
        NSLog(@"if");
        anObject = [[PPhysicsObject alloc] init];
    }
    else
    {
        NSLog(@"else");
        anObject = [self.spherePhysicsObjects objectAtIndex:0];
        [self.spherePhysicsObjects removeObjectAtIndex:0];
    }

    [self.spherePhysicsObjects addObject:anObject];

    [appDelegate physicsRegisterSphereObject:anObject
                                    position:GLKVector3Make(0,3.5,-2)
                                        mass:0.0f];
    [self setUpSphere];

    /*[appDelegate physicsSetVelocity:GLKVector3Make(
     random() / (float)RAND_MAX * 2.0f - 1.0f,
     0.0f,
     random() /(float)RAND_MAX * 2.0f - 1.0f)
     forObject:anObject];*/
}

- (void)setUpSphere{

    CGImageRef image = [[UIImage imageNamed:@"basketball.png"] CGImage];
    textureInfo = [GLKTextureLoader textureWithCGImage:image options:nil error:NULL];

    self.baseEffect.texture2d0.name = textureInfo.name;
    self.baseEffect.texture2d0.enabled = YES;

    glEnableVertexAttribArray( GLKVertexAttribPosition);
    glVertexAttribPointer( GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), newbasketballVerts);

    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), newbasketballNormals);

    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), newbasketballTexCoords);

    //glDisableVertexAttribArray(GLKVertexAttribTexCoord0);

}

- (void)drawPhysicsSphereObjects{
    NSLog(@"draw");
    /*static int x = 1;
     if (x>20) {
     x=20;
     }
     matrix = GLKMatrix4Identity;
     matrix = GLKMatrix4MakeTranslation(0.1 * (x++), 0.0, 0.0);*/
    //self.baseEffect.texture2d0.target = textureInfo2.target;

    PAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

    GLKMatrix4 savedModelviewMatrix = self.baseEffect.transform.modelviewMatrix;

    /*CGImageRef image = [[UIImage imageNamed:@"basketball.png"] CGImage];
     GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithCGImage:image options:nil error:NULL];

     self.baseEffect.texture2d0.name = textureInfo.name;
     self.baseEffect.texture2d0.target = textureInfo.target;*/

    self.baseEffect.light0.diffuseColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f);
    //glVertexPointer(3, GL_FLOAT, 0, sphereVerts);
    //glNormalPointer(GL_FLOAT, 0, sphereNormals);
    //glTexCoordPointer(2, GL_FLOAT, 0, final meshTexCoords);

    /*glGenBuffers(1, &ballVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, ballVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(MeshVertexData), MeshVertexData, GL_STATIC_DRAW);

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(arrowVertexData), 0);
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_TRUE, sizeof(arrowVertexData), (void *)offsetof(arrowVertexData, normal));
    glBindVertexArrayOES(arrowVertexArray);*/

    //glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    //glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), newbasketballTexCoords);
    if (!isSecondPlayer) {
        for(PPhysicsObject *currentObject in self.spherePhysicsObjects)
        {NSLog(@"first");
            self.baseEffect.transform.modelviewMatrix =
            GLKMatrix4Multiply(savedModelviewMatrix, [appDelegate physicsTransformForObject:currentObject]);
            [self.baseEffect prepareToDraw];

            glDrawArrays(GL_TRIANGLES,  0, newbasketballNumVerts);
            //glDrawArrays(GL_TRIANGLES, 0, sizeof(MeshVertexData) / sizeof(arrowVertexData));
        }
    }
    else{
        for(PPhysicsObject *currentObject in self.secondSpherePhysicsObjects)
        {
            self.baseEffect.transform.modelviewMatrix =
            GLKMatrix4Multiply(savedModelviewMatrix, [appDelegate physicsTransformForObject:currentObject]);
            [self.baseEffect prepareToDraw];

            glDrawArrays(GL_TRIANGLES,  0, newbasketballNumVerts);
            //glDrawArrays(GL_TRIANGLES, 0, sizeof(MeshVertexData) / sizeof(arrowVertexData));
        }
    }
    //glBindBuffer(GL_ARRAY_BUFFER, 0);
    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    //glDisableVertexAttribArray(GLKVertexAttribTexCoord0);
    self.baseEffect.transform.modelviewMatrix = savedModelviewMatrix;
}

Why is this only using one texture for all three, and not three different textures, one for each object? How can I fix this?


Solution

  • I had achieved a scene that the moon around the earth moving. different textures for the earth and the moon. under GLKit frame, the code just like this:

    -(void)viewDidLoad
    {
         //......
        // Setup Earth texture  
    CGImageRef earthImageRef =  
    [[UIImage imageNamed:@"Earth512x256.jpg"] CGImage];  
    
    earthTextureInfo = [GLKTextureLoader  
                        textureWithCGImage:earthImageRef  
                        options:[NSDictionary dictionaryWithObjectsAndKeys:  
                                 [NSNumber numberWithBool:YES],  
                                 GLKTextureLoaderOriginBottomLeft, nil nil]  
                        error:NULL];  
    
    // Setup Moon texture  
    CGImageRef moonImageRef =  
    [[UIImage imageNamed:@"Moon256x128.png"] CGImage];  
    
    moonTextureInfo = [GLKTextureLoader  
                       textureWithCGImage:moonImageRef  
                       options:[NSDictionary dictionaryWithObjectsAndKeys:  
                                [NSNumber numberWithBool:YES],  
                                GLKTextureLoaderOriginBottomLeft, nil nil]  
                       error:NULL];  
    //......
    

    }

    then, draw earth and moon.

    - (void)drawEarth  
    {  
    //setup texture
    self.baseEffect.texture2d0.name = earthTextureInfo.name;  
    self.baseEffect.texture2d0.target = earthTextureInfo.target;  
    
    //  
    GLKMatrixStackPush(self.modelviewMatrixStack);  
    
    
    GLKMatrixStackRotate(   // Rotate (tilt Earth's axis)  
                         self.modelviewMatrixStack,  
                         GLKMathDegreesToRadians(SceneEarthAxialTiltDeg),  
                         1.0, 0.0, 0.0);  
    GLKMatrixStackRotate(   // Rotate about Earth's axis  
                         self.modelviewMatrixStack,  
                         GLKMathDegreesToRadians(earthRotationAngleDegrees),  
                         0.0, 1.0, 0.0);  
    
    
    self.baseEffect.transform.modelviewMatrix =  
    GLKMatrixStackGetMatrix4(self.modelviewMatrixStack);  
    
    //draw earth  
    [self.baseEffect prepareToDraw];  
    
    
    glBindVertexArrayOES(_vertexArray);  
    glDrawArrays(GL_TRIANGLES, 0, sphereNumVerts);  
    
    //pop 
    GLKMatrixStackPop(self.modelviewMatrixStack);  
    
    self.baseEffect.transform.modelviewMatrix =  
    GLKMatrixStackGetMatrix4(self.modelviewMatrixStack);  
    

    }

    - (void)drawMoon  
    {  
    
    self.baseEffect.texture2d0.name = moonTextureInfo.name;  
    self.baseEffect.texture2d0.target = moonTextureInfo.target;  
    
    
    GLKMatrixStackPush(self.modelviewMatrixStack);  
    
    GLKMatrixStackRotate(   // Rotate to position in orbit  
                         self.modelviewMatrixStack,  
                         GLKMathDegreesToRadians(moonRotationAngleDegrees),  
                         0.0, 1.0, 0.0);  
    GLKMatrixStackTranslate(// Translate to distance from Earth  
                            self.modelviewMatrixStack,  
                            0.0, 0.0, SceneMoonDistanceFromEarth);  
    GLKMatrixStackScale(    // Scale to size of Moon  
                        self.modelviewMatrixStack,  
                        SceneMoonRadiusFractionOfEarth,  
                        SceneMoonRadiusFractionOfEarth,  
                        SceneMoonRadiusFractionOfEarth);  
    GLKMatrixStackRotate(   // Rotate Moon on its own axis  
                         self.modelviewMatrixStack,  
                         GLKMathDegreesToRadians(moonRotationAngleDegrees),  
                         0.0, 1.0, 0.0);  
    // 
    self.baseEffect.transform.modelviewMatrix =  
    GLKMatrixStackGetMatrix4(self.modelviewMatrixStack);  
    
    //draw moon  
    [self.baseEffect prepareToDraw];  
    
    
    glBindVertexArrayOES(_vertexArray);  
    glDrawArrays(GL_TRIANGLES, 0, sphereNumVerts);  
    
    GLKMatrixStackPop(self.modelviewMatrixStack);  
    
    self.baseEffect.transform.modelviewMatrix =  
    GLKMatrixStackGetMatrix4(self.modelviewMatrixStack);  
    
    }