0

我正在尝试加载将在四个顶点之间的简单正方形上绘制的纹理。不幸的是,这似乎可行的唯一方法是,如果我将用于加载图像数据的代码放入每帧调用的函数中。我的代码最初基于 ARToolKit 函数(因此得名 drawCube)。这是我的代码的样子:

- (void) drawCube
{

glStateCacheEnableTex2D();
glStateCacheEnableBlend();
glStateCacheBlendFunc(GL_ONE, GL_SRC_COLOR);
glStateCacheEnableClientStateVertexArray();
glStateCacheEnableClientStateTexCoordArray();
glStateCacheEnableClientStateNormalArray();


const GLfloat cube_vertices [4][3] = {
    {-1.0f, 1.0f, -1.0f}, {1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f} };
const GLfloat texCoords [4][2] = {
    {0.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}
};
const GLfloat normals [4][3] = {
    {0.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, 1.0}
};


glGenTextures(1, &texture[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:@"iTunesArtwork" 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 contextt = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
CGContextTranslateCTM (contextt, 0, height);
CGContextScaleCTM (contextt, 1.0, -1.0);
CGColorSpaceRelease( colorSpace );
CGContextClearRect(contextt, CGRectMake( 0, 0, width, height ) );
CGContextTranslateCTM(contextt, 0, height - height );
CGContextDrawImage(contextt, CGRectMake( 0, 0, width, height ), image.CGImage );

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

CGContextRelease(contextt);

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

glPushMatrix(); // Save world coordinate system.
glScalef(20.0f, 20.0f, 20.0f);
glTranslatef(0.0f, 0.0f, 1.0f); // Place base of cube on marker surface.
glStateCacheDisableLighting();
glBindTexture(GL_TEXTURE_2D, texture[0]);
glStateCacheVertexPtr(3, GL_FLOAT, 0, cube_vertices);
glStateCacheNormalPtr(GL_FLOAT, 0, normals);
glStateCacheTexCoordPtr(2, GL_FLOAT, 0, texCoords);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glStateCacheDisableClientStateNormalArray();
glStateCacheDisableClientStateTexCoordArray();
glStateCacheDisableClientStateVertexArray();


glPopMatrix();    // Restore world coordinate system.
}

这段代码工作正常,唯一的问题是它被调用的每一帧都有一个 AR 标记对相机可见,这当然是不行的。但是,当我尝试将图像数据线移动到 init 函数时,我只得到一个没有纹理的白色方块。我移动的行是前 3 条 Enable Tex2D/Blend 和 BlendFunc。然后在正常坐标之后,一切都归结为[texData release]。我的代码基于我在这里阅读的教程:http: //iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-part-6_25.html

对我来说,一切似乎都在正确的地方,但显然情况并非如此。谁能解释一下我的问题?

4

1 回答 1

0

没有看到你的初始化代码,我不能确定。可能您正在运行此代码以在设置 OpenGL 上下文之前加载纹理。上下文创建是在 Apple 的 Xcode OpenGL 应用程序模板中的视图控制器的 viewDidLoad 方法中完成的。由于服务器离线,我无法从这个博客系列下载模板。也许您的模板以相同的方法创建上下文。尝试移动纹理加载代码,使其在上下文创建后运行。

顺便说一句,本教程相当陈旧。自从该博客条目发布以来,GLKit 被添加到 iOS SDK 中。GLKit 包含非常方便的纹理加载代码。

于 2012-12-07T16:36:47.863 回答