我想设置一个纹理数组用于我的形状。我在互联网上研究了这个话题,但几乎没有任何像我这样的新手可以使用的参考资料。 再一次,我想要实现的是一个纹理数组,我可以用它来将不同的纹理映射到我的形状的不同面上。 到目前为止,我只有一个从UIView生成的纹理。
我的核心问题是:
这是我的代码:
- (void)setupGL {
[EAGLContext setCurrentContext:self.myContext];
self.effect = [[GLKBaseEffect alloc] init];
self.layer.contentsScale = 2.0;
BOOL useTexture = YES;
// Create default framebuffer object.
glGenFramebuffers(1, &defaultFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFrameBuffer);
myView = [[MyView alloc]initWithFrame:CGRectMake(0,0,320,320)];
self.effect.transform.projectionMatrix = GLKMatrix4MakePerspective(45.0f,0.9f, 0.01f, .08f);
self.effect.transform.projectionMatrix = GLKMatrix4Translate(self.effect.transform.projectionMatrix, 0, 0.1, 1.2);
rotMatrix = GLKMatrix4Translate(self.effect.transform.modelviewMatrix,0,0,-2);
self.effect.transform.modelviewMatrix = rotMatrix;
/*********************
MAPPING UIVIEW ONTO THE FACE
****************/
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
self.effect.texture2d0.enabled = true;
GLubyte *pixelBuffer = (GLubyte *)malloc(
4 *
myView.bounds.size.width * coordToPixScale *
myView.bounds.size.height * coordToPixScale);
CGContextRef context =
CGBitmapContextCreate(pixelBuffer,
myView.bounds.size.width*coordToPixScale, myView.bounds.size.height*coordToPixScale,
8, 4*myView.bounds.size.width *coordToPixScale,
colourSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colourSpace);
// draw the view to the buffer
[myView.layer renderInContext:context];
// upload to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0,
GL_RGBA,
myView.bounds.size.width * coordToPixScale, myView.bounds.size.height * coordToPixScale, 0,
GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// clean up
CGContextRelease(context);
glGenBuffers(1, &texArray);
glBindBuffer(GL_ARRAY_BUFFER, texArray);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glBufferData(GL_ARRAY_BUFFER, sizeof(TexCoords), TexCoords, GL_STATIC_DRAW);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0,0);
/**************************
******************************************/
free(pixelBuffer);
glGenRenderbuffers(1, &depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, myView.bounds.size.width * coordToPixScale, myView.bounds.size.height * coordToPixScale);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
glEnable(GL_DEPTH_TEST);
glGenBuffers(1, &vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, vertexArray);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glVertexAttribPointer(GLKVertexAttribPosition,3,GL_FLOAT,GL_FALSE,0,0);
}
此方法在绘制时被调用:
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
self.opaque = NO;
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, sizeof(Vertices) / (sizeof(GLfloat) * 3));
}
答案 0 :(得分:0)
看到你正在使用GLKit我认为你可以更容易地加载纹理。首先创建CGImageRef
:
CGImageRef image0 =
[[UIImage imageNamed:@"image0.png"] CGImage];
将其加载到GLKTextureInfo
ivar textureInfo0
中,如下所示:
self.textureInfo0 = [GLKTextureLoader
textureWithCGImage:image1
options:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],
GLKTextureLoaderOriginBottomLeft, nil]
error:NULL];
对第二个纹理做同样的事情。这应该命名为textureInfo1
。
使用glEnableVertexAttribArray
属性使用glVertexAttribPointer
和GLKVertexAttribTexCoord0
加载纹理坐标。我认为你已经设置了上述内容。您需要将纹理中的坐标映射到目标三角形。例如,如果要绘制一个由两个三角形组成的正方形,则需要将源图像的S和T坐标映射两次,即对于每个相应的三角形。例如带有坐标的三角形1:
{0.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}.
(如果你绘制的那样你会看到它是一个三角形)
然后,正方形的第二个三角形如下:
{1.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}.
接下来,在您的绘图方法中;
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
首先,设置初始纹理:
self.effect.texture2d0.name = self.textureInfo0.name;
self.effect.texture2d0.target = self.textureInfo0.target;
[self.effect prepareToDraw];
根据需要使用glDrawArrays
绘制三角形。然后,用第二个纹理替换:
self.effect.texture2d0.name = self.textureInfo1.name;
self.effect.texture2d0.target = self.textureInfo1.target;
[self.effect prepareToDraw];
并使用glDrawArrays
绘制其余三角形。他们将使用第二个纹理。
继续使用不同的self.effect.texture2d0.name
实例替换self.effect.texture2d0.target
和GLKTextureInfo
以绘制不同的纹理。