iOS openGL ES uygulaması geliştiriyorum.- [EAGLContext renderbufferStorage: fromDrawable:] İkinci kez açma başarısız mı?
Normal EAGLView/ES2Render öğelerini yapıyorum. UIView
'ın -layoutSubviews
denir ve ben sırayla -resizeFromLayer:
yürütmek Kısa bir süre sonra
- (BOOL) createFramebuffers
{
[EAGLContext setCurrentContext:_mainContext];
// [ A ] On-screen
// 1. Framebuffer
glGenFramebuffers(1, &_mainFramebuffer);
bindFramebuffer(_mainFramebuffer);
// 2. Color buffer
glGenRenderbuffers(1, &_mainColorbuffer);
bindRenderbuffer(_mainColorbuffer);
// Adjust size to view's layer:
CAEAGLLayer* layer = (CAEAGLLayer*)[_view layer];
if (![_mainContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]) {
// something went horribly wrong
NSLog(@"-[ES2Renderer createFramebuffers]: Failed to obtain renderbuffer storage from layer!");
return NO;
}
// Query new size:
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_backingWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_backingHeight);
// Attach to color:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _mainColorbuffer);
// 3. Depth buffer
glGenRenderbuffers(1, &_depthBuffer);
bindRenderbuffer(_depthBuffer);
if (_useStencilBuffer) {
// Depth + Stencil
// Allocate storage:
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight);
// Attach to depth:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer);
// Attach to stencil:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer);
}
else{
// Depth only
// Allocate storage:
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight);
// Attachto depth:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer);
}
// 4. Validate the set:
GLenum framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (framebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
// Something went wrong!
NSLog(@"-[ES2Renderer createFramebuffers]: Failed to make complete framebuffer object: %@",
[self stringFromFramebufferStauts:framebufferStatus]);
return NO;
}
// [ B ] Off-screen (Render-to-texture)
// 1. Framebuffer
glGenFramebuffers(1, &_transFramebuffer);
bindFramebuffer(_transFramebuffer);
// 2. Depth buffer
glGenRenderbuffers(1, &_transDepthBuffer);
bindRenderbuffer(_transDepthBuffer);
if (_useStencilBuffer) {
// Allocate storage:
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight);
// Attach to depth:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _transDepthBuffer);
// Attach to stencil:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _transDepthBuffer);
}
else{
// Allocate storage
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight);
// Attach to depth:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _transDepthBuffer);
}
// 3. Textures (color buffers)
GLuint* texPtrs[2] = {&_transTexture1, &_transTexture2};
for (NSUInteger i=0; i < 2; i++) {
GLuint* texPtr = texPtrs[i];
// Create:
glGenTextures(1, texPtr);
// Bind:
bindTexture2D(*texPtr);
// Configure for pixel-aligned use:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Allocate storage:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backingWidth, _backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// Attach:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texPtr, 0);
framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
// Validate:
if (framebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
// Something went wrong!
NSLog(@"-[ES2Renderer createFramebuffers]: Failed to make complete framebuffer object: %@",
[self stringFromFramebufferStauts:framebufferStatus]);
return NO;
}
}
// Final State:
bindFramebuffer(_mainFramebuffer);
bindRenderbuffer(_mainColorbuffer);
bindTexture2D(0);
NSLog(@"-[ES2Renderer createFramebuffers] Succeeded.");
return YES;
}
,: Başlangıçta
, frambuffer oluşturma Aşağıdaki kodu kullanarak, başarılı neyin
- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer
{
// [ A ] On screen framebuffer
bindFramebuffer(_mainFramebuffer);
// 1. Resize color buffer
bindRenderbuffer(_mainColorbuffer);
if (![_mainContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]) {
// Something went wrong
return NO; // <-- SECOND TIME ON, THIS HAPPENS
}
// Query new size:
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_backingWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_backingHeight);
// 2. Resize depth buffer
bindRenderbuffer(_depthBuffer);
if (_useStencilBuffer) {
// (Depth & Stencil)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight);
}
else{
// (Depth only)
glRenderbufferStorage(GL_FRAMEBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight);
}
// ...Validate:
GLenum framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (framebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
// Something went wrong!
NSLog(@"-[ES2Renderer resizeFromLayer:]: Failed to make complete framebuffer object: %@",
[self stringFromFramebufferStauts:glCheckFramebufferStatus(GL_FRAMEBUFFER)]);
return NO;
}
// [ B ] Off screen (render-to-terxture) framebuffer
bindFramebuffer(_transFramebuffer);
// 1. Resize depth buffer
bindRenderbuffer(_transDepthBuffer);
if (_useStencilBuffer) {
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _backingWidth, _backingHeight);
}
else{
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, _backingWidth, _backingHeight);
}
// 2. Resize textures
GLuint* texPtrs[2] = {&_transTexture1, &_transTexture2};
for (NSUInteger i=0; i < 2; i++) {
GLuint* texPtr = texPtrs[i];
// Bind:
bindTexture2D(*texPtr);
// Configure for pixel-aligned use:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Allocate storage:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backingWidth, _backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// Attach:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texPtr, 0);
// Validate:
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
// Something went wrong!
NSString* statusString = [self stringFromFramebufferStauts:glCheckFramebufferStatus(GL_FRAMEBUFFER)];
NSLog(@"-[ES2Renderer resizeFromLayer:]: Failed to make complete framebuffer object: %@", statusString);
return NO;
}
}
bindFramebuffer(_mainFramebuffer);
bindRenderbuffer(_mainColorbuffer);
// Pass new ortho projection to shaders
[self initializeModelViewMatrix];
[self initializeSpriteProgram];
// Set new viewport
glViewport(0, 0, _backingWidth, _backingHeight);
NSLog(@"-[ES2Renderer resizeFromLayer:]: Succeeded.");
return YES;
}
Hiçbir şey Yapmak özeldir. Renklere ve derinliğe bağlı iki doku ile sahne geçişlerini işlemek için ayrı bir çerçeveleyicim var.
-renderbufferStorage:fromDrawable:
olarak adlandırılan ikinci kez (-layoutSubviews
->resizeFromLayer:
), bu her zaman başarısız (NO
döner); Bundan hemen önce glGetError()
numaralı telefonu arayarak hata yapmazsınız, ancak GL_INVALID_OPERATION
geri döndükten sonra hemen çağırır. Bunu göz ardı edip devam edersem glGetRenderbufferParameteriv()
hala bana doğru genişlik ve yüksekliği (iPhone 5 üzerinde sırasıyla 640 ve 1136) alır, ancak glCheckFramebufferStatus()
GL_FRAMEBUFFER_UNSUPPORTED
'u döndürür.
- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer
{
[self destroyFramebuffers];
return [self createFramebuffers];
}
... aynı hata devam (; bu kez -createFramebuffers
içinde -renderStorage:fromDrawable:
başarısız):
Alternatif olarak, yukarıdaki resizeFromLayer:
atlanır ve bu ile değiştirilir.
Şimdilik, sadece YES
'u döndürüyorum (uygulamam yalnızca portre özelliğini destekliyor, dolayısıyla hiçbir ekran boyutu değişikliği gerçekleşmiyor), ama gerçekten düzeltmek istiyorum çünkü bir gün manzarayı desteklemem gerekecek ... renderbufferStorage:fromDrawable:
başarısız olduğunu
gibi onları silmek, ancak iOS 7 cihazda çalışan yalnızca (simülatör) biçimde. Ne yazık ki neden kaynaklandığını bilmiyorum, ancak aygıtı yeniden başlatmak sorunu çözmek için ortaya çıktı. Yine de çok sinir bozucu ve tekrar olmayacağını garanti etmez ... – Stuart