[英]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.