温馨提示:本文翻译自stackoverflow.com,查看原文请点击:python - hdrexposure program from SB OpenGL rendering blank screen
opengl python python-3.x

python - SB OpenGL的hdrexposure程序呈现空白屏幕

发布于 2020-03-27 11:42:23

相对简单的程序绘制一个空白屏幕。从Superbible Opengl第7版移植。

该程序当前正在绘制黑屏。尽管textoverlay正常工作。

更新:添加了使用glGetError来添加其他错误检查。虽然没有错误产生。但是仍然是黑屏。

更新和成功:该程序现在可以完美渲染hdr图像。感谢Rabbid76出色的回答。这也是需要修复的ktxloader。谢谢。

预期输出为:

预期产量

支持文件:hdrexposure_support.zip

移植自:hdrexposure.cpp

源代码:

#!/usr/bin/python3

import sys
import time
import ctypes

fullscreen = True
sys.path.append("./shared")

from sbmloader import SBMObject    # location of sbm file format loader
from ktxloader import KTXObject    # location of ktx file format loader
from textoverlay import OVERLAY_
from shader import shader_load, link_from_shaders

from sbmath import m3dDegToRad, m3dRadToDeg, m3dTranslateMatrix44, m3dRotationMatrix44, \
    m3dMultiply, m3dOrtho, m3dPerspective, rotation_matrix, translate, m3dScaleMatrix44, \
    scale, m3dLookAt, normalize

try:
    from OpenGL.GLUT import *
    from OpenGL.GL import *
    from OpenGL.GLU import *
    from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, glBindVertexArray
except:
    print ('''
    ERROR: PyOpenGL not installed properly.
        ''')
    sys.exit()

import numpy as np
from math import cos, sin
import glm
identityMatrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]

myobject = SBMObject()
ktxobject = KTXObject()
overlay = OVERLAY_()

texture = GLuint(0)
program = GLuint(0)
vao = GLuint(0)
exposure=1.0

vs_source = '''
#version 420 core

void main(void)
{
    const vec4 vertices[] = vec4[](vec4(-1.0, -1.0, 0.5, 1.0),
                                   vec4( 1.0, -1.0, 0.5, 1.0),
                                   vec4(-1.0,  1.0, 0.5, 1.0),
                                   vec4( 1.0,  1.0, 0.5, 1.0));

    gl_Position = vertices[gl_VertexID];
}
'''

fs_source = '''
#version 430 core

uniform sampler2D s;

uniform float exposure;

out vec4 color;

void main(void)
{
    vec4 c = texture(s, gl_FragCoord.xy / vec2(512.0, 512.0));
    c.xyz = vec3(1.0) - exp(-c.xyz * exposure);
    color = c;
}
'''
def checkGLError():
    status = glGetError()
    if status != GL_NO_ERROR:
        raise RuntimeError('gl error %s' % (status,))

class Scene:

    def __init__(self, width, height):
        global overlay
        global texture
        global program
        global vao    

        self.width = width
        self.height = height

        overlay.init(80, 50)

        #// Generate a name for the texture
        glGenTextures(1, texture)

        #// Load texture from file
        texture = ktxobject.ktx_load("treelights_2k.ktx")

        #// Now bind it to the context using the GL_TEXTURE_2D binding point
        glBindTexture(GL_TEXTURE_2D, texture)

        program = glCreateProgram()
        fs = glCreateShader(GL_FRAGMENT_SHADER)
        glShaderSource(fs, fs_source)
        glCompileShader(fs)

        if not glGetShaderiv(fs, GL_COMPILE_STATUS):
            print( 'compile error:' )
            print( glGetShaderInfoLog(fs) )

        vs = glCreateShader(GL_VERTEX_SHADER)
        glShaderSource(vs, vs_source)
        glCompileShader(vs)

        if not glGetShaderiv(vs, GL_COMPILE_STATUS):
            print( 'compile error:' )
            print( glGetShaderInfoLog(vs) )

        glAttachShader(program, vs)
        glAttachShader(program, fs)

        glLinkProgram(program)

        if not glGetProgramiv(program, GL_LINK_STATUS):
            print( 'link error:' )
            print( glGetProgramInfoLog(program) )

        glGenVertexArrays(1, vao)
        glBindVertexArray(vao)


    def display(self):
        global texture
        global program

        currentTime = time.time()

        green = [ 0.0, 0.25, 0.0, 1.0 ]
        glClearBufferfv(GL_COLOR, 0, green)

        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, texture)
        glUseProgram(program)
        glViewport(0, 0, self.width, self.height)
        glUniform1f(0, exposure)
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)

        overlay.clear()
        buffer = ("Exposure = %2.2f (Numpad +/- to change)" % exposure)
        overlay.drawText(buffer, 0, 0)
        overlay.draw()

        checkGLError()

        glutSwapBuffers()

    def reshape(self, width, height):
        self.width = width
        self.height = height

    def keyboard(self, key, x, y ):
        global fullscreen
        global exposure

        print ('key:' , key)
        if key == b'\x1b': # ESC
            sys.exit()

        elif key == b'f' or key == b'F': #fullscreen toggle
            if (fullscreen == True):
                glutReshapeWindow(512, 512)
                glutPositionWindow(int((1360/2)-(512/2)), int((768/2)-(512/2)))
                fullscreen = False
            else:
                glutFullScreen()
                fullscreen = True
        elif key == b'+':
            exposure *= 1.1
        elif key == b'-':
            exposure /= 1.1

    def init(self):
        pass

    def timer(self, blah):
        glutPostRedisplay()
        glutTimerFunc( int(1/60), self.timer, 0)
        time.sleep(1/60.0)

if __name__ == '__main__':
    glutInit()
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
    glutInitWindowSize(512, 512)
    w1 = glutCreateWindow('OpenGL SuperBible - HDR Exposure')
    glutInitWindowPosition(int((1360/2)-(512/2)), int((768/2)-(512/2)))
    fullscreen = False
    #glutFullScreen()
    scene = Scene(512,512)
    glutReshapeFunc(scene.reshape)
    glutDisplayFunc(scene.display)
    glutKeyboardFunc(scene.keyboard)
    glutIdleFunc(scene.display)
    #glutTimerFunc( int(1/60), scene.timer, 0)
    scene.init()
    glutMainLoop()

电流输出:

在此处输入图片说明

我在更新片段着色器之前正在获取: 在此处输入图片说明

任何帮助表示赞赏。谢谢。

查看更多

查看更多

提问者
Stan S.
被浏览
83
Rabbid76 2019-07-04 05:46

结果exp(0.0)为1.0,因此结果1.0-exp(0.0)为0.0。
您必须确保统一exposure值不是0.0,以使表达式的结果大于0.0:

c.xyz = vec3(1.0) - exp(-c.xyz * exposure);

纹理数据的类型为float在初始化纹理图像之前,使用字节数组中numpy.array的元素类型创建numpy.float32

for i in range(0, h.miplevels):

    if h.gltype == GL_FLOAT:

        float_data = np.frombuffer(data[ptr:], dtype=np.float32)
        glTexSubImage2D(GL_TEXTURE_2D, i, 0, 0, width, height, h.glformat, h.gltype, float_data)

    else: # h.type == GL_UNSIGNED_BYTE

        glTexSubImage2D(GL_TEXTURE_2D, i, 0, 0, width, height, h.glformat, h.gltype, data[ptr:])

    ptr += height * calculate_stride(h, width, 1)

请注意,您必须为不同的类型实现不同的情况。