相对简单的程序绘制一个空白屏幕。从Superbible Opengl第7版移植。
该程序当前正在绘制空白屏幕。尽管textoverlay可以正常工作。
更新:添加了使用glGetError
来添加其他错误检查的功能。虽然没有错误产生。但是仍然是黑屏。
更新和成功:该程序现在可以完美渲染hdr图像。感谢Rabbid76出色的回答。这也是需要修复的ktxloader。谢谢。
预期输出为:
移植自: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()
当前输出:
感谢您的帮助。谢谢。
答案 0 :(得分:1)
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.float32
的{{3}}:
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)
请注意,您必须针对不同的类型实施不同的案例。