pyopengl之cube texture

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

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

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

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

   

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

最终生成的效果如图:

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

proware

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值