GLUT 程序无一例外地崩溃

GLUT program crashes without any exception

我正在学习 GLSL 并尝试编写自己的光线追踪着色器。我将 Python 与 PyOpenGL + GLUT 一起使用。这通常是完美的,但是当我增加要跟踪的光线量时,程序会在 glutSwitchBuffers 操作上崩溃。没有错误消息,调试器中没有异常,只要应用程序遇到高负载(每帧大约 2000 毫秒),它就会关闭。 我现在不能上传我的代码,所以我希望至少有人能给点提示或建议

from random import random
from typing import Any
from OpenGL.GL import * 
from OpenGL.GLU import * 
from OpenGL.GLUT import *
import numpy as np
import time
import win32api
from PIL import Image
import sys


class RayTracing:

    def __init__(self):

        self.start = time.time()
        self.cam_x = 0
        self.cam_y = 0
        self.cam_z = 0
        self.cam_rot_x = 0
        self.cam_rot_y = 0
        self.cam_rot_z = 0
        self.save = False
        self.samples = 25

        glutInit(sys.argv)
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB) 
        glutInitWindowSize(1920, 1080)
        glutCreateWindow(b'Ray Tracing')
        glutFullScreen()

        glutDisplayFunc(self.draw)
        glutIdleFunc(self.draw)

        with open('./rtx.frag', 'r') as shader_file:
            shader = self.create_shader(GL_FRAGMENT_SHADER, shader_file.read())

        self.program = glCreateProgram()
        glAttachShader(self.program, shader)
        glLinkProgram(self.program)
        glUseProgram(self.program)

        self.width = glutGet(GLUT_WINDOW_WIDTH)
        self.height = glutGet(GLUT_WINDOW_HEIGHT)

        location = glGetUniformLocation(self.program,'WindowSize')
        glUniform2f(location, self.width, self.height)

        glutKeyboardFunc(self.catch_keyboard)
        glutSpecialFunc(self.specialKeys)
        glutPassiveMotionFunc(self.mouse)
        glutSetCursor(GLUT_CURSOR_NONE)
        

    def draw(self):

        location = glGetUniformLocation(self.program,'samples')
        glUniform1i(location, self.samples)

        location = glGetUniformLocation(self.program,'time')
        glUniform1f(location, self.start - time.time())

        location = glGetUniformLocation(self.program,'camera_pos')
        glUniform3f(location, self.cam_x, self.cam_y, self.cam_z)

        location = glGetUniformLocation(self.program,'camera_rot')
        glUniform3f(location, self.cam_rot_x, self.cam_rot_y, self.cam_rot_z)

        location = glGetUniformLocation(self.program,'seed_1')
        glUniform2f(location, random(), random())
        location = glGetUniformLocation(self.program,'seed_2')
        glUniform2f(location, random(), random())

        glClear(GL_COLOR_BUFFER_BIT)
        glRecti(-1, -1, 1, 1)

        glutSwapBuffers()  # Crashes on this line

    def create_shader(self, shader_type, source):

        shader = glCreateShader(shader_type)
        glShaderSource(shader, source)
        glCompileShader(shader)
        return shader

    def catch_keyboard(self, key, x, y):
        if key == b'w':  # 87
            self.cam_x += 1
        if key == b's':  # 83
            self.cam_x -= 1
        if key == b'a':  # 65
            self.cam_y -= 1
        if key == b'd':  # 68
            self.cam_y += 1
        if key == b'e':  # 16
            self.cam_z += 1
        if key == b'q':  # 17
            self.cam_z -= 1

    def specialKeys(self, key, x, y):
        if key == GLUT_KEY_END:
            self.samples = 2500
            self.save = True
            glutHideWindow()

    def mouse(self, x, y):
        dx = 1920 / 2 - x
        dy = 1080 / 2 - y
        self.cam_rot_z += dy / 1080
        self.cam_rot_y += -dx / 1920
        win32api.SetCursorPos((int(1920 / 2), int(1080 / 2)))

    def run(self):
        glutMainLoop()

rtx = RayTracing()
rtx.run()

好的,我使用BDL评论自己找到解决方案。 当显卡渲染帧超过 2 秒 Windows 时,只需终止该进程。这称为 TDL 超时。 当您需要进行硬计算时,有两种方法可以解决问题:

  1. 增加 TDL 超时时间click(不推荐)
  2. 将您的样本分成小样本,然后通过调用 glFlush 或类似的方法对它们进行一个一个地计算。