带有纹理的PyOpenGL球体 [英] PyOpenGL sphere with texture

查看:472
本文介绍了带有纹理的PyOpenGL球体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Python PyOpenGL生成三个球体的场景.侧面有两个颜色(红色和绿色).中间带有任何纹理(砖纹理实际上是与代码位于同一目录中的正方形jpg文件的砖纹理).

I want to use Python PyOpenGL for generating a scene of three spheres. Two on the side with color (red and green). Middle one with any texture on it (bricks texture which is actually square jpg file in the same directory as code is).

到目前为止,我已经完成了以下工作:

There is what I have done so far:

出于某些原因,gluSphere()生成的中间球体的纹理具有奇怪的行为.有一些小的绿色三角形而不是我的纹理文件.

From some reason texture in the middle sphere generated by gluSphere() has strange behaviour. There are some small green triangles instead of my texture file.

这是我的纹理文件:

我尝试将此文件映射为表面,例如在中间球体上的纹理.我不知道问题出在哪里.

I have tried to map this file as surface, e.g. texture on the middle sphere. I don't know where the problem is.

有我的代码,我不知道要在中间球体上获得正确的纹理贴图的丢失或错误之处:

There is my code, I have no idea what I miss or what is wrong to get proper texture mapping on middle sphere:

from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
import sys
from PIL import Image as Image
import numpy

name = 'Navigation paradigm'

def main():
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
    glutInitWindowSize(800, 800)
    glutInitWindowPosition(350, 200)
    glutCreateWindow(name)
    glClearColor(0., 0., 0., 1.)
    glShadeModel(GL_SMOOTH)
    glEnable(GL_CULL_FACE)
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_LIGHTING)
    lightZeroPosition = [10., 4., 10., 1.]
    lightZeroColor = [0.8, 1.0, 0.8, 1.0]
    glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition)
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor)
    glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1)
    glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05)
    glEnable(GL_LIGHT0)
    glutDisplayFunc(display_scene)
    glMatrixMode(GL_PROJECTION)
    gluPerspective(40., 1., 1., 40.)
    glMatrixMode(GL_MODELVIEW)
    gluLookAt(0, 0, 10,
              0, 0, 0,
              0, 1, 0)
    glPushMatrix()
    glutMainLoop()
    return

def display_scene():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glPushMatrix()
    # Textured thing 
    tex = read_texture('brick.jpg')
    qobj = gluNewQuadric()
    gluQuadricTexture(qobj, GL_TRUE)
    glEnable(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, tex)
    glBegin(GL_TRIANGLES)
    gluSphere(qobj, 1, 50, 50)
    gluDeleteQuadric(qobj)
    glDisable(GL_TEXTURE_2D)
    # Left sphere
    color = [1.0, 0.0, 0.0, 1.0]
    glMaterialfv(GL_FRONT, GL_DIFFUSE, color)
    glTranslatef(-2, 0, 0)
    glutSolidSphere(1, 100, 20)
    # Right sphere
    color = [0.0, 1.0, 0.0, 1.0]
    glMaterialfv(GL_FRONT, GL_DIFFUSE, color)
    glTranslatef(4, 0, 0)
    glutSolidSphere(1, 100, 20)
    glPopMatrix()
    glutSwapBuffers()
    return

def read_texture(filename):
    img = Image.open(filename)
    img_data = numpy.array(list(img.getdata()), numpy.int8)
    textID = glGenTextures(1)
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    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, GL_RGB, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
    return textID

if __name__ == '__main__':
    main()

推荐答案

我知道这与您的新问题有关. 但是,这里存在一个稍微不同的问题".因此,以防万一其他人遇到相同的问题,我将回答它.

I know that this is in relation to your new question. But there is a slightly different "problem" at hand. So just in case someone else has the same problem, I'm going to answer it.

首先,如注释中所述,您不需要调用glBegin().因为gluSphere()已经对此进行了管理.另外,如果您要呼叫glBegin(),则还需要呼叫glEnd().因此,您看到某事的原因基本上是因为您混淆了驱动程序,然后执行了原本不应该做的事情.

First of all, as mentioned in the comments you don't need to call glBegin(). Because gluSphere() already manages that. Additionally if you were to call glBegin() you'd also need to call glEnd(). So the reason you're seeing something, is basically because you're confusing your driver, and it then does something it isn't supposed to do.

read_texture()中,生成纹理名称后,您无需绑定它.因此,后续与纹理相关的调用将转到默认纹理,而不是您新创建的纹理.

In read_texture() after you generate a texture name you don't bind it. So the subsequent texture related calls are going to the default texture and not your newly created texture.

textID  = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, textID) # This is what's missing

添加丢失的glBindTexture()呼叫后,您将获得如下所示的结果.

After adding the missing glBindTexture() call, you'll get a result looking like this.

现在,它看起来可能有点怪异,并且看起来好像出了点问题.但事实是,所有事情都按其应有的方式运行.问题在于纹理本身.

Now it might look a bit weird, and it might look like something is wrong. But the fact of the matter is that everything is working as it should. The problem lies with the texture itself.

问题"是您的砖纹理不是球形贴图纹理.如果我们现在只用球形映射纹理替换您的砖块纹理,那么请执行以下操作.

The "problem" is that your brick texture isn't a spherical mapped texture. If we now just only replace your brick texture with a spherical mapped texture, then well get the following.

这是上面使用的球形贴图纹理:

Here's the spherical mapped texture used above:

这篇关于带有纹理的PyOpenGL球体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