Heh, well back to my problem.
Testing the rendering of the textures to the screen shows the rectangle primitives are being drawn correctly when I set the colour with half alpha so I can see the rectangles, no matter what.
The problem is clearly that the textures aren’t being rendered correctly to other textures with the frame buffer method.
I’ll show some more of my relevant code:
Edit: It seems when I want to render an image to the screen without being rendered to another texture first, it still fails.
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)
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
def draw_texture(texture,offset,size,c):
glMatrixMode(GL_MODELVIEW)
glLoadIdentity() #Loads model matrix
glColor4fv(c)
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()
class Surface():
def __init__(self,size,extra = None):
self.__offset = (0,0)
self.children = []
self.blitted = False
self.last_offset = [0,0]
self.surface_size = [size[0],size[1]]
self.colour = [0,0,0,255]
self.data = None
self.rounded = 0
self.parent = None
self.parent_offset = (0,0)
self.texture = None
def blit(self,surface,offset,area=None, special_flags = 0):
#Create textures if not done already
if self.texture == None:
create_texture(self)
if surface.texture == None:
create_texture(surface)
#Render child to parent
frame_buffer = glGenFramebuffersEXT(1)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_buffer)
render_buffer = glGenRenderbuffersEXT(1)
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,self.surface_size[0],self.surface_size[1])
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, render_buffer)
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, self.texture, 0)
glPushAttrib(GL_VIEWPORT_BIT)
glViewport(0,0,self.surface_size[0],self.surface_size[1])
draw_texture(surface.texture,offset,surface.surface_size,[float(c)/255.0 for c in surface.colour])
glPopAttrib()
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)
glDeleteFramebuffersEXT(1, [int(frame_buffer)])
glDeleteRenderbuffersEXT(1,[int(render_buffer)])
try:
offset_before_last = surface.last_offset
surface.last_offset = [offset[0] + self.__offset[0],offset[1] + self.__offset[1]]
self.children.append([0,surface]) #0 states it is a surface
surface.parent = self
surface.parent_offset = offset
if surface.get_offset() != surface.last_offset or not surface.blitted:
surface.__set_offset(surface.last_offset)
self.__recursive_offset_add(surface,offset_before_last,surface.last_offset) #Add to the children's offsets
surface.blitted = True
except AttributeError:
pass
def __recursive_offset_add(self,surface,offset_before_last,last_offset):
for child in surface.children:
try:
child.__set_offset((child.get_offset()[0] - offset_before_last[0] + last_offset[0],child.get_offset()[1] - offset_before_last[1] + last_offset[1]))
self.__recursive_offset_add(child,offset_before_last,last_offset)
except AttributeError:
pass
def get_offset(self):
return self.__offset
def __set_offset(self,offset):
self.__offset = offset
def fill(self,colour):
colour = list(colour)
if len(colour) < 4:
colour.append(255)
self.children = []
self.textures = []
self.colour = colour
def get_size(self):
return self.surface_size
def get_width(self):
return self.surface_size[0]
def get_height(self):
return self.surface_size[1]
class ScaledScreen(Surface):
game_size = None
first_screen = None
screen = None
fs = False #Fullscreen false to start
clock = None
resize = True
game_gap = None
game_scaled = None
title = None
fps = -1
enter_fullscreen = False
exit_fullscreen = False
scale_to_screen = False
iconify = False
on_focus_fullscreen = False
f_key = False
def __init__(self,title,game_size,on_exit):
pygame.init()
self.title = title
self.game_size = game_size
screen_info = pygame.display.Info() #Required to set a good resolution for the game screen
self.first_screen = (screen_info.current_w, screen_info.current_h - 120) #Take 120 pixels from the height because the menu bar, window bar and dock takes space
pygame.display.set_caption(self.title)
self.clock = pygame.time.Clock()
self.game_gap = (0,0)
self.on_exit = on_exit
self.mod_key = 1024 if sys.platform == "darwin" else 64
pygame.display.set_mode(self.first_screen,RESIZABLE|DOUBLEBUF|OPENGL)
#OpenGL Parts
Surface.__init__(self,game_size)
self.textures = []
self.screen_change = True
def update(self,events):
#Updates screen properly
win_size_done = False #Changes to True if the window size is got by the VIDEORESIZE event below
for event in events:
if event.type == QUIT:
self.on_exit()
if event.type == VIDEORESIZE:
ss = [event.w,event.h]
self.resize = True
win_size_done = True
keys = pygame.key.get_pressed() #Get the pressed keys
if pygame.key.get_mods() & self.mod_key:
if(keys[K_q] or keys[K_w]):
self.on_exit()
if keys[K_f]:
if self.f_key == False:
self.f_key = True
if self.fs == False:
self.enter_fullscreen = True
else:
self.exit_fullscreen = True
else:
self.f_key = False
if self.on_focus_fullscreen and pygame.display.get_active():
self.on_focus_fullscreen = False
self.enter_fullscreen = True
if self.enter_fullscreen:
self.screen_change = True
pygame.mouse.set_visible(False)
self.screen = pygame.display.set_mode((self.first_screen[0],self.first_screen[1]+ 120))
if self.scale_to_screen:
self.game_scaled = (self.screen.get_width(),self.screen.get_height())
else:
self.game_scaled = get_resolution(self.screen,(self.screen.get_width(),self.screen.get_height()),self.game_size)
self.game_gap = [(self.screen.get_width() - self.game_scaled[0])/2,(self.screen.get_height() - self.game_scaled[1])/2]
pygame.display.set_mode((0,0), FULLSCREEN|HWSURFACE|DOUBLEBUF|OPENGL)
self.fs = True
self.enter_fullscreen = False
self.resize = False
elif self.exit_fullscreen:
self.screen_change = True
pygame.mouse.set_visible(True)
pygame.display.set_mode(self.first_screen,RESIZABLE|DOUBLEBUF|OPENGL)
self.fs = False
self.resize = True
self.game_gap = (0,0)
self.exit_fullscreen = False
if self.iconify:
self.on_focus_fullscreen = True
#Scale game to screen resolution, keeping aspect ratio
if self.resize:
self.screen_change = True
if(win_size_done == False): #Sizes not gotten by resize event
ss = [self.screen.get_width(),self.screen.get_height()]
self.game_scaled = get_resolution(self.screen,ss,self.game_size)
pygame.display.set_mode(self.game_scaled,RESIZABLE|DOUBLEBUF|OPENGL)
self.resize = False #Next time do not scale unless resize or fullscreen events occur
if self.iconify:
pygame.display.iconify() #Minimise
self.iconify = False
#Open GL Screen setup
if self.screen_change:
glViewport(0,0,self.game_scaled[0],self.game_scaled[1]) #Creates the viewport which is mapped to the window
glEnable(GL_LINE_SMOOTH,GL_FASTEST) #Create antialiased lines
glEnable(GL_BLEND) #Enable alpha blending
glEnable(GL_TEXTURE_2D) #Enable 2D Textures
glDisable(GL_DEPTH_TEST) #Disable depth
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) #The recomended blending functions.
glMatrixMode(GL_PROJECTION)
glLoadIdentity() #Load the projection matrix
gluOrtho2D(0,1280,720,0) #Set an orthorgraphic view
self.screen_change = False
pygame.display.flip() #Flip buffer
self.textures = []
self.children = []
self.clock.tick(60)
self.fps = self.clock.get_fps()
pygame.display.set_caption(self.title + " - " + str(int(self.fps)) + "fps")
glClear(GL_COLOR_BUFFER_BIT)
def blit(self,surface,offset,area=None, special_flags = 0):
if surface.texture == None:
create_texture(surface)
print surface.colour
draw_texture(surface.texture,offset,surface.surface_size,[float(c)/255.0 for c in surface.colour])
I removed quite a bit of irrelevant code.