如何在 glkit 中获得立方体每个面上具有不同纹理图像的立方体?

问题描述 投票:0回答:2

我正在开发一款游戏,我必须摇动骰子才能获得数字。我正在使用 glkit 制作一个立方体并通过 GLKBaseEffect 对该立方体进行纹理化。出色地 !我想要一个立方体的每个面上都有不同的纹理图像,以便它可以模拟骰子。我希望立方体的每个面显示不同的骰子图像,例如一个面显示数字 1,另一个面显示数字 2,依此类推。

我将我的代码粘贴在这里。

- (void)setupGL {

[EAGLContext setCurrentContext:self.context];
glEnable(GL_CULL_FACE);

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

NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithBool:YES],
                          GLKTextureLoaderOriginBottomLeft, 
                          nil];

NSError * error;    
NSString *path = [[NSBundle mainBundle] pathForResource:@"tile_floor" ofType:@"png"];
GLKTextureInfo * info = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
if (info == nil) {
    NSLog(@"Error loading file: %@", [error localizedDescription]);
}
self.effect.texture2d0.name = info.name;
self.effect.texture2d0.enabled = true;

// draw one texture per side



// New lines
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

// Old stuff
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);

// New lines (were previously in draw)
glEnableVertexAttribArray(GLKVertexAttribPosition);        
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Color));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, TexCoord));

// New line
glBindVertexArrayOES(0); 
}

并从这里调用drawInRects中的绘制元素方法

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {

glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
[self.effect prepareToDraw];
glBindVertexArrayOES(_vertexArray);
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);

}

我怎样才能实现这个目标?

opengl-es ios6 opengl-es-2.0 game-physics glkit
2个回答
1
投票

GLKit 允许的纹理数量有限(我认为是 2 个),因此您需要所谓的纹理贴图。基本上,你设置一个像这样的纹理:

a a a a a a a a b b b b b b b b c c c c c c c c d d d d d d d d
a a a a a a a a b b b b b b b b c c c c c c c c d d d d d d d d
a a a a a a a a b b b b b b b b c c c c c c c c d d d d d d d d
a a a a a a a a b b b b b b b b c c c c c c c c d d d d d d d d
a a a a a a a a b b b b b b b b c c c c c c c c d d d d d d d d ...
a a a a a a a a b b b b b b b b c c c c c c c c d d d d d d d d
a a a a a a a a b b b b b b b b c c c c c c c c d d d d d d d d
a a a a a a a a b b b b b b b b c c c c c c c c d d d d d d d d

然后设置每个顶点的纹理坐标以指向要使用的纹理的子部分。

注意:即使 GLKit 像许多 OpenGL 实现一样支持更多纹理,这种方法也比加载大量纹理并一直切换它们要快得多。

glBind()
是一个相对较慢的操作。

另请注意:如果您的纹理图像边数是 2 的幂(2、4、8、16、32...),那么事情会更有效,纹理图像中可以有空白(未使用)点。我通常会在未使用的部分放一个大红色斑点,这样我就可以知道它是否无意中出现在任何东西上。

因此,您的骰子纹理可能是 32 像素高、512 (32*8) 宽,但您只使用它的前 192 (32*6) 个纹理,并且在一个图像中拥有一组六个 32x32 纹理。


0
投票

我通过分层或拥有更多对象来做到这一点。所以,一个立方体,然后是两个刚好位于立方体表面的正方形。如果立方体是 2 x 2 x 2,只需将图片顶点设置为 2.01,这样就像蛋糕糖衣

因此,您不是在对立方体进行纹理处理,而是在添加更多对象。这是一个视频示例 - https://www.youtube.com/watch?v=lh2Zc8kHFbU&list=UUu5WfUbKdhLCW9aPq3WZsNA

© www.soinside.com 2019 - 2024. All rights reserved.