- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 PyOpenGL 比较陌生,并开始学习转换以及模型、 View 和投影矩阵。一切都很好,直到我编译并运行我的代码,发现我的对象突然消失了,说实话,我不知道 OpenGL 是否正在裁剪我的对象,或者只是因为某些相机错误而没有显示它,但我相信它有一些东西与我的代码中实现的投影矩阵有关,因为当我从代码中删除投影矩阵并运行我的程序时,一切都突然再次工作,除了我不会实现透视投影这一事实。无论如何,任何人都会非常感激:D
这是我的 PyOpenGL 代码。
import OpenGL, PIL, pygame, numpy, pyrr, math, sys, os
from OpenGL.GL import *
from PIL import Image
from pyrr import Matrix44, Vector4, Vector3, Quaternion
VERT_DATA = numpy.array([0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, -0.5, 0.0,
-0.5, 0.5, 0.0],
dtype="float32")
COLOR_DATA = numpy.array([1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0,
0.0, 1.0, 1.0, 1.0],
dtype="float32")
TEXTURE_COORD_DATA = numpy.array([0.5, 0.5,
0.5, -0.5,
-0.5, -0.5,
-0.5, 0.5],
dtype="float32")
INDICES = numpy.array([0, 1, 3,
1, 2, 3],
dtype="int32")
class GLProgram:
def __init__(self):
self.gl_program = glCreateProgram()
self.mvp_matrix = self.projection()
self.shaders()
self.gl_buffers()
def gl_texture(self, texture_path):
image = Image.open(texture_path).transpose(Image.FLIP_TOP_BOTTOM)
image_data = numpy.fromstring(image.tobytes(), numpy.uint8)
width, height = image.size
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)
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_LINEAR)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data)
glGenerateMipmap(GL_TEXTURE_2D)
return texture
def gl_buffers(self):
self.vao = glGenVertexArrays(1)
glBindVertexArray(self.vao)
self.pos_vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.pos_vbo)
glBufferData(GL_ARRAY_BUFFER, VERT_DATA, GL_STATIC_DRAW)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
glEnableVertexAttribArray(0)
self.text_coord_vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.text_coord_vbo)
glBufferData(GL_ARRAY_BUFFER, TEXTURE_COORD_DATA, GL_STATIC_DRAW)
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, None)
glEnableVertexAttribArray(1)
self.pos_ebo = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.pos_ebo)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.pos_ebo)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, INDICES, GL_STATIC_DRAW)
self.brick_texture = self.gl_texture("check.jpg")
def shaders(self):
vertex_shader = glCreateShader(GL_VERTEX_SHADER)
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER)
with open("VertexShader.vert", "r") as vert_file:
vert_source = vert_file.read()
with open("FragmentShader.frag", "r") as frag_file:
frag_source = frag_file.read()
glShaderSource(vertex_shader, vert_source)
glShaderSource(fragment_shader, frag_source)
glCompileShader(vertex_shader)
if not glGetShaderiv(vertex_shader, GL_COMPILE_STATUS):
info_log = glGetShaderInfoLog(vertex_shader)
print ("Compilation Failure for " + vertex_shader + " shader:\n" + info_log)
glCompileShader(fragment_shader)
if not glGetShaderiv(fragment_shader, GL_COMPILE_STATUS):
info_log = glGetShaderInfoLog(fragment_shader)
print ("Compilation Failure for " + fragment_shader + " shader:\n" + info_log)
glAttachShader(self.gl_program, vertex_shader)
glAttachShader(self.gl_program, fragment_shader)
glLinkProgram(self.gl_program)
glDeleteShader(vertex_shader)
glDeleteShader(fragment_shader)
def projection(self):
scale_matrix = pyrr.matrix44.create_from_scale(Vector3([1, 1, 1]))
rot_matrix = Matrix44.identity()
trans_matrix = pyrr.matrix44.create_from_translation(Vector3([1, 1, 0]))
model_matrix = scale_matrix * rot_matrix * trans_matrix
view_matrix = pyrr.matrix44.create_look_at(numpy.array([4, 3, 3]), numpy.array([1, 1, 0]), numpy.array([0, 1, 0]))
proj_matrix = pyrr.matrix44.create_perspective_projection_matrix(45.0, 1280/720, 0.1, 1000.0)
mvp_matrix = proj_matrix * view_matrix * model_matrix
return mvp_matrix
def display(self):
glEnable(GL_DEPTH_TEST)
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(self.gl_program)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, self.brick_texture)
texture_uniform = glGetUniformLocation(self.gl_program, "the_texture")
glUniform1i(texture_uniform, 0)
trans_uniform = glGetUniformLocation(self.gl_program, "mvp")
glUniformMatrix4fv(trans_uniform, 1, GL_FALSE, self.mvp_matrix)
glBindVertexArray(self.vao)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
glUseProgram(0)
def main():
pygame.init()
os.environ['SDL_VIDEO_CENTERED'] = '1'
pygame.display.set_caption("3D Graphics")
pygame.display.set_mode((1280, 720), pygame.DOUBLEBUF | pygame.OPENGL)
clock = pygame.time.Clock()
gl = GLProgram()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
clock.tick(60)
gl.display()
pygame.display.flip()
if __name__ == "__main__":
main()
顶点着色器:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 text_coord;
out vec2 final_text_coord;
uniform mat4 mvp;
void main() {
gl_Position = mvp * vec4(position, 1.0);
final_text_coord = text_coord;
}
片段着色器:
#version 330 core
in vec2 final_text_coord;
out vec4 frag_color;
uniform sampler2D the_texture;
void main() {
frag_color = texture(the_texture, final_text_coord);
}
最佳答案
您的代码存在一些问题:
矩阵乘法。将两个二维 numpy 数组相乘会产生按分量乘积,而不是矩阵乘法。使用 numpy.matmul 可以解决这个问题。
矩阵约定不明确。
正如pyrr
的文档所述,矩阵在内存中按行优先排列,这与 GL 的默认约定相反。此外,pyrr 创建转置为标准 GL 约定的矩阵。人们可能会认为这两件事都会自行抵消,这只是在一定程度上是正确的。每当您实际对这些矩阵执行其他操作(例如乘法)时,它就会中断,然后使用 native 约定,然后把事情搞砸。
我确实修改了你的代码,提供了两种不同的解决方案。由于您在问题和答案之间稍微更改了代码,因此我最终得到了两个版本的疯狂组合。我还禁用了纹理功能,因为我缺少一些库(和图像文件)。我相应地修改了片段着色器,但这并不重要。
import OpenGL, PIL, pygame, numpy, pyrr, math, sys, os
from OpenGL.GL import *
from PIL import Image
from pyrr import Matrix44, Vector4, Vector3, Quaternion
VERT_DATA = numpy.array([0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, -0.5, 0.0,
-0.5, 0.5, 0.0],
dtype="float32")
COLOR_DATA = numpy.array([1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0,
0.0, 1.0, 1.0, 1.0],
dtype="float32")
TEXTURE_COORD_DATA = numpy.array([0.5, 0.5,
0.5, -0.5,
-0.5, -0.5,
-0.5, 0.5],
dtype="float32")
INDICES = numpy.array([0, 1, 3,
1, 2, 3],
dtype="int32")
WINDOW_WIDTH=1280
WINDOW_HEIGHT=720
class GLProgram:
def __init__(self):
self.gl_program = glCreateProgram()
self.mvp_matrix = self.projection()
self.shaders()
self.gl_buffers()
self.cube_model_matrix, self.cube_view_matrix, self.cube_proj_matrix = self.gl_translate(Vector3([1.0, 1.0, 1.0]), 45.0, Vector3([0.5, 0.5, 0.5]))
self.cube_mvp = self.gl_translate3(Vector3([1.0, 1.0, 1.0]), -45.0, Vector3([0.5, 0.5, 0.5]))
def gl_texture(self, texture_path):
return 0
def gl_buffers(self):
self.vao = glGenVertexArrays(1)
glBindVertexArray(self.vao)
self.pos_vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.pos_vbo)
glBufferData(GL_ARRAY_BUFFER, VERT_DATA, GL_STATIC_DRAW)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
glEnableVertexAttribArray(0)
self.text_coord_vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.text_coord_vbo)
glBufferData(GL_ARRAY_BUFFER, TEXTURE_COORD_DATA, GL_STATIC_DRAW)
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, None)
glEnableVertexAttribArray(1)
self.pos_ebo = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.pos_ebo)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.pos_ebo)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, INDICES, GL_STATIC_DRAW)
self.brick_texture = self.gl_texture("check.jpg")
def shaders(self):
vertex_shader = glCreateShader(GL_VERTEX_SHADER)
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER)
with open("VertexShader.vert", "r") as vert_file:
vert_source = vert_file.read()
with open("FragmentShader.frag", "r") as frag_file:
frag_source = frag_file.read()
glShaderSource(vertex_shader, vert_source)
glShaderSource(fragment_shader, frag_source)
glCompileShader(vertex_shader)
if not glGetShaderiv(vertex_shader, GL_COMPILE_STATUS):
info_log = glGetShaderInfoLog(vertex_shader)
print ("Compilation Failure for " + vertex_shader + " shader:\n" + info_log)
glCompileShader(fragment_shader)
if not glGetShaderiv(fragment_shader, GL_COMPILE_STATUS):
info_log = glGetShaderInfoLog(fragment_shader)
print ("Compilation Failure for " + fragment_shader + " shader:\n" + info_log)
glAttachShader(self.gl_program, vertex_shader)
glAttachShader(self.gl_program, fragment_shader)
glLinkProgram(self.gl_program)
glDeleteShader(vertex_shader)
glDeleteShader(fragment_shader)
def projection(self):
scale_matrix = pyrr.matrix44.create_from_scale(Vector3([1, 1, 1]))
rot_matrix = Matrix44.identity()
trans_matrix = pyrr.matrix44.create_from_translation(Vector3([1, 1, 0]))
model_matrix = scale_matrix * rot_matrix * trans_matrix
view_matrix = pyrr.matrix44.create_look_at(numpy.array([4, 3, 3]), numpy.array([1, 1, 0]), numpy.array([0, 1, 0]))
proj_matrix = pyrr.matrix44.create_perspective_projection_matrix(45.0, 1280/720, 0.1, 1000.0)
mvp_matrix = proj_matrix * view_matrix * model_matrix
return mvp_matrix
def gl_translate(self, translation, rotation, scale):
trans_matrix = pyrr.matrix44.create_from_translation(translation)
rot_matrix = numpy.transpose(pyrr.matrix44.create_from_y_rotation(rotation))
scale_matrix = numpy.transpose(pyrr.matrix44.create_from_scale(scale))
model_matrix = scale_matrix * rot_matrix * trans_matrix
view_matrix = pyrr.matrix44.create_look_at(numpy.array([2.0, 2.0, 3.0], dtype="float32"),
numpy.array([0.0, 0.0, 0.0], dtype="float32"),
numpy.array([0.0, 1.0, 0.0], dtype="float32"))
proj_matrix = pyrr.matrix44.create_perspective_projection(45.0, WINDOW_WIDTH/WINDOW_HEIGHT, 0.1, 200.0)
return model_matrix, view_matrix, proj_matrix
def gl_translate2(self, translation, rotation, scale):
trans_matrix = pyrr.matrix44.create_from_translation(translation)
rot_matrix = pyrr.matrix44.create_from_y_rotation(rotation)
scale_matrix = pyrr.matrix44.create_from_scale(scale)
model_matrix = numpy.matmul(numpy.matmul(scale_matrix,rot_matrix),trans_matrix)
view_matrix = pyrr.matrix44.create_look_at(numpy.array([2.0, 2.0, 3.0], dtype="float32"),
numpy.array([0.0, 0.0, 0.0], dtype="float32"),
numpy.array([0.0, 1.0, 0.0], dtype="float32"))
proj_matrix = pyrr.matrix44.create_perspective_projection(45.0, WINDOW_WIDTH/WINDOW_HEIGHT, 0.1, 200.0)
m = numpy.matmul(numpy.matmul(model_matrix,view_matrix),proj_matrix)
return m
def gl_translate3(self, translation, rotation, scale):
trans_matrix = numpy.transpose(pyrr.matrix44.create_from_translation(translation))
rot_matrix = numpy.transpose(pyrr.matrix44.create_from_y_rotation(rotation))
scale_matrix = numpy.transpose(pyrr.matrix44.create_from_scale(scale))
model_matrix = numpy.matmul(numpy.matmul(trans_matrix,rot_matrix),scale_matrix)
view_matrix = numpy.transpose(pyrr.matrix44.create_look_at(numpy.array([2.0, 2.0, 3.0], dtype="float32"),
numpy.array([0.0, 0.0, 0.0], dtype="float32"),
numpy.array([0.0, 1.0, 0.0], dtype="float32")))
proj_matrix = numpy.transpose(pyrr.matrix44.create_perspective_projection(45.0, WINDOW_WIDTH/WINDOW_HEIGHT, 0.1, 200.0))
m = numpy.matmul(numpy.matmul(proj_matrix,view_matrix),model_matrix)
return numpy.transpose(m)
def display(self):
glEnable(GL_DEPTH_TEST)
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(self.gl_program)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, self.brick_texture)
texture_uniform = glGetUniformLocation(self.gl_program, "the_texture")
glUniform1i(texture_uniform, 0)
trans_uniform = glGetUniformLocation(self.gl_program, "mvp")
glUniformMatrix4fv(trans_uniform, 1, GL_FALSE, self.cube_mvp)
#model_location = glGetUniformLocation(self.gl_program, "model")
#glUniformMatrix4fv(model_location, 1, GL_FALSE, self.cube_model_matrix)
#view_location = glGetUniformLocation(self.gl_program, "view")
#glUniformMatrix4fv(view_location, 1, GL_FALSE, self.cube_view_matrix)
#proj_location = glGetUniformLocation(self.gl_program, "proj")
#glUniformMatrix4fv(proj_location, 1, GL_FALSE, self.cube_proj_matrix)
glBindVertexArray(self.vao)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
glUseProgram(0)
def main():
pygame.init()
os.environ['SDL_VIDEO_CENTERED'] = '1'
pygame.display.set_caption("3D Graphics")
pygame.display.set_mode((1280, 720), pygame.DOUBLEBUF | pygame.OPENGL)
clock = pygame.time.Clock()
gl = GLProgram()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
clock.tick(60)
gl.display()
pygame.display.flip()
if __name__ == "__main__":
main()
使用此顶点着色器:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 text_coord;
out vec2 final_text_coord;
uniform mat4 mvp;
void main() {
gl_Position = mvp * vec4(position, 1.0);
final_text_coord = text_coord;
}
还有这个片段着色器:
#version 330 core
in vec2 final_text_coord;
out vec4 frag_color;
uniform sampler2D the_texture;
void main() {
frag_color = vec4(1,0,0,1);
}
我专门添加了方法gl_translate2
和gl_translate3
。两者都会产生相同的矩阵,2
变体仅使用 pyrr
库的 native 乘法顺序约定,而 gl_translate3
使用 GL 约定.
我还创建了具有不同参数的矩阵
self.cube_mvp = self.gl_translate3(Vector3([1.0, 1.0, 1.0]), -45.0, Vector3([0.5, 0.5, 0.5]))
其不同之处在于旋转的负号(并补偿您在 gl_transaltion
中执行的额外转置
)。
结果与您在发布的答案中得到的结果不同,但这是由于您的模型矩阵在该答案中被破坏,这是由于错误的乘法函数(特别是删除了平移部分并将旋转扭曲为一些剪切操作)。
我使用 gl_translate2
和 gl_translate3
得到的结果是: 对于指定的参数来说,这看起来非常合理。
关于python - PyOpenGL 透视投影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45514353/
我正在尝试使用透视投影描绘一个立方体,但我得到的只是一个正方形的角。正方形的面设置在原点并向正方向扩展。使用 glOrtho 我可以设置坐标系,但我在使用 glPerspective 做同样的事情时遇
SELECT j.departure, stopDepartures.* FROM journey j JOIN journey_day ON journey_day.journey = j.id J
我确实需要一些帮助来了解如何根据相似的值对表格进行透视。 day | startDate ----------------------- Monday | 09:00 Monday |
我有以下数据框 df = pd.DataFrame({ '1': ['Mon (07/08)','Sales', '2'], '2': ['Mon (07/0
dummy_df = pd.DataFrame({ 'accnt' : [101, 102, 103, 104, 101, 102, 103, 104, 101, 102, 103, 104,
public class MainActivity extends Activity { LinearLayout rotator; protected void onCreate(Bundle sa
我正在尝试通过 PHP 更改 ImageMagick 中 Plane2Cylinder 失真的视角。 为了帮助解释我在寻找什么,我制作了这张图: 您可以看到红色 block 的下部比顶部的半径更大,就
我有一个像这样的简单查询.. USE AdventureWorks; GO SELECT DaysToManufacture, AVG(StandardCost) AS AverageCost FRO
我希望我可以更改架构,但我受制于它,假设我有以下表格 JanDataTable FebDataTable MarDataTable ProductsTable 其中前三个表有 ID 和 Amount
我正在将我们的一个旧应用程序从 vb6 更新到 c#,在此过程中必须重新创建原始程序员设计的自定义控件。该控件简单地获取对象的尺寸,矩形或圆锥形,并在 3D 中放置对象的轮廓草图(我认为在技术上是 2
我一直在尝试在 MySQL 中对表进行透视(将行移动到列)。我知道 mysql 没有枢纽功能,所以我认为需要联合,但不是 100% 确定。我有三列,user_id、option_id 和 Questi
我正在尝试旋转像这样创建的 mysql 表 'CREATE TABLE `fundreturns` ( `Timestamp` datetime NOT NULL, `FundName` varcha
提前感谢任何对此提供帮助的人。我知道我以前做过这件事,没有太多痛苦,但似乎找不到解决方案 我的数据库看起来像这样: `tbl_user: ---------- id ( pkey )
我正在尝试开发 X 轴方向的卡片翻转动画。截至目前,div 现在只需使用 rotateX() 方法进行旋转。我试过对上层 div 使用透视属性,而不是工作它扭曲了我的 div 结构。因为,这只是一个工
我有一个带有 CSS3 透视图的 DIV 元素。 DIV 包含 2 个子 DIV,其中之一在 z 轴上有平移。这应该会导致一个 DIV 在另一个前面,因此后面的那个应该被挡住。 然而,这些 DIV 的
大家好,我有一张这样的 map http://sinanisler.com/demo/map/ 如您所见,有一些树,但不是真正的视角,我想要这个 http://sinanisler.com/demo/
我有以下代码将快照拍摄到帧缓冲区。我验证了帧缓冲区工作正常并且相机正确地面向对象。我曾经正确地完成图片,但它是基于错误的代码,使用了错误的截锥体。所以我决定重新开始(使用截锥体)。 物体以中间为中心,
我正在尝试将求和列添加到透视数据框,但不断收到数据解析错误。 mydata = [{'amount': 3200, 'close_date':'2013-03-31', 'customer': 'Cu
我正在尝试将一些 groupby/crosstabbing 逻辑应用于用户定义对象的 IEnumerable 列表,并且想知道是否有人可以帮助我。我坚持使用现有的(相当烦人的)对象模型来工作,但无论如
我想使用一个 CALayer 创建如下图所示的效果 - 而不是通过拆分图像、对两半进行透视变换然后将它们并排放置。 可以使用 CoreImage 以任何方式完成吗? 或者,有人可以使用 OpenGL
我是一名优秀的程序员,十分优秀!