如何在iOS5中使用Square上的图像放置2D纹理

时间:2012-07-19 06:04:42

标签: ios opengl-es textures glkit

这是我在iphone中的第一个应用程序,我正在尝试在GLKView中加载纹理。我没有使用GLKVIewController课程。 。经过大量的搜索,我认为我经理将图像加载到2D纹理中,但我仍然不确定如何将图像映射到矩形。以下是我用来绘制矩形的代码。

创建顶点数组:

GLfloat gSqaureVertexData[216] = 
{
    // Data layout for each line below is:
    // positionX, positionY, positionZ,     normalX, normalY, normalZ,
    0.5f, -0.5f, -0.5f,        0.0f, 0.0f, -1.0f,
    -0.5f, -0.5f, -0.5f,       0.0f, 0.0f, -1.0f,
    0.5f, 0.5f, -0.5f,         0.0f, 0.0f, -1.0f,
    0.5f, 0.5f, -0.5f,         0.0f, 0.0f, -1.0f,
    -0.5f, -0.5f, -0.5f,       0.0f, 0.0f, -1.0f,
    -0.5f, 0.5f, -0.5f,        0.0f, 0.0f, -1.0f
};

在viewDidLoad中初始化上下文:

 context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
    CAEAGLLayer *eaglLayer = (CAEAGLLayer*)self.view.layer;
    eaglLayer.opaque=NO;

    glView = [[GLKView alloc]initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+45, self.view.frame.size.width, self.view.frame.size.height-100.0f)];

    glView.context=context;
    glView.delegate=self;
    glView.backgroundColor=[UIColor clearColor];
    glView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
    [self setupGL];
    [self.view addSubview:glView];

将png图像加载到TEXTURE对象和其他setUp

-(void) setupGL
{
    [EAGLContext setCurrentContext:context];

    //[self loadShaders];

    self.effect = [[GLKBaseEffect alloc] init];
    //self.effect.light0.enabled = GL_TRUE;
    //self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);

    glEnable(GL_DEPTH_TEST);

    glGenVertexArraysOES(1, &_vertexArray);
    glBindVertexArrayOES(_vertexArray);

    glGenBuffers(1, &_vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(gSqaureVertexData), gSqaureVertexData, GL_STATIC_DRAW);

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

    glBindVertexArrayOES(0);
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    NSString *path = [[NSBundle mainBundle] pathForResource:@"texture" ofType:@"png"];
    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 contextTex = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
    CGColorSpaceRelease( colorSpace );
    CGContextClearRect( contextTex, CGRectMake( 0, 0, width, height ) );
    CGContextTranslateCTM( contextTex, 0, height - height );
    CGContextDrawImage( contextTex, CGRectMake( 0, 0, width, height ), image.CGImage );

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

    CGContextRelease(contextTex);

    free(imageData);
    [image release];
    [texData release];    
}

在drawInRect中绘制sqaure:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glBindVertexArrayOES(_vertexArray);

    // Render the object[[ with GLKit
    [self.effect prepareToDraw];

    glDrawArrays(GL_TRIANGLES, 0, 36);

    // Render the object again with ES2
    glUseProgram(_program);

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

    glDrawArrays(GL_TRIANGLES, 0, 36);
}

1 个答案:

答案 0 :(得分:0)

您需要为每个顶点添加纹理坐标,将纹理设置为活动纹理,并为纹理坐标添加顶点属性:

顶点数据:

//Vertex, Normal, Texture coordinate (ranges from 0 to 1)
0.5f, -0.5f, -0.5f,        0.0f, 0.0f, -1.0f,  1, 1,
-0.5f, -0.5f, -0.5f,       0.0f, 0.0f, -1.0f,  0, 1,
0.5f, 0.5f, -0.5f,         0.0f, 0.0f, -1.0f,  1, 0,
0.5f, 0.5f, -0.5f,         0.0f, 0.0f, -1.0f,  1, 0, etc

设置活动纹理(这是标准的OpenGL方式,不确定GLKit):

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);

设置纹理属性(可能不完全正确,我不熟悉GLKit):

glEnableVertexAttribArray(GLKVertexAttribTexCoord);
glVertexAttribPointer(GLKVertexAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(16));