将一张图片贴到 立方体的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()
最终生成的效果如图: