219 lines
6.1 KiB
Python
Executable file
219 lines
6.1 KiB
Python
Executable file
import ctypes
|
|
from OpenGL.GL import *
|
|
try:
|
|
import OpenGL.raw.GL
|
|
raw = OpenGL.raw
|
|
except ImportError:
|
|
pass
|
|
from OpenGL.arrays import GLintArray, GLcharArray, GLsizeiArray, GLcharARBArray
|
|
import sys
|
|
import gamedata
|
|
|
|
|
|
class shader_manager(object):
|
|
def __init__(self):
|
|
# Fixed Pipeline is always zero
|
|
self.shaderlib = {'ffp': 0}
|
|
self.shaderprograms = {}
|
|
|
|
self.initshadersources = []
|
|
self.initmode = 'auto'
|
|
self.initialized = False
|
|
|
|
def use_gl2_shaders(self):
|
|
self.funcs = {
|
|
'create': glCreateShader,
|
|
'source': glShaderSource,
|
|
'compile': glCompileShader,
|
|
'program': glCreateProgram,
|
|
'attach': glAttachShader,
|
|
'link': glLinkProgram,
|
|
'use': glUseProgram,
|
|
'param': glGetShaderiv,
|
|
'uniform': glUniform4f,
|
|
'arraytype': GLcharArray
|
|
}
|
|
def use_raw_shaders(self):
|
|
self.funcs = {
|
|
'create': raw.GL.glCreateShader,
|
|
'source': raw.GL.glShaderSource,
|
|
'compile': raw.GL.glCompileShader,
|
|
'program': raw.GL.glCreateProgram,
|
|
'attach': raw.GL.glAttachShader,
|
|
'link': raw.GL.glLinkProgram,
|
|
'use': raw.GL.glUseProgram,
|
|
'param': raw.GL.glGetShaderiv
|
|
}
|
|
|
|
def use_arb_shaders(self):
|
|
from OpenGL.GL.ARB import shader_objects
|
|
if not shader_objects.glInitShaderObjectsARB():
|
|
raise RuntimeError("ARB Shaders failed to initialize")
|
|
|
|
self.funcs = {
|
|
'create': shader_objects.glCreateShaderObjectARB,
|
|
'source': shader_objects.glShaderSourceARB,
|
|
'compile': shader_objects.glCompileShaderARB,
|
|
'program': shader_objects.glCreateProgramObjectARB,
|
|
'attach': shader_objects.glAttachObjectARB,
|
|
'link': shader_objects.glLinkProgramARB,
|
|
'use': shader_objects.glUseProgramObjectARB,
|
|
'uniform': shader_objects.glUniform4fARB,
|
|
'param': shader_objects.glGetObjectParameterivARB
|
|
}
|
|
def use_arb_new_shaders(self):
|
|
from OpenGL.GL.ARB import shader_objects_new
|
|
shader_objects = shader_objects_new
|
|
if not shader_objects.glInitShaderObjectsARB():
|
|
raise RuntimeError("ARB New Shaders failed to initialize")
|
|
|
|
self.funcs = {
|
|
'create': shader_objects.glCreateShaderObjectARB,
|
|
'source': shader_objects.base_glShaderSourceARB,
|
|
'compile': shader_objects.glCompileShaderARB,
|
|
'program': shader_objects.glCreateProgramObjectARB,
|
|
'attach': shader_objects.glAttachObjectARB,
|
|
'link': shader_objects.glLinkProgramARB,
|
|
'use': shader_objects.glUseProgramObjectARB,
|
|
'param': shader_objects.glGetObjectParameterivARB,
|
|
'arraytype': GLcharARBArray
|
|
}
|
|
|
|
def init_gl(self):
|
|
if self.initialized:
|
|
return
|
|
|
|
self.initialized = True
|
|
import files
|
|
#print glGetString(GL_EXTENSIONS)
|
|
if True:
|
|
self.use_gl2_shaders()
|
|
else:
|
|
self.use_arb_shaders()
|
|
#self.use_gl2_shaders()
|
|
|
|
for name, vertex, fragment in self.initshadersources:
|
|
vf = files.mgr.open('shaders/%s.vert' % (vertex,))
|
|
ff = files.mgr.open('shaders/%s.frag' % (fragment,))
|
|
vs = self.funcs['create'](GL_VERTEX_SHADER)
|
|
fs = self.funcs['create'](GL_FRAGMENT_SHADER)
|
|
self.funcs['source'](vs, vf.read())
|
|
self.funcs['source'](fs, ff.read())
|
|
rv = self.funcs['compile'](vs)
|
|
rv = self.funcs['compile'](fs)
|
|
sp = self.funcs['program']()
|
|
self.funcs['attach'](sp, vs)
|
|
self.funcs['attach'](sp, fs)
|
|
rv = self.funcs['link'](sp)
|
|
self.shaderlib[name] = sp
|
|
self.shaderprograms[name] = (vs, fs)
|
|
|
|
def detect(self):
|
|
shaderlist = [
|
|
('GL2', self.use_gl2_shaders),
|
|
('ARB', self.use_arb_shaders),
|
|
('ARBNEW', self.use_arb_new_shaders),
|
|
('RAW', self.use_raw_shaders)
|
|
]
|
|
|
|
workable_shaders = []
|
|
|
|
for shadername, shaderinit in shaderlist:
|
|
try:
|
|
shaderinit()
|
|
except:
|
|
print(("Shader type %s failed to initialize" % (shadername,)))
|
|
continue
|
|
try:
|
|
self.select("ffp")
|
|
except:
|
|
print(("Shader type %s failed to access the fixed function pipeline" % (shadername,)))
|
|
continue
|
|
try:
|
|
self.select("standard")
|
|
except:
|
|
print(("Shader type %s failed to load the \"standard\" vertex and fragment shaders" % (shadername,)))
|
|
continue
|
|
|
|
workable_shaders.append(shadername)
|
|
|
|
return workable_shaders
|
|
|
|
def autoinit(self):
|
|
shadertypes = self.detect()
|
|
|
|
if not shadertypes:
|
|
raise ValueError("No working shaders detected")
|
|
|
|
self.init_shadertype(shadertypes[0])
|
|
|
|
def init_shadertype(self, shadertype):
|
|
if shadertype == "GL2":
|
|
self.use_gl2_shaders()
|
|
elif shadertype == "ARB":
|
|
self.use_arb_shaders()
|
|
elif shadertype == "ARBNEW":
|
|
self.use_arb_new_shaders()
|
|
elif shadertype == "RAW":
|
|
self.use_raw_shaders()
|
|
|
|
|
|
|
|
def select(self, shader):
|
|
if self.initshadersources:
|
|
self.init_gl()
|
|
self.initshadersources = []
|
|
if not shader in self.shaderlib:
|
|
self.funcs['use'](0)
|
|
return True
|
|
try:
|
|
self.funcs['use'](self.shaderlib[shader])
|
|
except GLError:
|
|
p = self.shaderlib[shader]
|
|
v, f = self.shaderprograms[shader]
|
|
print(("Shader failed to execute: %s" % (shader,)))
|
|
print("Vertex shader log:")
|
|
lenarr = GLintArray.zeros(1)
|
|
glGetShaderiv(v, GL_INFO_LOG_LENGTH, lenarr)
|
|
infoarr = GLcharArray.zeros(lenarr[0])
|
|
outsize = GLsizeiArray.zeros(1)
|
|
glGetShaderInfoLog(v, lenarr[0], outsize, infoarr)
|
|
print((''.join([chr(x) for x in infoarr[:outsize[0]]])))
|
|
print("Fragment shader log:")
|
|
lenarr = GLintArray.zeros(1)
|
|
glGetShaderiv(f, GL_INFO_LOG_LENGTH, lenarr)
|
|
infoarr = GLcharArray.zeros(lenarr[0])
|
|
outsize = GLsizeiArray.zeros(1)
|
|
glGetShaderInfoLog(f, lenarr[0], outsize, infoarr)
|
|
print((''.join([chr(x) for x in infoarr[:outsize[0]]])))
|
|
print("Program info log:")
|
|
lenarr = GLintArray.zeros(1)
|
|
glGetProgramiv(p, GL_INFO_LOG_LENGTH, lenarr)
|
|
infoarr = GLcharArray.zeros(lenarr[0])
|
|
outsize = GLsizeiArray.zeros(1)
|
|
glGetProgramInfoLog(p, lenarr[0], outsize, infoarr)
|
|
print((''.join([chr(x) for x in infoarr[:outsize[0]]])))
|
|
glDeleteShader(v)
|
|
glDeleteShader(f)
|
|
glDeleteProgram(p)
|
|
del self.shaderprograms[shader]
|
|
del self.shaderlib[shader]
|
|
glUseProgram(0)
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
def load(self):
|
|
shader_data = gamedata.get('shaders')
|
|
self.load_shaders(shader_data)
|
|
|
|
def load_shaders(self, shaders):
|
|
for shader in shaders.shader:
|
|
self.initshadersources.append((shader['id'], shader['vertex'], shader['fragment']))
|
|
|
|
def init():
|
|
global mgr
|
|
mgr = shader_manager()
|
|
|
|
mgr = None
|