Линии не отображаются в закадровом буфере кадра с полностью черной текстурой.

Если у меня есть буфер кадра, к которому привязана текстура, которая просто черная с полной альфой, и я пытаюсь нарисовать к нему линию, даже если линия имеет полную альфу, она не будет отображаться. Я не дурак, поэтому линии точно не черные. Если вместо этого текстура белая, линия внезапно отображается правильно, как будто цвет текстуры за ней влияет на цвет линий, что глупо. Только если линии имеют прозрачность, цвет позади них должен иметь эффект.

Я использую сглаживание линий. Я использую следующую функцию смешивания, которая, по-видимому, должна использоваться:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

Как я могу это исправить?

Много кода:

Для рисования линий:

def draw_line(a,b,c,w,antialias):
    if antialias:
        glEnable(GL_LINE_SMOOTH) #Enable line smoothing.
    c = [float(sc)/255.0 for sc in c] #Divide colours by 255 because OpenGL uses 0-1
    if len(c) != 4:
        c.append(1) #Add a value for aplha transparency if needed
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity() #Loads model matrix
    glColor4fv(c)
    glLineWidth(w)
    glBegin(GL_LINES)
    glVertex2fv(a)
    glVertex2fv(b)
    glEnd()
    if antialias:
        glDisable(GL_LINE_SMOOTH) #Disable line smoothing.

Настройка объекта фреймбуфера:

def setup_framebuffer(surface):
    #Create texture if not done already
    if surface.texture == None:
        create_texture(surface)
    #Render child to parent
    if surface.frame_buffer == None:
        surface.frame_buffer =  glGenFramebuffersEXT(1)
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, surface.frame_buffer)
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, surface.texture, 0)
    glPushAttrib(GL_VIEWPORT_BIT)
    glViewport(0,0,surface.surface_size[0],surface.surface_size[1])
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity() #Load the projection matrix
    gluOrtho2D(0,surface.surface_size[0],0,surface.surface_size[1])

def end_framebuffer():
    glPopAttrib()
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity() #Load the projection matrix
    gluOrtho2D(0,1280,720,0) #Set an orthorgraphic view

Создание текстуры:

def create_texture(surface):
    surface.texture = glGenTextures(1)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity() #Loads model matrix
    glBindTexture(GL_TEXTURE_2D, surface.texture) #Binds the current 2D texture to the texture to be drawn
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) #Required to be set for maping the pixel data
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) #Similar as above
    if surface.data == None:
        surf = pygame.Surface((1,1),SRCALPHA)
        surf.fill(surface.colour[:-1])
        surface.data = pygame.image.tostring(surf, "RGBA") * (surface.surface_size[0] * surface.surface_size[1])
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface.surface_size[0], surface.surface_size[1], 0, GL_RGBA,GL_UNSIGNED_BYTE, surface.data) #Put surface pixel data into texture

Функция для рисования множества линий на экране или текстуре объекта Surface с объектом кадрового буфера:

def add_lines(surface, c, coordinates, w = 1, antialias = True):
    if surface.__class__ == Surface: #Only use a frame buffer if the line isn't being drawn to the screen.
        setup_framebuffer(surface)
    last = None
    for coordinate in coordinates: #Loop though the coordinates and draw the lines
        if last != None:
            draw_line(last,coordinate,c,w,antialias)
        last = coordinate
    if surface.__class__ == Surface: #Only use a frame buffer if the line isn't being drawn to the screen.
        end_framebuffer()

Это все, что я вижу важным. За исключением, возможно, кода инициализации:

glutInit(sys.argv)
glutInitWindowPosition(0,0)
glutInitWindowSize(*game_size)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA)
glutCreateWindow(title)
glutSetIconTitle(title)
glutReshapeFunc(self.reshaped)
glutKeyboardFunc(self.keydown)
glutKeyboardUpFunc(self.keyup)
glutSpecialFunc(self.specialdown)
glutSpecialUpFunc(self.specialup)
glViewport(0,0,self.first_screen[0],self.first_screen[1]) #Creates the viewport which is mapped to the window
glEnable(GL_BLEND) #Enable alpha blending
glEnable(GL_TEXTURE_2D) #Enable 2D Textures
glEnable(GL_POLYGON_SMOOTH) #Enable antialiased polygons
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST)
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glMatrixMode(GL_PROJECTION)
glLoadIdentity() #Load the projection matrix
gluOrtho2D(0,1280,720,0) #Set an orthorgraphic view

person Matthew Mitchell    schedule 09.01.2010    source источник
comment
как насчет того, чтобы показать код для рисования линии и/или некоторых изображений того, что вы наблюдаете? Кроме того, у вас странная номенклатура. текстурированный, привязанный к буферу кадра? Вы имеете в виду, что уже нарисовали текстуру в буфере кадра?   -  person Bahbar    schedule 09.01.2010
comment
Вам нужно разместить больше кода для рендеринга фона и линий?   -  person Jim Buck    schedule 09.01.2010
comment
Я добавил много кода. Под связанной текстурой я подразумеваю использование этого: glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, surface.texture, 0)   -  person Matthew Mitchell    schedule 10.01.2010
comment
Ваш код работает должным образом без включенного GL_BLEND или без включенного GL_LINE_SMOOTH?   -  person tkerwin    schedule 11.01.2010
comment
Отключение смешивания для всего или только для линий, по-видимому, приводит к тому, что линии, которые отображаются непосредственно на экране, работают, но не линии, визуализируемые в текстурах. Отключение сглаживания линий ничего не меняет.   -  person Matthew Mitchell    schedule 11.01.2010


Ответы (1)


Есть по крайней мере одна вещь, которая выглядит подозрительно: вы включаете текстурирование в своем коде инициализации и забываете об этом.

Таким образом, ваши линии рисуются с включенным текстурированием (и постоянными координатами текстуры), предположительно выбирая текстуру, которую вы пытаетесь записать.

Скорее всего, это не то, что вам нужно (я не помню, что об этом говорится в спецификации fbo, но это не сработает). Как насчет того, чтобы отключить текстурирование при рендеринге линий?

person Bahbar    schedule 12.01.2010
comment
Большое тебе спасибо. Я запомню это в будущем. - person Matthew Mitchell; 12.01.2010