OpenGL - Show Texture Only
<p>I'm working on a 2D isometric game, using pygame and pyopengl.</p>

<p>I'm drawing sprites as quads, with a texture. I managed to get the alpha transparency to work for the texture, but the quad itself is still filled in a solid color (whatever colour gl pipeline is set with at the time). </p>

<p>How do I hide the quad shape, and just show the texture?</p>

<p>Here is a pic showing the problem (gl pipeline set to pink/purple color):</p>

<p><a href="https://i.stack.imgur.com/mCaU4.png" rel="nofollow"><img src="https://i.stack.imgur.com/mCaU4.png" alt="enter image description here"></a></p>

<p>The code is a bit messy, and I've been blindly copy 'n pasting gl calls hoping it solves the problem so there are bound to be quite a few calls in the wrong place or duplicated (or both).</p>

<p>GL Setup code (called once at start of script)</p>

<pre><code>glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glViewport(0, 0, screen_size[0], screen_size[1])
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0.0, screen_size[0], 0.0, screen_size[1], 0.0, 1.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glDisable(GL_LIGHTING)
glEnable(GL_TEXTURE_2D)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
</code></pre>

<p>Drawing setup code (called once at the start of each frame)</p>

<pre><code>glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glViewport(0, 0, screen_size[0], screen_size[1])
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0.0, screen_size[0], 0.0, screen_size[1], 0.0, 1.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glDisable(GL_LIGHTING)
glEnable(GL_TEXTURE_2D)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
</code></pre>

<p>Quad draw code (called for every sprite draw call):</p>

<pre><code>glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_TEXTURE_2D)
glEnable(GL_ALPHA_TEST)
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)

# Start new transformation matrix
glPushMatrix()

# Apply translation
glTranslatef(self.rect.centerx, self.rect.centery, 0.0)

# Start gl drawing cursor
glColor4f(1.0, 0.0, 1.0, 1.0)

# Bind the texture to this draw session
glBindTexture(GL_TEXTURE_2D, self.texture.id)

# Start drawing a quad
glBegin(GL_QUADS)

# Grab new copy of rect, and move to the origin
r = self.rect.copy()
r.center = (0, 0)

# Draw top left point
glTexCoord2f(1.0, 0.0)
glVertex2f(*r.topleft)

# Draw top right point
glTexCoord2f(0.0, 0.0)
glVertex2f(*r.topright)

# Draw bottom right point
glTexCoord2f(0.0, 1.0)
glVertex2f(*r.bottomright)

# Draw bottom left point
glTexCoord2f(1.0, 1.0)
glVertex2f(*r.bottomleft)

# End quad
glEnd()

# Apply transformation matrix
glPopMatrix()
</code></pre>

<p>The colored background behind your tiles is probably due to this line when you set up your texture:</p>

<pre><code>glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
</code></pre>

<p>Just remove this as the default texture environment settings are probably fine for standard tile rendering. As an example of what messing with these parameters can do, if you wanted <code>glColor</code> calls to "tint" your texture instead, then replace <code>GL_DECAL</code> with <code>GL_BLEND</code>.</p>

<p>There is no need for any of those lighting calls included in your code as far as I can tell unless you are working with 3d models and ancient per-vertex lighting (I assume you are not since this is a 2d isometric game). Also you only need blending for this, no need for alpha testing. Assuming you are working with images with alpha (RGBA format), here is a simple demo that displays two tiles with a transparent background (supply your own image of course instead of <code>./images/grass.png</code>):</p>

<pre><code>import pygame
from pygame.locals import *
from OpenGL.GL import *
import sys

class Sprite(object):
    def __init__(self):
        self.x = 0
        self.y = 0
        self.width = 0
        self.height = 0 
        self.texture = glGenTextures(1)

    def load_texture(self, texture_url):
        tex = pygame.image.load(texture_url)
        tex_surface = pygame.image.tostring(tex, 'RGBA')
        tex_width, tex_height = tex.get_size()
        glBindTexture(GL_TEXTURE_2D, self.texture)
        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)
        self.width = tex_width
        self.height = tex_height

    def set_position(self, x, y):
        self.x = x
        self.y = y

    def render(self):
        #glColor(1, 1, 1, 1)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glBindTexture(GL_TEXTURE_2D, self.texture)
        glBegin(GL_QUADS)
        glTexCoord(0, 0)
        glVertex(self.x, self.y, 0)
        glTexCoord(0, 1)
        glVertex(self.x, self.y + self.height, 0)
        glTexCoord(1, 1)
        glVertex(self.x + self.width, self.y + self.height, 0)
        glTexCoord(1, 0)
        glVertex(self.x + self.width, self.y, 0)
        glEnd()
        glBindTexture(GL_TEXTURE_2D, 0)

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()

if __name__ == "__main__":
    init_gl()
    tile1 = Sprite()
    tile1.load_texture("./images/grass.png")
    tile1.set_position(50, 100)
    tile2 = Sprite()
    tile2.load_texture("./images/grass.png")
    tile2.set_position(80, 130)
    tiles = [tile1, tile2]

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

        glClear(GL_COLOR_BUFFER_BIT)
        glColor(1, 0, 0, 1)
        for tile in tiles:
            tile.render()
        pygame.display.flip()
</code></pre>

<p>Let me know if this helps!</p>

python opengl