I have two textures in .png format (floor and wall), I load them during the initialization, and choose before rendering by glBindTexture
, but I get this:
screen_shot_1
instead of this:
screen_shot_2
Initialization:
def __init__(self, screen_info, wall_number):
self.screen = screen_info
self.inscription = font.Font(get_path([RES_PATH[0], 'font', 'main.ttf']), 12)
self.path = get_path([RES_PATH[0], RES_PATH[1], ''])
self.sprite_list = {}
self.tex_list = {}
self.generate_list()
self.wall_coordinates = []
self.wall_number = wall_number
self.wall_counter = 0
glClearColor(*BACKGROUND_COLOR)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(FOV, self.screen.current_w / self.screen.current_h, DISTANCE_NEAR, DISTANCE_FAR)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glEnable(GL_DEPTH_TEST)
glEnable(GL_TEXTURE_2D)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
Main loop:
gi = interaction.GI(screen_info, 11)
while True:
timer.tick(60)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
camera.update_view()
camera.update_move(forward, backward, left, right, gi.get_wall_coordinates())
gi.draw_ground(0, 0)
gi.draw_square(-2, 1.5, -4)
gi.draw_square(0, 1.5, -4)
gi.draw_square(2, 1.5, -4)
gi.draw_square(4, 1.5, -4, rot=True)
gi.draw_square(4, 1.5, -2, rot=True)
gi.draw_square(4, 1.5, 0, rot=True)
gi.draw_square(2, 1.5, 2)
gi.draw_square(0, 1.5, 2)
gi.draw_square(-2, 1.5, 2)
gi.draw_square(-2, 1.5, 0, rot=True)
gi.draw_square(-2, 1.5, -4, rot=True)
pygame.display.flip()
Texture loader:
def load_tex(self, filename, rotate=False, text_render=False, text=''):
if not text_render:
surface = image.load(filename)
if rotate:
surface = transform.rotate(surface, 180)
else:
surface = self.inscription.render(str(text), 1, (255, 255, 255), (0, 0, 0))
surface = transform.scale(surface, (64, 64))
surface = transform.rotate(surface, 180)
size = surface.get_size()
surface = image.tostring(surface, 'RGB', True)
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
glTexImage2D(GL_TEXTURE_2D, 0, 3, size[0], size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, surface)
return texture
Loading texture during the initialization:
def generate_list(self):
for filename in listdir(self.path):
self.tex_list[filename] = self.load_tex(get_path([RES_PATH[0], RES_PATH[1], filename]))
Drawing ground:
def draw_ground(self, x, z, length=50):
glBindTexture(GL_TEXTURE_2D, self.tex_list['floor.png'])
# glBindTexture(GL_TEXTURE_2D, self.load_tex(get_path([RES_PATH[0], RES_PATH[1], 'floor.png'])))
glBegin(GL_QUADS)
glTexCoord2f(0, length)
glVertex3f(x - length, -0.5, z + length)
glTexCoord2f(length, length)
glVertex3f(x + length, -0.5, z + length)
glTexCoord2f(length, 0)
glVertex3f(x + length, -0.5, z - length)
glTexCoord2f(0, 0)
glVertex3f(x - length, -0.5, z - length)
glEnd()
Drawing walls:
def draw_square(self, x, y, z, length=2, rot=False):
glBindTexture(GL_TEXTURE_2D, self.tex_list['wall.png'])
# glBindTexture(GL_TEXTURE_2D, self.load_tex(get_path([RES_PATH[0], RES_PATH[1], 'wall.png'])))
glBegin(GL_QUADS)
glTexCoord2f(0, 1)
glVertex3f(x, y, z)
glTexCoord2f(1, 1)
if not rot:
glVertex3f(x + length, y, z)
glTexCoord2f(1, 0)
glVertex3f(x + length, y - length, z)
else:
glVertex3f(x, y, z + length)
glTexCoord2f(1, 0)
glVertex3f(x, y - length, z + length)
glTexCoord2f(0, 0)
glVertex3f(x, y - length, z)
glEnd()
So what is the problem?
These are some things I noticed in your code that may or may not be related to your texturing issues:
Here is a simple demo I made that uses pyopengl and pygame. It renders two 2d squares, each with a different texture. The main while loop and the load_texture function are the important parts:
import pygame
from pygame.locals import *
from OpenGL.GL import *
import sys
def init_gl():
window_size = width, height = (550, 400)
pygame.init()
pygame.display.set_mode(window_size, OPENGL | DOUBLEBUF)
glEnable(GL_TEXTURE_2D)
glMatrixMode(GL_PROJECTION)
glOrtho(0, width, height, 0, -1, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def load_texture(texture_url):
tex_id = glGenTextures(1)
tex = pygame.image.load(texture_url)
tex_surface = pygame.image.tostring(tex, 'RGBA')
tex_width, tex_height = tex.get_size()
glBindTexture(GL_TEXTURE_2D, tex_id)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_surface)
glBindTexture(GL_TEXTURE_2D, 0)
return tex_id
if __name__ == "__main__":
init_gl()
texture1 = load_texture("texture1.png")
texture2 = load_texture("texture2.png")
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
glClear(GL_COLOR_BUFFER_BIT)
glBindTexture(GL_TEXTURE_2D, texture1)
glBegin(GL_QUADS)
glTexCoord(0, 0)
glVertex(50, 50, 0)
glTexCoord(0, 1)
glVertex(50, 100, 0)
glTexCoord(1, 1)
glVertex(100, 100, 0)
glTexCoord(1, 0)
glVertex(100, 50, 0)
glEnd()
glBindTexture(GL_TEXTURE_2D, 0)
glBindTexture(GL_TEXTURE_2D, texture2)
glBegin(GL_QUADS)
glTexCoord(0, 0)
glVertex(450, 300, 0)
glTexCoord(0, 1)
glVertex(450, 350, 0)
glTexCoord(1, 1)
glVertex(500, 350, 0)
glTexCoord(1, 0)
glVertex(500, 300, 0)
glEnd()
glBindTexture(GL_TEXTURE_2D, 0)
pygame.display.flip()
As a side note, most of both your code and the demo code I have posted is deprecated in modern OpenGL, which does not support slow immediate mode calls like glBegin and glEnd. If you run into performance issues later on, that might be something to consider refactoring to use more modern techniques, like VBOs (Vertex Buffer Objects). But for simple applications, this should not be too much of an issue. Let me know if this helps!