pyopengl之cube texture

    将一张图片贴到 立方体的6个面上。

    这里最主要理解纹理坐标。以下面一张图为例,其纹理的坐标系统如下图的四个顶点所标识。

pyopengl之cube texture_第1张图片

纹理的坐标是从0-1,和图像大小无关。

一个正方形的顶点坐标为图中红色部分:此红色部分构造了一个正方形,而正方形的颜色填充,即从图像中采样的对应关系则一目了然。

pyopengl之cube texture_第2张图片   

# coding: utf-8
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
from ctypes import sizeof, c_float, c_void_p, c_uint, string_at

from shader import *
import numpy, math


vertices=[
    -0.5, -0.5, -0.5,  0.0, 0.0,
     0.5, -0.5, -0.5,  1.0, 0.0,
     0.5,  0.5, -0.5,  1.0, 1.0,
     0.5,  0.5, -0.5,  1.0, 1.0,
    -0.5,  0.5, -0.5,  0.0, 1.0,
    -0.5, -0.5, -0.5,  0.0, 0.0,

    -0.5, -0.5,  0.5,  0.0, 0.0,
     0.5, -0.5,  0.5,  1.0, 0.0,
     0.5,  0.5,  0.5,  1.0, 1.0,
     0.5,  0.5,  0.5,  1.0, 1.0,
    -0.5,  0.5,  0.5,  0.0, 1.0,
    -0.5, -0.5,  0.5,  0.0, 0.0,

    -0.5,  0.5,  0.5,  1.0, 0.0,
    -0.5,  0.5, -0.5,  1.0, 1.0,
    -0.5, -0.5, -0.5,  0.0, 1.0,
    -0.5, -0.5, -0.5,  0.0, 1.0,
    -0.5, -0.5,  0.5,  0.0, 0.0,
    -0.5,  0.5,  0.5,  1.0, 0.0,

     0.5,  0.5,  0.5,  1.0, 0.0,
     0.5,  0.5, -0.5,  1.0, 1.0,
     0.5, -0.5, -0.5,  0.0, 1.0,
     0.5, -0.5, -0.5,  0.0, 1.0,
     0.5, -0.5,  0.5,  0.0, 0.0,
     0.5,  0.5,  0.5,  1.0, 0.0,

    -0.5, -0.5, -0.5,  0.0, 1.0,
     0.5, -0.5, -0.5,  1.0, 1.0,
     0.5, -0.5,  0.5,  1.0, 0.0,
     0.5, -0.5,  0.5,  1.0, 0.0,
    -0.5, -0.5,  0.5,  0.0, 0.0,
    -0.5, -0.5, -0.5,  0.0, 1.0,

    -0.5,  0.5, -0.5,  0.0, 1.0,
     0.5,  0.5, -0.5,  1.0, 1.0,
     0.5,  0.5,  0.5,  1.0, 0.0,
     0.5,  0.5,  0.5,  1.0, 0.0,
    -0.5,  0.5,  0.5,  0.0, 0.0,
    -0.5,  0.5, -0.5,  0.0, 1.0
]



screenWidth=960
screenHeight=960

cameraAngleX=218
cameraAngleY=10

zdistance=-0.2
mouseLeftDown=False
mouseRightDown=False
mouseX=0.0
mouseY=0.0

cameraDistance=1.7

#将图片加载到 texture 缓存对象中
def loadImage(imageName = "beau.jpg" ):
    """Load an image from a file using PIL.
    This is closer to what you really want to do than the
    original port's crammed-together stuff that set global
    state in the loading method.  Note the process of binding
    the texture to an ID then loading the texture into memory.
    This didn't seem clear to me somehow in the tutorial.
    """
    try:
        from PIL.Image import open
    except ImportError:
        from Image import open
    im = open(imageName)
    try:
        ix, iy, image = im.size[0], im.size[1], im.tobytes("raw", "RGBA", 0, -1)
    except SystemError:
        ix, iy, image = im.size[0], im.size[1], im.tobytes("raw", "RGBX", 0, -1)
    # generate a texture ID
    ID=glGenTextures(1)
    # make it current
    glBindTexture(GL_TEXTURE_2D, ID)
    glPixelStorei(GL_UNPACK_ALIGNMENT,1)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    # copy the texture into the current texture ID
    glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
    print(ix,iy)
    glGenerateMipmap(GL_TEXTURE_2D)
    # return the ID for use
    return ID

