2012-02-29 3 views
1

Я пытаюсь получить multisampling для работы в моем приложении OpenGL ES.Почему не работает мультисэмплинг?

Framebuffer код установки:

glGenFramebuffersOES(1, &framebuffer); 
glGenRenderbuffersOES(1, &colorRenderbuffer); 

glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer); 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); 
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer]; 
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer); 

GLint backingWidth; 
GLint backingHeight; 
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); 
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); 

glGenFramebuffersOES(1, &sampleFramebuffer); 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, sampleFramebuffer); 

glGenRenderbuffersOES(1, &sampleColorRenderbuffer); 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, sampleColorRenderbuffer); 
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_RGBA8_OES, backingWidth, backingWidth); 
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, sampleColorRenderbuffer); 

glGenRenderbuffersOES(1, &sampleDepthRenderbuffer); 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, sampleDepthRenderbuffer); 
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_DEPTH_COMPONENT16_OES, backingWidth, backingWidth); 
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, sampleDepthRenderbuffer); 

Rendering Код:

glBindFramebufferOES(GL_RENDERBUFFER_OES, sampleFramebuffer); 
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 

GLfloat vertices[] = { 
    1.0f, 1.0f, 0.0f, 
    2.0f, 4.0f, 0.0f, 
    1.0f, 3.0f, 0.0f 
}; 
glColor4f(1.0f, 0.0f, 0.0f, 1.0f); 
glVertexPointer(3, GL_FLOAT, 0, vertices); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); 

glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, sampleFramebuffer); 
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, framebuffer); 
glResolveMultisampleFramebufferAPPLE(); 

glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); 
[context presentRenderbuffer:GL_RENDERBUFFER_OES]; 

Результат:

Rendering result

Как вы можете видеть треугольник до сих пор псевдонимами стороны.

+0

Я не могу найти проблему, кроме, возможно, вашего предположения, что 4 является приемлемым уровнем мультисэмплирования, когда вы должны запрашивать 'glGetIntegerv (GL_MAX_SAMPLES_APPLE, & maxSamplesAllowed) '. Я специально проверил вашу строку кода для строки против некоторых из моих, и вы, кажется, делаете все безупречно. Если вы выполняете быстрый' glCheckFramebufferStatusOES' на 'sampleFramebuffer', вы получаете соответствующий ответ? – Tommy

+0

@Tommy 1) Ошибка: я привязываю 'sampeFramebuffer' как renderbuffer в начале кода рендеринга (спасибо Mārtiņš Možeiko). 2) iPhone поддерживает ровно 4 выборки. 3) Буфер кадров' glCheckFramebufferStatusOES' завершен. –

ответ

2

sampleFramebuffer - это фреймбуфер, а не renderbuffer. Но вы привязываете его как renderbuffer в рендеринге кода. Это неверно. Вы должны проверить ошибки OpenGL, вызвав glGetError - это скажет вам, какой вызов GL недействителен.

Вашего код рендеринг должен начинаться со следующей строкой:

glBindFramebufferOES(GL_FRAMEBUFFER_OES, sampleFramebuffer); 

Остальным это нормально. Но для повышения производительности можно использовать glDiscardFramebufferEXT вызов на вашем мультитекстурированного фреймбуфером после Resolve вызова:

glResolveMultisampleFramebufferAPPLE(); 
const GLenum discards[] = {GL_COLOR_ATTACHMENT0,GL_DEPTH_ATTACHMENT}; 
glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE,2,discards); 
мульти-выборки
+0

Вы правы, там это ошибка в вызове функции связывания. Я исправил его. Я вижу падение производительности, это означает, что теперь он использует 'sampleFramebuffer'. Но он по-прежнему не видит никаких визуальных изменений. Я получаю ошибку 1282 (0x0502, 'GL_INVALID_OPERATION') после вызова' glResolveMultisampleFramebufferAPPLE() '. –

+0

Правильно, я не вижу каких-либо визуальных различий на iPhone 3G. Но симулятор и iPhone 4S делают что-то непредсказуемое. –

+0

В соответствии с документацией (http://www.khronos.org/registry/gles/extensions/APPLE/APPLE_framebuffer_multisample.txt) glResolveMultisampleFramebufferAPPLE возвращает GL_INVALID_OPERATION, если 1) SAMPLE_BUFFERS для чтения фреймбуфера равно нулю, 2) SAMPLE_BUFFERS для фрейм-буфера draw больше нуля, 3) считывающий фреймбуфер или рисовальный фрейм-буфер не имеет цветного вложения; 4) размеры буферов считывания и рисования не идентичны; 5) компоненты в формате цветного вложения рамки кадра не присутствуют в формате цветной вставки считывающего фреймбуфера. –

0

компании Apple не полностью избавиться от псевдонимами краев, особенно в углах, близких 0, 90, 180, & 270. Но это должно помочь смягчить их.

В некоторых моих тестах я обнаружил, что он слегка отличается от него. И вы должны решить, стоит ли это в вашем приложении. Например, на iPhone плотность пикселей настолько мала, что это не имеет никакого значения для моего глаза. На tvOS, однако, псевдонимы довольно заметны, например, как 45-дюймовый экран.