Select Git revision
BP_RWTHVRPawn_Base.uasset
Create_openGL_mock.py 25.08 KiB
#------------------------------------------------------------------------------
# Project Phoenix
#
# Copyright (c) 2017-2018 RWTH Aachen University, Germany,
# Virtual Reality & Immersive Visualization Group.
#------------------------------------------------------------------------------
# License
#
# Licensed under the 3-Clause BSD License (the "License");
# you may not use this file except in compliance with the License.
# See the file LICENSE for the full text.
# You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#------------------------------------------------------------------------------
import sys, getopt
#functions you want to mock should be put in this list
functions_to_mock = ['__glewBindAttribLocation',
'__glewBindBuffer', '__glewBindBufferBase',
'__glewBindBufferRange', '__glewBindFragDataLocation',
'__glewBindFragDataLocationIndexed',
'__glewBindFramebuffer', '__glewBindRenderbuffer',
'__glewBlitNamedFramebuffer',
'__glewCheckNamedFramebufferStatus', '__glewClampColor',
'__glewClearDepthf', '__glewClearNamedBufferData',
'__glewClearNamedBufferSubData',
'__glewClearNamedFramebufferfi',
'__glewClearNamedFramebufferfv',
'__glewClearNamedFramebufferiv',
'__glewClearNamedFramebufferuiv', '__glewClientWaitSync',
'__glewColorMaski', '__glewCopyImageSubData',
'__glewCopyNamedBufferSubData', '__glewCreateFramebuffers',
'__glewCreateRenderbuffers', '__glewCreateShaderProgramv',
'__glewCreateTextures', '__glewDebugMessageControl',
'__glewDebugMessageInsert', '__glewDeleteBuffers',
'__glewDeleteFramebuffers', '__glewDeleteProgram',
'__glewDeleteRenderbuffers', '__glewDeleteShader',
'__glewDeleteSync', '__glewDeleteVertexArrays',
'__glewDepthRangef', '__glewDepthRangeIndexed',
'__glewDetachShader', '__glewDisableVertexArrayAttrib',
'__glewFenceSync', '__glewFlushMappedNamedBufferRange',
'__glewGenerateTextureMipmap',
'__glewGetActiveAtomicCounterBufferiv',
'__glewGetActiveAttrib', '__glewGetActiveSubroutineName',
'__glewGetActiveSubroutineUniformiv',
'__glewGetActiveSubroutineUniformName',
'__glewGetActiveUniform', '__glewGetActiveUniformBlockiv',
'__glewGetActiveUniformBlockName',
'__glewGetActiveUniformName', '__glewGetActiveUniformsiv',
'__glewGetAttachedShaders', '__glewGetAttribLocation',
'__glewGetDebugMessageLog', '__glewGetFragDataIndex',
'__glewGetFragDataLocation',
'__glewGetGraphicsResetStatus',
'__glewGetInternalformati64v', '__glewGetInternalformativ',
'__glewGetNamedBufferParameteri64v',
'__glewGetNamedBufferParameteriv',
'__glewGetNamedBufferPointerv',
'__glewGetNamedBufferSubData',
'__glewGetNamedFramebufferAttachmentParameteriv',
'__glewGetNamedFramebufferParameteriv',
'__glewGetNamedRenderbufferParameteriv',
'__glewGetObjectPtrLabel', '__glewGetProgramInterfaceiv',
'__glewGetProgramResourceIndex',
'__glewGetProgramResourceiv',
'__glewGetProgramResourceLocation',
'__glewGetProgramResourceLocationIndex',
'__glewGetProgramResourceName', '__glewGetProgramStageiv',
'__glewGetShaderInfoLog', '__glewGetShaderiv',
'__glewGetShaderSource', '__glewGetSubroutineIndex',
'__glewGetSubroutineUniformLocation', '__glewGetSynciv',
'__glewGetTextureHandleARB',
'__glewGetTransformFeedbackVarying',
'__glewGetUniformBlockIndex', '__glewGetUniformdv',
'__glewGetUniformfv', '__glewGetUniformIndices',
'__glewGetUniformiv', '__glewGetUniformSubroutineuiv',
'__glewGetUniformuiv', '__glewGetVertexArrayIndexed64iv',
'__glewGetVertexArrayIndexediv', '__glewGetVertexArrayiv',
'__glewInvalidateBufferData',
'__glewInvalidateBufferSubData',
'__glewInvalidateNamedFramebufferData',
'__glewInvalidateNamedFramebufferSubData',
'__glewIsFramebuffer', '__glewIsImageHandleResidentARB',
'__glewIsRenderbuffer', '__glewIsShader', '__glewIsSync',
'__glewIsTextureHandleResidentARB',
'__glewMakeImageHandleNonResidentARB',
'__glewMakeImageHandleResidentARB',
'__glewMakeTextureHandleNonResidentARB',
'__glewMakeTextureHandleResidentARB',
'__glewMapNamedBuffer', '__glewMapNamedBufferRange',
'__glewNamedBufferStorage', '__glewNamedBufferSubData',
'__glewNamedFramebufferDrawBuffer',
'__glewNamedFramebufferDrawBuffers',
'__glewNamedFramebufferParameteri',
'__glewNamedFramebufferReadBuffer',
'__glewNamedFramebufferRenderbuffer',
'__glewNamedFramebufferTexture',
'__glewNamedRenderbufferStorage',
'__glewNamedRenderbufferStorageMultisample',
'__glewObjectPtrLabel', '__glewPopDebugGroup',
'__glewProgramParameteri', '__glewProgramUniform1d',
'__glewProgramUniform1dv', '__glewProgramUniform1f',
'__glewProgramUniform1fv', '__glewProgramUniform1i',
'__glewProgramUniform1iv', '__glewProgramUniform1ui',
'__glewProgramUniform1uiv', '__glewProgramUniform2d',
'__glewProgramUniform2dv', '__glewProgramUniform2f',
'__glewProgramUniform2fv', '__glewProgramUniform2i',
'__glewProgramUniform2iv', '__glewProgramUniform2ui',
'__glewProgramUniform2uiv', '__glewProgramUniform3d',
'__glewProgramUniform3dv', '__glewProgramUniform3f',
'__glewProgramUniform3i', '__glewProgramUniform3iv',
'__glewProgramUniform3ui', '__glewProgramUniform3uiv',
'__glewProgramUniform4d', '__glewProgramUniform4dv',
'__glewProgramUniform4f', '__glewProgramUniform4fv',
'__glewProgramUniform4i', '__glewProgramUniform4iv',
'__glewProgramUniform4ui', '__glewProgramUniform4uiv',
'__glewProgramUniformHandleui64ARB',
'__glewProgramUniformHandleui64vARB',
'__glewProgramUniformMatrix2dv',
'__glewProgramUniformMatrix2fv',
'__glewProgramUniformMatrix2x3dv',
'__glewProgramUniformMatrix2x3fv',
'__glewProgramUniformMatrix2x4dv',
'__glewProgramUniformMatrix2x4fv',
'__glewProgramUniformMatrix3dv',
'__glewProgramUniformMatrix3fv',
'__glewProgramUniformMatrix3x2dv',
'__glewProgramUniformMatrix3x2fv',
'__glewProgramUniformMatrix3x4dv',
'__glewProgramUniformMatrix3x4fv',
'__glewProgramUniformMatrix4dv',
'__glewProgramUniformMatrix4x2dv',
'__glewProgramUniformMatrix4x2fv',
'__glewProgramUniformMatrix4x3dv',
'__glewProgramUniformMatrix4x3fv', '__glewPushDebugGroup',
'__glewReleaseShaderCompiler', '__glewShaderBinary',
'__glewShaderStorageBlockBinding',
'__glewSpecializeShader', '__glewStencilMaskSeparate',
'__glewTextureParameteri', '__glewTextureStorage2D',
'__glewTextureStorage3D', '__glewTextureSubImage2D',
'__glewTextureSubImage3D',
'__glewTransformFeedbackVaryings',
'__glewUniformBlockBinding', '__glewUniformSubroutinesuiv',
'__glewUnmapNamedBuffer', '__glewValidateProgram',
'__glewVertexArrayAttribBinding',
'__glewVertexArrayAttribIFormat',
'__glewVertexArrayAttribLFormat',
'__glewVertexArrayBindingDivisor',
'__glewViewportIndexedf', '__glewWaitSync',
'glAttachShader', 'glBindTexture', 'glBindVertexArray',
'glClear', 'glClearColor', 'glClearDepth',
'glClearStencil', 'glColorMask', 'glCompileShader',
'glCreateBuffers', 'glCreateProgram', 'glCreateShader',
'glCreateVertexArrays', 'glDebugMessageCallback',
'glDeleteTextures', 'glDepthMask', 'glDepthRange',
'glDisable', 'glDrawArrays', 'glDrawElements', 'glEnable',
'glEnableVertexArrayAttrib', 'glFinish', 'glFlush',
'glGetError', 'glGetIntegerv', 'glGetPointerv',
'glGetProgramInfoLog', 'glGetProgramiv',
'glGetUniformLocation', 'glIsBuffer', 'glIsEnabled',
'glIsProgram', 'glIsTexture', 'glIsVertexArray',
'glLinkProgram', 'glNamedBufferData', 'glPolygonMode',
'glProgramUniform3fv', 'glProgramUniformMatrix4fv',
'glReadPixels', 'glShaderSource', 'glUniform1f',
'glUniform3fv', 'glUniformMatrix4fv', 'glUseProgram',
'glVertexArrayAttribFormat', 'glVertexArrayElementBuffer',
'glVertexArrayVertexBuffer', 'glViewport']
#allow calls you want to provide and not be auto generated
allow_calls_provided = ['ALLOW_CALL(open_gl_mock,glewInit()).RETURN(GLEW_OK);',
'ALLOW_CALL(open_gl_mock,glCheckNamedFramebufferStatus(gt(0u),_)).RETURN(GL_FRAMEBUFFER_COMPLETE);',
'ALLOW_CALL(open_gl_mock,glCompileShader(gt(0u)));',
'ALLOW_CALL(open_gl_mock,glCreateBuffers(1,_)).SIDE_EFFECT(*_2=1);',
'ALLOW_CALL(open_gl_mock,glCreateProgram()).RETURN(1u);',
'ALLOW_CALL(open_gl_mock,glCreateShader(_)).RETURN(1u);''ALLOW_CALL(open_gl_mock,glAttachShader(gt(0u),gt(0u)));',
'ALLOW_CALL(open_gl_mock,glCreateVertexArrays(0,_));',
'ALLOW_CALL(open_gl_mock,glCreateVertexArrays(1,_)).SIDE_EFFECT(*_2=1);',
'ALLOW_CALL(open_gl_mock,glGetProgramInfoLog(_,_,_,_)).SIDE_EFFECT(*_3=0);',
'ALLOW_CALL(open_gl_mock,glGetProgramiv(_,_,_)).SIDE_EFFECT(*_3=GL_TRUE);',
'ALLOW_CALL(open_gl_mock,glIsBuffer(0u)).RETURN(false);',
'ALLOW_CALL(open_gl_mock,glIsBuffer(gt(0u))).RETURN(true);',
'ALLOW_CALL(open_gl_mock,glIsFramebuffer(gt(0u))).RETURN(true);',
'ALLOW_CALL(open_gl_mock,glIsProgram(0u)).RETURN(false);',
'ALLOW_CALL(open_gl_mock,glIsProgram(gt(0u))).RETURN(true);',
'ALLOW_CALL(open_gl_mock,glIsVertexArray(0u)).RETURN(false);',
'ALLOW_CALL(open_gl_mock,glIsVertexArray(gt(0u))).RETURN(true);',
'ALLOW_CALL(open_gl_mock,glLinkProgram(gt(0u)));']
gl_types = ['GLbitfield', 'GLboolean', 'GLbyte', 'GLchar',
'GLcharARB', 'GLclampd', 'GLclampf', 'GLclampx', 'GLDEBUGPROC',
'GLDEBUGPROCAMD', 'GLDEBUGPROCARB', 'GLdouble',
'GLeglClientBufferEXT', 'GLenum', 'GLfixed', 'GLfloat', 'GLhalf',
'GLhandleARB', 'GLint', 'GLint64', 'GLint64EXT', 'GLintptr',
'GLintptrARB', 'GLLOGPROCREGAL', 'GLshort', 'GLsizei', 'GLsizeiptr',
'GLsizeiptrARB', 'GLsync', 'GLubyte', 'GLuint', 'GLuint64',
'GLuint64EXT', 'GLushort', 'GLvdpauSurfaceNV',
'GLvoid','cl_context','cl_event','void']
functions = []
glew_header_path = ""
mock_path = ""
template_path = ""
class Function_Type:
return_type = "void"
param_types = ""
type_name = "unknown"
function_name = "unknown"
def Sanity_Check(self):
if self.param_types == "void":
self.param_types = ""
if "string" in self.param_types:
#some of the paramteres are named with keyword string
self.param_types= self.param_types.replace("string", "string_arg")
def GetNrParams(self):
if len(self.param_types.strip())==0:
return 0
return 1 + self.param_types.count(',')
def GetGlName(self):
if self.function_name.startswith("__glew"):
return "gl"+self.function_name[6:]
elif self.type_name == "glFunction":
return self.function_name
def GetParamsWithoutTypes(self):
params = self.param_types
params = params.replace('*',' ')
params = params.replace('&',' ')
params = params.replace('[',' ')
params = params.replace(']',' ')
params = params.replace('const','')
for gl_type in gl_types:
params = params.replace(gl_type+' ',' ')
#we need to remove numbers from types but not from variable names
changed_something = True
while changed_something:
changed_something = False
for x in range(0,10):
length = len(params)
params = params.replace(' '+str(x),' ')
if len(params) != length:
changed_something = True
return params
def default_return(self):
ret_type = self.return_type.strip()
if ret_type == "GLint":
return ".RETURN(0)"
elif ret_type == "GLboolean":
return ".RETURN(false)"
elif ret_type == "void*" or ret_type == "void *" or ret_type == "const void *":
return ".RETURN(nullptr)"
elif ret_type == "GLuint":
return ".RETURN(0u)"
elif ret_type == "const GLubyte*":
return ".RETURN(nullptr)"
elif ret_type == "GLenum":
return ".RETURN(GL_FALSE)"
elif ret_type == "GLsync":
return ".RETURN(nullptr)"
elif ret_type == "GLuint64":
return ".RETURN(0)"
elif ret_type == "GLuint64":
return ".RETURN(0u)"
elif ret_type == "GLhandleARB":
return ".RETURN(0)"
elif ret_type == "GLintptr":
return ".RETURN(NULL)"
elif ret_type == "GLsizei":
return ".RETURN(0u)"
elif ret_type == "GLushort":
return ".RETURN(static_cast<GLushort>(0u))"
elif ret_type == "GLsizei":
return ".RETURN(0u)"
elif ret_type == "GLVULKANPROCNV":
return ".RETURN([](){return;})"
elif ret_type == "GLfloat":
return ".RETURN(0.0f)"
elif ret_type == "GLvdpauSurfaceNV":
return ".RETURN(0u)"
elif ret_type == "const GLchar*":
return ".RETURN(nullptr)"
elif ret_type == "const GLubyte *":
return ".RETURN(nullptr)"
elif ret_type == "void":
return ""
else:
print "unspecified default return for return_type: "+ret_type
return ""
def Write_Autogeneration_Warning(file):
file.write("//WARNING: This file is autogenerated, DO NOT CHANGE IT, but the template!\n")
def Write_Mock_Definitions(header_file):
for function in functions:
line = " MAKE_MOCK" + str(function.GetNrParams()) +"("+ function.GetGlName() + ", " + function.return_type + " ("+function.param_types+"));\n"
header_file.write(line)
def Write_ALLOW_CALLS(header_file):
line = "#define OPENGL_MOCK_ALLOW_ANY_CALL\\\n"
for allow_call in allow_calls_provided:
line += " " + allow_call + "\\\n"
for function in functions:
allow_call_was_provided = False
for allow_call in allow_calls_provided:
if function.GetGlName()+"(" in allow_call:
allow_call_was_provided = True
if not allow_call_was_provided:
line = line + " ALLOW_CALL(open_gl_mock, " + function.GetGlName() + "("
nrParams = function.GetNrParams()
for x in range(1, nrParams+1):
line = line +"_"
if not x==nrParams:
line = line +","
line = line + "))"
line = line + function.default_return()
line = line + ";\\\n"
line = line + " \n"
header_file.write(line)
def Write_Method_Definitions(source_file):
for function in functions:
if function.type_name == "glFunction":
line = function.return_type + function.function_name +"(" + function.param_types + "){\n"
else:
line = function.return_type + function.function_name +"_mock(" + function.param_types + "){\n"
if function.return_type.strip() != "void":
line = line + " return"
line = line + " open_gl_mock." + function.GetGlName() + "(" + function.GetParamsWithoutTypes() +");\n"
line = line + "}\n"
if function.type_name != "glFunction":
line = line + function.return_type + " (*" + function.function_name +")(" + function.param_types + ") = " + function.function_name +"_mock; \n"
line = line + "\n"
source_file.write(line)
def Write_Header():
header_template = open(template_path+'opengl_mock_template.hpp')
header_file = open(mock_path+'opengl_mock.hpp', 'w')
template_lines = header_template.readlines()
for line in template_lines:
if "<MOCK_DEFINITION>" in line:
Write_Mock_Definitions(header_file)
elif "<ALLOW_CALL_DEFINITION>" in line:
Write_ALLOW_CALLS(header_file)
elif "<AUTO_GENERATION_WARNING>" in line:
Write_Autogeneration_Warning(header_file)
else:
header_file.write(line)
header_file.close()
def Write_Source():
source_template = open(template_path+'opengl_mock_template.cpp')
source_file = open(mock_path+'opengl_mock.cpp', 'w')
template_lines = source_template.readlines()
for line in template_lines:
if "<__GLEW_METHODS>" in line:
Write_Method_Definitions(source_file)
elif "<AUTO_GENERATION_WARNING>" in line:
Write_Autogeneration_Warning(source_file)
else:
source_file.write(line)
source_file.close()
def Store_Function_Type(line):
function_type = Function_Type()
if not line.startswith("typedef "):
print line + " cannot be parsed, it does not start with typedef"
line = line[8:]
bracket_pos = line.find("(")
function_type.return_type = line[:bracket_pos]
line = line[bracket_pos+1:]
name_pos = line.find("PFNGL")
bracket_pos2 = line.find(")")
function_type.type_name = line[name_pos:bracket_pos2]
bracket_pos = line.find("(")
line = line[bracket_pos+1:]
bracket_pos2 = line.find(")")
function_type.param_types = line[:bracket_pos2]
functions.append(function_type)
def Store_Glew_Function(line):
if not "PFNGL" in line:
print line + " cannot be parsed, it does not contain PFNGL"
line = line[line.find("PFNGL"):]
typename = line[:line.find(" ")]
__glew_pos = line.find("__glew")
end_pos = line.find(";")
line = line[__glew_pos:end_pos]
for function in functions:
if function.type_name == typename:
if not function.function_name == "unknown":
print "For function_type "+function.type_name + " the function name was already set to " + function.function_name + " so it cannot be set to: " + line
function.function_name = line
return
print "For function_type "+typename + " of function " + line + " no typedef can be found"
def Store_GL_Function(line):
if not "GLAPIENTRY" in line:
print line + " cannot be parsed, it does notcontain GLAPIENTRY"
function = Function_Type()
line = line[line.find(" "):]
function.return_type = line[:line.find("GLAPIENTRY")]
line = line[line.find("GLAPIENTRY")+11:]
function.function_name = line[:line.find(" ")]
function.param_types = line[line.find("(")+1:line.find(")")]
function.type_name = "glFunction"
functions.append(function)
def Read_GLEW_methods():
glew_header = open(glew_header_path)
for line in glew_header.readlines():
if "PFNGL" in line and "typedef" in line:
Store_Function_Type(line)
elif line.startswith("GLEW_FUN_EXPORT"):
Store_Glew_Function(line)
elif line.startswith("GLAPI"):
Store_GL_Function(line)
def Filter_GLEW_methods():
print "we delete methods that have mote than 15 parameters since trompeloeil has no mock macro for it"
i = 0
n = len(functions)
while i < n:
function = functions[i]
function.Sanity_Check()
keep_it = True
if function.GetNrParams() >= 16:
#print "Removed mock for function "+function.GetGlName()+", because it has more than 15 parameters and trompeloeil has no mock macro for it"
keep_it = False
if keep_it:
keep_it = False
if function.GetGlName() in functions_to_mock:
keep_it = True
functions_to_mock.remove(function.GetGlName())
#print "Added function: "+function.GetGlName()
if function.function_name in functions_to_mock:
keep_it = True
functions_to_mock.remove(function.function_name)
#print "Added function: "+function.GetGlName()
if keep_it:
i = i + 1
else:
del functions[i]
n = n - 1
if(len(functions_to_mock)>0):
print "OpenGL Mock generation: WARNING We did not find "+str(len(functions_to_mock))+" functions. Namely:"
for function in functions_to_mock:
print " missed "+function
else:
print "OpenGL Mock generation: Success!"
def Extract_Function_Names_From_Error(error_string):
output = ""
while "__imp_" in error_string:
next_imp_pos = error_string.find("__imp_")
error_string = error_string[next_imp_pos+6:]
function_name = error_string[:error_string.find(" ")]
output += "'" + function_name + "', "
print output
def CleanUpGlewPath():
#the glew_header_path is given as gernerator expression, just takte the first on
global glew_header_path
#print "glew_header: "+glew_header_path
if "$<$<CONFIG:Release>:>;" in glew_header_path:
#the include path it at the start
first = glew_header_path.find(";$<$<CONFIG:")
glew_header_path = glew_header_path[:first]
else:
#the include path is within the generator expression
first = glew_header_path.find(">:")
glew_header_path = glew_header_path[first+2:]
end = glew_header_path.find(">")
glew_header_path = glew_header_path[:end]
#print "header afterwards: "+glew_header_path
glew_header_path += "/GL/glew.h"
def ParseArgs(argv):
global glew_header_path
global mock_path
global template_path
try:
opts, args = getopt.getopt(argv,"hg:m:t:",["glewHeaderPath=","mockPath=","templatePath"])
except getopt.GetoptError:
print "No arguments where given, please specify -g <path_to_glew.h> -m <path_where_opengl_mock.cpp/hpp_is_written> -t <path_to_templates>"
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print 'Create_openGL_mock.py -g <path_to_glew.h> -m <path_where_opengl_mock.cpp/hpp_is_written> -t <path_to_templates>'
sys.exit()
elif opt in ("-g", "--glewHeaderPath"):
glew_header_path = arg
elif opt in ("-m", "--mockPath"):
mock_path = arg
elif opt in ("-t", "--templatePath"):
template_path = arg
CleanUpGlewPath()
print 'glew_header_path is :"' + glew_header_path + '"'
print 'mock_path is :"' + mock_path + '"'
print 'template_path is :"' + template_path + '"'
def main():
Read_GLEW_methods()
Filter_GLEW_methods()
Write_Header()
Write_Source()
#if you need to pass an LNK2019 output, you can use this method (remove " and newlines)!
#linker_error_string = ' : error LNK2001: unresolved external symbol __imp___glewDeleteBuffers : error LNK2001: unresolved external symbol __imp___glewClearNamedBufferD'
#Extract_Function_Names_From_Error(linker_error_string)
print 'Auto-Generate OpenGl Mock:'
if __name__ == "__main__":
ParseArgs(sys.argv[1:])
main()