我正在开发一款游戏,我必须摇动骰子才能获得数字。我正在使用 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);
}
我怎样才能实现这个目标?
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 纹理。
我通过分层或拥有更多对象来做到这一点。所以,一个立方体,然后是两个刚好位于立方体表面的正方形。如果立方体是 2 x 2 x 2,只需将图片顶点设置为 2.01,这样就像蛋糕糖衣
因此,您不是在对立方体进行纹理处理,而是在添加更多对象。这是一个视频示例 - https://www.youtube.com/watch?v=lh2Zc8kHFbU&list=UUu5WfUbKdhLCW9aPq3WZsNA