用pygame和pyopengl的基础操作

本文介绍了如何在Python中使用Pygame库结合OpenGL进行3D图形渲染,包括顶点数据处理、纹理映射和着色器编程,展示了如何加载和显示纹理图片。
摘要由CSDN通过智能技术生成

内容包括:可编程管线、着色器、纹理。

用pip下载pyopengl,没去官网。OpenGL的初始化函数自然无法被调用,所以就用pygame来显示。

这是我最终的效果。注意改一下图片的路径,图片放在与本代码一起的文件夹内

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
from PIL.Image import open

# 初始化pygame
pygame.init()

# 设置窗口尺寸
WINDOW_WIDTH, WINDOW_HEIGHT = 800, 600

# 创建窗口
display = (WINDOW_WIDTH, WINDOW_HEIGHT)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)

# 初始化OpenGL
gluPerspective(45, (WINDOW_WIDTH / float(WINDOW_HEIGHT)), 0.1, 50.0)
glTranslatef(0.0, 0.0, -5)

# 准备顶点位置和颜色数据
position_data = [
    -1.0, -1.0, 0.0,  # 左下
    1.0, -1.0, 0.0,  # 右下
    -1.0, 1.0, 0.0,  # 左上
    1.0, 1.0, 0.0  # 右上
]

# position_data = [
#     0.0, 0.0, 0.0,  # 左下
#     1.0, 0.0, 0.0,  # 右下
#     0.0, 1.0, 0.0,  # 左上
#     1.0, 1.0, 0.0  # 右上
# ]

color_data = [
    1.0, 0.0, 0.0, 1.0,  # 红色
    0.0, 1.0, 0.0, 1.0,  # 绿色
    0.0, 0.0, 1.0, 1.0,  # 蓝色
    1.0, 1.0, 0.0, 1.0  # 黄色
]

# 设置纹理坐标
aTexCoord = [
    0.0, 1.0,
    1.0, 1.0,
    0.0, 0.0,
    1.0, 0.0
]

# 图片数据
image = open('./myphoto.jpg')

# 创建纹理对象
texture = glGenTextures(1)

# 绑定纹理对象
glBindTexture(GL_TEXTURE_2D, texture)

# 为当前绑定的纹理对象设置环绕、过滤方式
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)

# 使用图片数据生成纹理
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.size[0], image.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, image.tobytes())
glGenerateMipmap(GL_TEXTURE_2D)

# 设置纹理坐标
# 转移至准备数据的位置

# 指定纹理坐标属性
# 转移至VAO的位置

# 创建VBO
posVbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, posVbo)
glBufferData(GL_ARRAY_BUFFER, len(position_data) * 4, (ctypes.c_float * len(position_data))(*position_data),
             GL_STATIC_DRAW)

colorVbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, colorVbo)
glBufferData(GL_ARRAY_BUFFER, len(color_data) * 4, (ctypes.c_float * len(color_data))(*color_data), GL_STATIC_DRAW)

aTexCoordVbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, aTexCoordVbo)
glBufferData(GL_ARRAY_BUFFER, len(aTexCoord) * 4, (ctypes.c_float * len(aTexCoord))(*aTexCoord), GL_STATIC_DRAW)

# 创建VAO
vao = glGenVertexArrays(1)
glBindVertexArray(vao)

# 绑定VBO到VAO,并设置顶点属性
glEnableVertexAttribArray(0)  # 位置属性位置
glBindBuffer(GL_ARRAY_BUFFER, posVbo)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)

glEnableVertexAttribArray(1)  # 颜色属性位置
glBindBuffer(GL_ARRAY_BUFFER, colorVbo)
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, None)

# 指定纹理坐标属性
glEnableVertexAttribArray(2)
glBindBuffer(GL_ARRAY_BUFFER, aTexCoordVbo)
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, None)


glBindVertexArray(0)  # 解绑VAO

# shader部分

#顶点着色器部分
a = """
#version 330

layout (location = 0) in vec3 Position;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

void main()
{
    gl_Position = vec4(0.5 * Position.x, 0.5 * Position.y, Position.z, 1.0);
    ourColor = aColor;
    TexCoord = aTexCoord;
    }
"""
#   gl_Position = vec4(0.5 * Position.x, 0.5 * Position.y, Position.z, 1.0);
#   gl_Position = vec4(Position.x, Position.y, Position.z, 1.0);

# 片段着色器部分,字符串类型
b = """
#version 330

in vec3 ourColor;
in vec2 TexCoord;

out vec4 FragColor;

uniform sampler2D texture1;

void main()
{
    FragColor = texture(texture1, TexCoord);
    }
"""
#   FragColor = vec4(0.0, 1.0, 0.0, 1.0);
#   FragColor = texture(texture1, TexCoord);
#   FragColor = vec4(ourColor, 1.0);

# 创建Shader程序
my_vertex = glCreateShader(GL_VERTEX_SHADER)
my_fragment = glCreateShader(GL_FRAGMENT_SHADER)

# 为程序输入代码
glShaderSource(my_vertex, a, None)
glShaderSource(my_fragment, b, None)

# 代码编译
glCompileShader(my_vertex)
glCompileShader(my_fragment)

# 创建program空壳子
program = glCreateProgram()

# 将编译好的结果放入program空壳子中
glAttachShader(program, my_vertex)
glAttachShader(program, my_fragment)

# 执行program的链接操作,形成最终可执行的shader程序
glLinkProgram(program)

# 清理
glDeleteShader(my_vertex)
glDeleteShader(my_fragment)

# 绘制循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

            # 清除屏幕和深度缓冲区
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    # 这个地方也可以绘制,不太好,要升级
    # glRotatef(1, 3, 1, 1)

    # 绘制
    glUseProgram(program)
    glBindVertexArray(vao)
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)

    # 刷新显示
    pygame.display.flip()
    pygame.time.wait(10)

# 退出pygame和OpenGL,并删除不需要用的、GUI内的、上文中被申请的存储空间
glDeleteVertexArrays(1, [vao])
glDeleteBuffers(1, [posVbo])
glDeleteBuffers(1, [colorVbo])

pygame.quit()
  • 14
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值