#iphone #opengl-es #framebuffer #double-buffering
#iPhone #opengl-es #фреймбуфер #двойная буферизация
Вопрос:
Привет, ребята,
Я работаю над анимацией в opengl es. Анимация должна рисовать квадраты. Это уже работает, но как я могу скопировать содержимое из фреймбуфера в буфер рендеринга, проблема в том, что с каждым кадром на дисплее отображается только один квадрат.
Когда я тестировал это в симуляторе, и это сработало. С каждым новым кадром рисуется известный квадрат, а другие, которые уже были нарисованы, все еще находятся на экране. Но когда я тестировал это на устройстве, это не сработало. Экран просто мигал.
Я думаю, это происходит потому, что мой Mac, как и любой другой компьютер, использует двойную буферизацию, а iPhone этого не делает.
Пожалуйста, помогите мне.
Вот как я настраиваю свой фреймбуфер:
- (BOOL)createFramebuffer {
glGenFramebuffersOES(1, amp;viewFramebuffer);
glGenRenderbuffersOES(1, amp;viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, amp;backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, amp;backingHeight);
if (USE_DEPTH_BUFFER) {
glGenRenderbuffersOES(1, amp;depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
}
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
return YES;
}
Я также написал метод setupView:
- (void)setupView {
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
// glEnable(GL_DEPTH_TEST); // Enables Depth Testing
// glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glViewport(0,0,backingWidth,backingHeight); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)backingWidth/(GLfloat)backingHeight,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
isSetUp = YES;
}
Это мой метод DrawView:
const GLfloat squareVertices[] = { -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f };
[EAGLContext setCurrentContext:context];
if (!isSetUp) {
[self setupView];
}
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
//glClear(GL_COLOR_BUFFER_BIT);
//////////////////////Variablen
float xg = -26;
float yg = 35.5;
float z = -100.0;
float abstandXg = 3.0;
float abstandYg = 3.0;
for (int i = 0; i < 26; i ) {
//arrayKoordinatenY[j] = y - abstandY * (j);
for (int j = 0; j<=17; j ) {
// glLoadIdentity();
//arrayKoordinatenX[i] = x abstandX * (i);
//glTranslatef(arrayKoordinatenX[j],arrayKoordinatenY[i],z);
glTranslatef(xg,yg,z);
glEnableClientState(GL_VERTEX_ARRAY);
glColor4f(0.0f,0.0f,0.0f,0.0f);
glVertexPointer(3, GL_FLOAT, 0, squareVertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
arrayKoordinatenX[j]=xg;
xg = xg abstandXg;
}
xg = -26.0;
arrayKoordinatenY[i]=yg;
yg = yg - abstandYg;
}
//// Here comes the Part where the squares are draw
.
.
.
/////
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
Комментарии:
1. Опубликуйте свой код рендеринга
2. Вы имеете в виду метод DrawView??
3. почему вы вызываете LBINDERBUFFEROES (GL_RENDERBUFFER_OES, viewRenderbuffer); [контекстный презентационный буфер: GL_RENDERBUFFER_OES]; дважды?
4. о, спасибо за совет, но у меня есть более новая версия этого кода, я разместил неправильный, я отредактирую вопрос, извините…
Ответ №1:
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity();
Хорошо, но где то же самое для GL_MODELVIEW?
Комментарии:
1. В методе setupView или вы имеете в виду что-то другое?
2. вы должны загружать идентификатор каждый раз, когда вы визуализируете кадр (для матриц модели и проекции).
3. То есть вы имеете в виду, что я должен написать это так??
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_MODELVIEW); glLoadIdentity();
4. нет. вы должны написать glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity();
5. хорошо, спасибо за ваш действительно быстрый ответ = D. Это работает в симуляторе. Мне придется подождать до завтра, чтобы протестировать его на устройстве. Большое вам спасибо.