标题说明了一切。关于这类事情的教程并不多。有经验的人可以帮我吗?
我尝试了很多事情。有趣的是,尽管在Qt世界之外,我已经能够获得OpenTK(C#)和OpenGL(C ++)版本的工作(我的老板希望使用Python)。我知道我已经接近了,但是我看不到上一期。
我只看到一个黑色的窗口。
代码:
Python:
import sys
import numpy as np
import OpenGL.GL as gl
import array
from PyQt5 import QtGui
from PyQt5.QtCore import QSize, QPoint, Qt, pyqtSignal
from PyQt5.QtWidgets import QApplication, QWidget, QOpenGLWidget, QHBoxLayout
#from framework import *
vertexDim = 3
nVertices = 3
cubemap = np.array([-1.0, 1.0, -1.0,
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, 1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0,
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0], dtype='float32')
class App(QWidget):
def __init__(self):
super(App, self).__init__()
self.glWidget = GLWidget()
mainLayout = QHBoxLayout()
mainLayout.addWidget(self.glWidget)
self.setLayout(mainLayout)
self.title = 'OpenGL Window - PyQt5'
self.left = 20
self.top = 30
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
#self.setGeometry(self.left, self.top, self.width, self.height)
class GLWidget(QOpenGLWidget):
clicked = pyqtSignal()
def __init__(self, parent=None):
super(GLWidget, self).__init__(parent)
self.profile = QtGui.QOpenGLVersionProfile()
self.profile.setVersion( 2, 1 )
self.xRot = 0
self.yRot = 0
self.zRot = 0
# self.program = None
self.lastPos = QPoint()
def getOpenglInfo(self):
info = """
Vendor: {0}
Renderer: {1}
OpenGL Version: {2}
Shader Version: {3}
""".format(
gl.glGetString(gl.GL_VENDOR),
gl.glGetString(gl.GL_RENDERER),
gl.glGetString(gl.GL_VERSION),
gl.glGetString(gl.GL_SHADING_LANGUAGE_VERSION)
)
return info
def rotateBy(self, xAngle, yAngle, zAngle):
print(str(xAngle) + ", " + str(yAngle) + ", " + str(zAngle))
self.xRot += xAngle
self.yRot += yAngle
self.zRot += zAngle
self.update()
def minimumSizeHint(self):
return QSize(600, 400)
def initializeGL(self):
print(self.getOpenglInfo())
self.gl = self.context().versionFunctions( self.profile )
# Vertex Array Object
self.vao = QtGui.QOpenGLVertexArrayObject( self )
self.vao.create()
# Set up and link shaders
self.program = QtGui.QOpenGLShaderProgram( self )
self.program.addShaderFromSourceFile( QtGui.QOpenGLShader.Vertex, 'shader.vert' )
self.program.addShaderFromSourceFile( QtGui.QOpenGLShader.Fragment, 'shader.frag' )
self.program.link()
self.vao.bind()
self.vertices = np.array([ 0.0, 0.0, 0.0, # x, y, z
1.0, 0.0, 0.0,
0.5, 1.0, 0.0 ], dtype='float32')
self.vbo_vertices = self.setVertexBuffer( cubemap, 3, self.program, "position" )
self.colors = np.array([ 1.0, 0.0, 0.0, 1.0, # r, g, b, a
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0 ], dtype='float32')
self.vbo_colors = self.setVertexBuffer( self.colors, 4, self.program, "texture" )
self.vao.release()
self.program.bind()
self.program.release()
def resizeGL(self, width, height):
gl.glViewport(0, 0, width, height)
def setVertexBuffer( self, data_array, dim_vertex, program, shader_str ):
vbo = QtGui.QOpenGLBuffer( QtGui.QOpenGLBuffer.VertexBuffer )
vbo.create()
vbo.bind()
vertices = np.array( data_array, np.float32 )
vbo.allocate( vertices, vertices.shape[0] * vertices.itemsize )
attr_loc = program.attributeLocation( shader_str )
program.enableAttributeArray( attr_loc )
program.setAttributeBuffer( attr_loc, gl.GL_FLOAT, 0, dim_vertex )
vbo.release()
return vbo
def paintGL(self):
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glClearColor(0.0, 0.0, 0.2, 0.0)
self.program.bind()
self.texture = QtGui.QOpenGLTexture(QtGui.QOpenGLTexture.TargetCubeMap)
self.texture.create()
print(self.texture.isCreated())
img = QtGui.QImage("C:\\Users\\path\\to\\image.jpg")
self.texture.bind()
self.texture.setSize(1024, 1024)
self.texture.setFormat(QtGui.QOpenGLTexture.RGBAFormat)
self.texture.allocateStorage()
self.texture.setData(0, 0, QtGui.QOpenGLTexture.CubeMapNegativeX, QtGui.QOpenGLTexture.RGBA, QtGui.QOpenGLTexture.UInt16, img.bits())
self.texture.setData(0, 0, QtGui.QOpenGLTexture.CubeMapNegativeY, QtGui.QOpenGLTexture.RGBA, QtGui.QOpenGLTexture.UInt16, img.bits())
self.texture.setData(0, 0, QtGui.QOpenGLTexture.CubeMapNegativeZ, QtGui.QOpenGLTexture.RGBA, QtGui.QOpenGLTexture.UInt16, img.bits())
self.texture.setData(0, 0, QtGui.QOpenGLTexture.CubeMapPositiveX, QtGui.QOpenGLTexture.RGBA, QtGui.QOpenGLTexture.UInt16, img.bits())
self.texture.setData(0, 0, QtGui.QOpenGLTexture.CubeMapPositiveY, QtGui.QOpenGLTexture.RGBA, QtGui.QOpenGLTexture.UInt16, img.bits())
self.texture.setData(0, 0, QtGui.QOpenGLTexture.CubeMapPositiveZ, QtGui.QOpenGLTexture.RGBA, QtGui.QOpenGLTexture.UInt16, img.bits())
self.texture.setMinMagFilters(QtGui.QOpenGLTexture.Linear, QtGui.QOpenGLTexture.Linear)
self.texture.setWrapMode(QtGui.QOpenGLTexture.ClampToEdge)
# initialise Camera matrix with initial rotation
m = QtGui.QMatrix4x4()
m.ortho(-0.5, 0.5, 0.5, -0.5, 4.0, 15.0)
m.translate(0.0, 0.0, -10.0)
m.rotate(self.xRot / 16.0, 1.0, 0.0, 0.0)
m.rotate(self.yRot / 16.0, 0.0, 1.0, 0.0)
m.rotate(self.zRot / 16.0, 0.0, 0.0, 1.0)
self.program.setUniformValue('mvp', m)
self.program.setUniformValue('texture', 0)
self.vao.bind()
gl.glDrawArrays( gl.GL_TRIANGLES, 0, 36 )
self.vao.release()
self.program.release()
def mousePressEvent(self, event):
self.lastPos = event.pos()
def mouseMoveEvent(self, event):
dx = event.x() - self.lastPos.x()
dy = event.y() - self.lastPos.y()
if event.buttons() & Qt.LeftButton:
self.rotateBy(8 * dy, 8 * dx, 0)
elif event.buttons() & Qt.RightButton:
self.rotateBy(8 * dy, 0, 8 * dx)
self.lastPos = event.pos()
self.paintGL()
def mouseReleaseEvent(self, event):
self.clicked.emit()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
着色器:
shader.vert
#version 430 core
in vec3 position;
out vec3 texCoords;
uniform mat4 mvp;
void main(void)
{
texCoords = position;
gl_Position = mvp * vec4(position, 1.0);
}
shader.frag
#version 430 core
in vec3 texCoords;
uniform sampler2D texture;
void main(void)
{
gl_FragColor = texture2D(texture, texCoords.xy);
}
答案 0 :(得分:3)
由于self.texture是一个立方体贴图(QtGui.QOpenGLTexture.TargetCubeMap
),因此相应的纹理采样器统一类型必须为samplerCube
,而不是sampler2D
。
将立方体贴图的纹理坐标视为从立方体中心发出的方向向量。
由于立方体模型的中心是(0,0,0),因此方向矢量或纹理坐标等于片段的模型位置。
更改片段着色器以解决该问题:
#version 430 core
in vec3 texCoords;
uniform samplerCube texture;
void main(void)
{
gl_FragColor = texture(texture, texCoords.xyz);
}
注意,texture2D
和textureCube
分别是兼容性配置文件功能。您必须使用功能texture
,该功能与核心配置文件的兼容性一样。