def mydraw():

    # clear
    global cameraAngleX
    global cameraAngleY  
    global  zdistance
    #cameraAngleX=-55+cameraAngleX
    # zdistance=zdistance+0.1
    # if (zdistance>0.9):
        # zdistance=-0.9
    
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
    
    sinx=math.sin(math.radians(cameraAngleX))
    cosx=math.cos(math.radians(cameraAngleX))
    
    siny=math.sin(math.radians(cameraAngleY))
    cosy=math.cos(math.radians(cameraAngleY))
    modely = numpy.array([ cosy, 0.0, -siny,0.0, 
                           0,    1.0, 0.0,0.0, 
                           siny, 0, cosy, 0.0, 
                           0.0, 0.0, 0.0, 1.0], numpy.float32)
    modelx = numpy.array([ 1.0 ,0.0, -0.0,0.0,  
                          0.0,cosx, -sinx, 0,  
                          0.0, sinx, cosx, 0.0, 
                          0.0, 0.0, 0.0, 1.0], numpy.float32)
                                
    project=  numpy.array([ 1.0, 0.0,0.0, 0.0, 
                                0.0, 1, 0, 0.0, 
                                0.0, 0, -1/4, 0.0, 
                                0.0, 0.0, 0.0, 1.0], numpy.float32)
                                
    view=  numpy.array([ 1.0, 0.0,0.0, 0.0, 
                         0.0, 1, 0, 0.0, 
                         0.0, 0, 1, zdistance, 
                         0.0, 0.0, 0.0, 1.0], numpy.float32)
                                
    project=project.reshape(4,4)
    modelx=modelx.reshape(4,4)
    modely=modely.reshape(4,4)
    model=numpy.dot(modelx,modely)
    view=view.reshape(4,4)
       
    buffers = glGenBuffers(1)
    float_size = sizeof(c_float)
    vertex_offset    = c_void_p(0 * float_size)    
    glBindBuffer(GL_ARRAY_BUFFER, buffers)
    glBufferData(GL_ARRAY_BUFFER, 
            len(vertices)*4,  # byte size
            (ctypes.c_float*len(vertices))(*vertices), 
            GL_STATIC_DRAW)
    
    
    
    
    glVertexAttribPointer(0,3,GL_FLOAT, False, 5 * float_size, vertex_offset)
    glEnableVertexAttribArray(0) 
    
    color_offset    = c_void_p(3 * float_size) 
    glVertexAttribPointer(1,2,GL_FLOAT, False, 5 * float_size, color_offset)
    glEnableVertexAttribArray(1) 
    
    global shader
    if shader==None:
            shader=Shader()
            shader.initShader('''
   
    layout (location = 0) in vec3 aPos; 
    layout (location = 1) in vec2 aTexCoord;
    out vec2 TexCoord;


    uniform  mat4 matrix; 
    uniform  mat4 view;
    uniform  mat4 project ;

    void main()
    {
        gl_Position =project*view*matrix*vec4(aPos.x, aPos.y, aPos.z, 1.0); 
    
        TexCoord = aTexCoord;
        
       
    }
            ''',
            '''
    out vec4 FragColor; 
    in vec2 TexCoord;
    uniform sampler2D ourTexture;
    void main()
    {
        
       
        FragColor =texture(ourTexture, TexCoord);
    }
            ''')

    
    shader.begin()
    mvp_matrix_loc = glGetUniformLocation(shader.program, 'matrix' )
    glUniformMatrix4fv(mvp_matrix_loc,1,GL_FALSE, model) 
    vp_matrix_loc = glGetUniformLocation(shader.program, 'view' )
    glUniformMatrix4fv(vp_matrix_loc,1,GL_FALSE, view)

    p_matrix_loc = glGetUniformLocation(shader.program, 'project' )
    glUniformMatrix4fv(p_matrix_loc,1,GL_FALSE, project)   
    
    glDrawArrays(GL_TRIANGLES, 0,36)
   
    shader.end()
    glDisableVertexAttribArray(0)
    glDisableVertexAttribArray(1)
    
   
    
def disp_func():
    mydraw()    
    glutSwapBuffers()
    
def timerCB(millisec):

    glutTimerFunc(millisec, timerCB, millisec)
    glutPostRedisplay()
    
def mouseCB( button,  state,  x,  y):
    global mouseX 
    global mouseY 
    mouseX = x
    mouseY = y
    global mouseLeftDown
    if(button == GLUT_LEFT_BUTTON):
    
        if(state == GLUT_DOWN):
        
            mouseLeftDown = True
            
        
        elif(state == GLUT_UP):
            mouseLeftDown = False
       

    elif(button == GLUT_RIGHT_BUTTON):
    
        if(state == GLUT_DOWN):
        
            mouseRightDown = True
        
        elif(state == GLUT_UP):
            mouseRightDown = False
    
    


def mouseMotionCB( x,  y):
    global cameraAngleX
    global cameraAngleY     
    global mouseLeftDown 
    
    global mouseX 
    global mouseY 
    
    if(mouseLeftDown):
    
        cameraAngleY += (x - mouseX)
        cameraAngleX += (y - mouseY)
        mouseX = x
        mouseY = y
        # print(cameraAngleX)
    
    if(mouseRightDown):
    
        cameraDistance -= (y - mouseY) * 0.2
        mouseY = y
        
if __name__=="__main__":
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH| GLUT_STENCIL)
    glutInitWindowSize(screenWidth, screenHeight)
    glutCreateWindow(b"vbo")
    loadImage("122.jpg")
    glutDisplayFunc(disp_func)
    glutTimerFunc(330, timerCB, 330)
    glutMouseFunc(mouseCB) 
    glutMotionFunc(mouseMotionCB)
    
    glEnable(GL_DEPTH_TEST)
   
    
    glutMainLoop()

最终生成的效果如图:

pyopengl之cube texture_第3张图片

你可能感兴趣的:(python,opengl)