[英]Drawing with GLKit
我正在尝试使用opengl编写游戏,但是我在使用新的glkit类和iOS的默认模板时遇到了很多麻烦。
- (void)viewDidLoad
{
[super viewDidLoad];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!self.context) {
NSLog(@"Failed to create ES context");
}
if(!renderer)
renderer = [RenderManager sharedManager];
tiles = [[TileSet alloc]init];
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
[self setupGL];
}
- (void)setupGL
{
int width = [[self view] bounds].size.width;
int height = [[self view] bounds].size.height;
[EAGLContext setCurrentContext:self.context];
self.effect = [[GLKBaseEffect alloc] init];
self.effect.light0.enabled = GL_TRUE;
self.effect.light0.diffuseColor = GLKVector4Make(0.4f, 0.4f, 0.4f, 1.0f);
//Configure Buffers
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glGenRenderbuffers(2, &colourRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colourRenderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colourRenderBuffer);
glGenRenderbuffers(3, &depthRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);
//Confirm everything happened awesomely
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER) ;
if(status != GL_FRAMEBUFFER_COMPLETE) {
NSLog(@"failed to make complete framebuffer object %x", status);
}
glEnable(GL_DEPTH_TEST);
// Enable the OpenGL states we are going to be using when rendering
glEnableClientState(GL_VERTEX_ARRAY);
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
float iva[] = {
0.0,0.0,0.0,
0.0,1.0,0.0,
1.0,1.0,0.0,
1.0,0.0,0.0,
};
glVertexPointer(3, GL_FLOAT, sizeof(float) * 3, iva);
glDrawArrays(GL_POINTS, 0, 4);
}
@end
有了这个,缓冲区清除(灰色),但顶点数组没有渲染。 我不知道该怎么做,由于技术的时代,关于如何正确使用glkit的信息不多。
我没有在您的设置代码中看到任何加载着色器的内容 - 我认为您在代码中的某个位置执行此操作?
此外,在您的设置代码中,您正在创建帧缓冲区。 GLKView
为您完成此操作 - 实际上您正在告诉视图在viewDidLoad
方法中使用24位深度缓冲区:
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
那么你的glkView:drawInRect:
上面的代码正在做的是:“绑定我的手工制作的帧缓冲区,并将一些东西放入其中”。 然后GLKView
会自动呈现,但没有任何内容被吸引到你的GLKView
,你只会被吸引到手工制作的缓冲区中。 除非您需要额外的帧缓冲对象来执行渲染到纹理等任务,否则您根本不需要关注帧缓冲区创建 - 让GLKView
自动执行此操作。
你应该在setupGL
方法中做什么(或者你在设置中的任何地方),创建你的顶点数组对象,记住执行绘制所需的openGL状态。 然后,在glkView:drawInRect:
方法中,您应该:
glClear()
清除。 glDrawArrays()
或glDrawElements()
绘制数据。 GLKView
自动将其上下文设置为当前,并在每个绘制周期之前绑定其framebuffer对象。
也许试着把GLKView
成一个普通的UIView
。 它为您处理幕后的大部分openGL代码,让您只需告诉它需要绘制的内容。 它有drawRect:
代码就像一个普通的UIView
- 在drawRect:
有一个常规的UIView
drawRect:
你只需告诉它应该绘制什么,例如使用Core Graphics函数 - 你不要告诉它呈现自己。
然后,最好将GLKViewController
视为处理幕后渲染循环的机制。 您不需要实现计时器,甚至担心暂停进入后台的应用程序上的动画。 您只需要覆盖update
或 glkViewControllerUpdate:
方法(取决于您是子类还是委托)来更新openGL对象或视图矩阵的状态。
我发了一篇关于使用GLKit设置基本项目模板的方法的帖子。 你可以在这里找到它:
我还没有使用过GLKit,但似乎你在绘制之后没有呈现你的帧缓冲。 在iOs下使用OpenGL ES 2但没有GLKit的应用程序中,我使用在渲染循环结束时调用以下代码。
if(context) {
[EAGLContext setCurrentContext:context];
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER];
}
正如我所说,我还没有使用过GLKit所以我希望这可能有用。
我想你忘记打电话了
[self.effect prepareToDraw];
就在此之前
glDrawArrays(GL_POINTS, 0, 4);
由于GLKit模仿OpenGL ES 1.1渲染管道,因此您无需包含用于定义Shader的例程。 如果你想使用像OpenGL ES1.1这样的基本管道,GLKit实际上是为你做的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.