ID:183360
 
Code:
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
from Image import *

class pygameGL():
screensize = (500, 500)
ntangle = nsangle = 0
xrot = yrot = zrot = 0.0
textures = []

def __init__(self):
pygame.init()
screen = pygame.display.set_mode(self.screensize, HWSURFACE | OPENGL | DOUBLEBUF)
pygame.key.set_repeat(10, 5)
self.resize(*self.screensize)

self.loadtexture("NeHe.bmp")
glEnable(GL_TEXTURE_2D)
glShadeModel(GL_SMOOTH)
glClearColor(0.0, 0.0, 0.0, 0.5)
glClearDepth(1.0)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)

def loadtexture(self, name):
if(name):
image = open(name, "r")
if(image):
ix = image.size[0]
iy = image.size[1]
image = image.tostring("raw", "RGBX", 0, -1)

glGenTextures(1, image)
glBindTexture(GL_TEXTURE_2D, image)
glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGB, GL_UNSIGNED_BYTE, image)

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

textures += image

def resize(self, width, height):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, width / height, .1, 1000.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()

def drawgl(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()

glRotatef(xrot, 1.0, 0.0, 0.0)
glRotatef(yrot, 0.0, 1.0, 0.0)
glRotatef(zrot, 0.0, 0.0, 1.0)

glBindTexture(GL_TEXTURE_2D, textures[0]);

glBegin(GL_QUADS)
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0)
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0)
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0)
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0)

glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0)
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0)
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0)
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0)

glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0)
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 1.0)
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 1.0)
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0)

glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0)
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0)
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0)
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0)

glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0)
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0)
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, 1.0)
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0)

glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0)
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0)
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0)
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0)
glEnd()

glLoadIdentity()

xrot += 0.3
yrot += 0.2
zrot += 0.4

def main(self):
clock = pygame.time.Clock()

while True:
clock.tick(60)

for event in pygame.event.get():
if event.type == QUIT:
return

self.ntangle += 1
self.nsangle += 1

self.drawgl()
pygame.display.flip()

GL = pygameGL()
GL.main()

Problem description:

My problem is loading the texture and then displaying it. =/ I attempted to in the loadtexture() proc, but I get an error from OpenGL telling me that I am feeding it the wrong type of data for generating and binding the texture.

Help? <_<
Dumping a BMP straight down the tube to the video card won't work; a BMP isn't quite raw pixel data, it has a header and so forth. Plus the bytes may not be in the right order.

I haven't used pygame+OGL for ages, but in SDL (which is pygame's workhorse) you generally use an image-loading function to get an SDL surface. Then you use glTexImage2D to send the surface data to OpenGL.

It looks like the only thing you're seriously doing wrong is loading the BMP file as a string and then chucking the string at OpenGL; instead, you need a proper image-loading function. Check the pygame docs. (Edit: Too easy. That's the function you want to use. Then call glTexImage2D with the pixel data of the returned Surface object.)

Here's some abbreviated code from Mayhem Intergalactic that does this (written in D using SDL, but the Python code for pygame should be roughly analogous):

SDL_Surface* surface = IMG_Load(filename);

// I do some extra processing in here to make sure that
// the texture has power-of-two dimensions and that the
// SDL surface has the format I expect (RGBA)

// Assign the texture an OpenGL texture number (texnum) so we can refer to it later
int texnum;

glGenTextures(1, &texnum);

glBindTexture(GL_TEXTURE_2D, texnum);

// This call assumes that your SDL surface is in RGBA format
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface.w, surface.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, squaresurface.pixels);

// Alternatively, if your SDL surface is in RGB format
// (no alpha channel), use:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, surface.w, surface.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, squaresurface.pixels);

// When your app quits, delete the OpenGL texture. pygame may or may not handle this for you, check its documentation.
glDeleteTextures(1, &texnum);