Search code examples
3dtexturespyopengl

Rendering textures in pyopengl


I am trying to get the basics of how texture rendering work and doing it with pyopengl as I've worked for a time with it.

I have read some documentation, from the red book to tutorials, but my program does not render any texture - it just changes (darkens) the colors on the surfaces of the objects drawn.

Here is the relevant code: the function which reads the image file, sets the texture properties and enables it,

def generateTexture(texPath):
    im = Image.open(texPath)
    texData = im.tostring('raw', 'RGBX', 0, -1)
    texName = [0]
    glGenTextures(1, texName)
    glBindTexture(GL_TEXTURE_2D, texName[0])
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData)
    glEnable(GL_TEXTURE_2D)
    return texName

and the function which creates the object's vertex visualization list,

def showVertices(obj):
    Vertices_List = glGenLists(1)
    glNewList(Vertices_List,GL_COMPILE)
    texNames = generateTexture('tex_stone.jpg')
    glBindTexture(GL_TEXTURE_2D, texNames[0])
    glColor3f(1.0,1.0,1.0)
    glBegin(GL_POINTS)
    i=0
    while i < obj.nv:
        glNormal3f(obj.vnormals[i].x, obj.vnormals[i].y, obj.vnormals[i].z)
        glTexCoord2f(obj.texcoords[i].x, obj.texcoords[i].y)
        glVertex3f(obj.vertices[i].x,obj.vertices[i].y,obj.vertices[i].z)
        i = i + 1
    glEnd()
    glEndList()
    return Vertices_List

I don't think this is the problem, but I am calculating the texture coordinates for each object manually (calculating the intersection of a 'sorrounding sphere' with a vector from the object's center through each vertex).

If you want to see any other part of the code, please ask. Any hint or advice will be much appreciated.

EDIT: Maybe the problem is that I use glTexCoord2f() in combination with glBegin(GL_POINTS) and, in order for it to apply the texture to a surface, should be used with GL_QUADS, GL_TRIANGLES or any other surface? The thing is that my objects' sides are not composed of a determined polygon type: mainly it is triangles, but there are quadrilaters too.


Solution

  • Well, that was it. I moved the calls to glTexCoord2f() to the function that calculates the sides of the objects:

    def showSides(obj):
    Sides_List = glGenLists(1)
    glNewList(Sides_List,GL_COMPILE)
    texNames = generateTexture('tex_pattern.jpg')
    glColor3f(1.0,1.0,0.0)
    i = 0
    while i < obj.ns:
        j = 0
        glBegin(GL_POLYGON)        
        while j < len(obj.sides[i]):
            glNormal3f(obj.vnormals[obj.sides[i][j]].x, obj.vnormals[obj.sides[i][j]].y, obj.vnormals[obj.sides[i][j]].z)
            glTexCoord2f(obj.texcoords[obj.sides[i][j]].x, obj.texcoords[obj.sides[i][j]].y)
            glVertex3f(obj.vertices[obj.sides[i][j]].x, obj.vertices[obj.sides[i][j]].y, obj.vertices[obj.sides[i][j]].z)
            j = j + 1
        glEnd()
        i = i + 1
    glEndList()
    return Sides_List
    

    Also, I displaced glEnable(GL_TEXTURE_2D) to the main visualization function just before it calls showSides().