wglGetProcAddress() を自分でなんとかしないといけない局面があり glext.hから一連の処理を自動生成するrubyを書いた。
GLEXT_PATH, EXT_FUNCTION の定義は外で。
# glext.hで宣言されている関数群を {関数名, 宣言文} のHashにする
glextFunctions = File.read(GLEXT_PATH) \
.split("\n") \
.select{|line| line.match(/GLAPI \S+ \*?APIENTRY gl\S+/)} \
.map{|api| [api.match(/APIENTRY (\S+) /)[1] , api] } \
.to_h
data = []
initData = []
initData << "inline bool initGLExtensionProcAddress()"
initData << "{"
initData << " return"
EXT_FUNCTION.each do |funcName|
unless glextFunctions.key?(funcName)
puts "!!!! not found function -- #{funcName} !!!!"
exit
end
funcDecl = glextFunctions[funcName]
funcPointer = "wglProcAddress_#{funcName}"
funcType = "PFN#{funcName.upcase}PROC"
returnType = funcDecl.match(/GLAPI (\S+ \*?)APIENTRY/)[1]
argDecl = funcDecl.match(/\(([^\)]+)\)/)[1]
args = argDecl.split(',').map{|arg| arg.match(/\*?([a-zA-Z0-9]+)$/)[1]}.join(',')
args = "" if args == "void"
data << <<-CODE
static #{funcType} #{funcPointer} = NULL;
inline #{returnType} APIENTRY #{funcName}( #{argDecl} ){
return (*#{funcPointer})( #{args} );
}
CODE
initData << " ( #{funcPointer} = "
initData << " (<%=funcType%>)wglGetProcAddress(\"#{funcName}\") ) != NULL &&"
end
initData << " true;"
initData << "}"
File.write("glextension.h", data.join("\n") + "\n" + initData.join("\n"))
↓みたいなヘッダーを、EXT_FUNCTIONで設定しただけ吐く。
static PFNGLGENBUFFERSPROC wglProcAddress_glGenBuffers = NULL;
inline void APIENTRY glGenBuffers( GLsizei n, GLuint *buffers ){
return (*wglProcAddress_glGenBuffers)( n,buffers );
}
inline bool initGLExtensionProcAddress()
{
return
( wglProcAddress_glGenBuffers =
(<%=funcType%>)wglGetProcAddress("glGenBuffers") ) != NULL &&
true;
}
もっとrubyうまくなりたい。