Объект кадрового буфера OpenGL для рендеринга в текстуры, рендерится странно

Я использую python, но OpenGL в значительной степени делается точно так же, как и на любом другом языке.

Проблема в том, что когда я пытаюсь визуализировать текстуру или линию в текстуру с помощью объекта кадрового буфера, она отображается вверх ногами, слишком мала в левом нижнем углу. Очень странно. У меня есть эти фотографии для демонстрации:

Вот как это выглядит,

www.godofgod.co.uk/my_files/Incorrect_operation.png

Вот как это выглядело, когда вместо этого я использовал pygame. Я узнал, что Pygame слишком медленный. Моя игра была бы неиграбельна без скорости OpenGL. Не обращайте внимания на изогнутые углы. Я еще не реализовал их в OpenGL. Мне нужно сначала решить эту проблему.

www.godofgod.co.uk/my_files/Correct_operation.png

Я не использую глубину.

Что может быть причиной такого странного поведения. Вот код (функции имеют отступ в фактическом коде. Он отображается правильно), вы можете найти его полезным,

def texture_to_texture(target,surface,offset): #Target is an object of a class which contains texture data. This texture should be the target. Surface is the same but is the texture which should be drawn onto the target. offset is the offset where the surface texture will be drawn on the target texture.
#This will create the textures if not already. It will create textures from image data or block colour. Seems to work fine as direct rendering of textures to the screen works brilliantly.
if target.texture == None:
    create_texture(target)
if surface.texture == None:
    create_texture(surface)
frame_buffer =  glGenFramebuffersEXT(1)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_buffer)
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, target.texture, 0) #target.texture is the texture id from the object
glPushAttrib(GL_VIEWPORT_BIT)
glViewport(0,0,target.surface_size[0],target.surface_size[1])
draw_texture(surface.texture,offset,surface.surface_size,[float(c)/255.0 for c in surface.colour]) #The last part changes the 0-255 colours to 0-1 The textures when drawn appear to have the correct colour. Don't worry about that.
glPopAttrib()
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)
glDeleteFramebuffersEXT(1, [int(frame_buffer)]) #Requires the sequence of the integer conversion of the ctype variable, meaning [int(frame_buffer)] is the odd required way to pass the frame buffer id to the function.

Эта функция также может быть полезна,

def draw_texture(texture,offset,size,c):
glMatrixMode(GL_MODELVIEW)
glLoadIdentity() #Loads model matrix
glColor4fv(c)
glBegin(GL_QUADS)
glVertex2i(*offset) #Top Left
glVertex2i(offset[0],offset[1] + size[1]) #Bottom Left
glVertex2i(offset[0] + size[0],offset[1] + size[1]) #Bottom, Right
glVertex2i(offset[0] + size[0],offset[1]) #Top, Right
glEnd()
glColor4fv((1,1,1,1))
glBindTexture(GL_TEXTURE_2D, texture)
glBegin(GL_QUADS)
glTexCoord2f(0.0, 0.0)
glVertex2i(*offset) #Top Left
glTexCoord2f(0.0, 1.0)
glVertex2i(offset[0],offset[1] + size[1]) #Bottom Left
glTexCoord2f(1.0, 1.0)
glVertex2i(offset[0] + size[0],offset[1] + size[1]) #Bottom, Right
glTexCoord2f(1.0, 0.0)
glVertex2i(offset[0] + size[0],offset[1]) #Top, Right
glEnd()

person Matthew Mitchell    schedule 04.01.2010    source источник


Ответы (1)


Вы не показываете свою проекционную матрицу, так что я тоже предполагаю, что это личность.

  • Источник кадрового буфера OpenGL находится внизу слева, а не вверху слева.
  • Вопрос размера объяснить сложнее. В конце концов, какая у вас проекционная матрица?
  • Кроме того, вы не показываете, как использовать текстуру, и я не уверен, что мы видим на вашем «неправильном» изображении.

Некоторые несвязанные комментарии:

  • создание фреймбуфера для каждого кадра - неправильный способ сделать это.
  • если подумать, зачем вообще использовать фреймбуфер? кажется, что единственное, что вам нужно, это смешивание с буфером кадра? glEnable(GL_BLEND) делает это просто отлично.
person Bahbar    schedule 05.01.2010
comment
Спасибо за ответ. Я изменю аргументы glTexCoord2f, чтобы перевернуть текстуры. Я отвечу на ваши вопросы по порядку. Для проекционной матрицы я использовал gluOrtho2D(0,1280,720,0). Мне нужен только простой 2D вид. В конечном итоге текстуры отображаются на экране с помощью функции draw_texture(), которую я показал. Я использую ту же функцию для рисования текстур, когда настроил буфер кадра. Для задачи сравните нижний градиент и меню посередине. Изображения рисуются правильно, потому что они рисуются прямо на экране. GL_BLEND - это не то, что мне нужно, я не думаю. - person Matthew Mitchell; 06.01.2010
comment
GL_BLEND только для альфа-смешивания, верно? Мне нужно поместить текстуры внутри текстур. Вы могли бы порекомендовать мне отрисовывать все за кадр, но я обнаружил, что это ужасно неэффективно и связано с проблемами утечки памяти. Я буду сохранять объекты буфера кадра после их создания и уничтожать их только тогда, когда удаляю объекты Surface. Это должно было стать следующим шагом. - person Matthew Mitchell; 06.01.2010
comment
КАКИЕ? Ничто не говорило мне, что я должен сбросить матрицу проекта!!! Я снова использовал gluOrtho2D, и проблема устранена! Сумасшедший. Вся эта боль и решение были такими простыми. Ваше упоминание о проекционной матрице заставило меня внезапно задуматься об этом. Спасибо большое. Это не полностью сделано, но почти готово. - person Matthew Mitchell; 06.01.2010
comment
Матрица проекции остается такой, какой она была установлена ​​в последний раз (как и каждый бит состояния OpenGL). Если приходится сбрасывать, значит что-то где-то менялось. - person Bahbar; 06.01.2010