Created
October 22, 2015 16:25
-
-
Save PtrMan/7880dda96d050f053727 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Client.OpenGlContext; | |
import Client.opengl.gl; | |
import Client.opengl.glExt; | |
const bool WINDOWS = true; | |
// just for debugging | |
import std.stdio : writeln; | |
static if( WINDOWS ) | |
{ | |
import core.sys.windows.windows; | |
import std.c.string : memset; | |
import std.string; | |
// WINAPI | |
extern (Windows) | |
{ | |
int ChoosePixelFormat(HDC, PIXELFORMATDESCRIPTOR*); | |
BOOL SwapBuffers(HDC); | |
int DescribePixelFormat( | |
HDC hdc, | |
int iPixelFormat, | |
UINT nBytes, | |
PIXELFORMATDESCRIPTOR *ppfd | |
); | |
BOOL wglDeleteContext(HGLRC hglrc); | |
BOOL wglMakeCurrent(HDC hdc, HGLRC hglrc); | |
HDC wglGetCurrentDC(); | |
HGLRC wglCreateContext(HDC); | |
void *wglGetProcAddress(LPCSTR); | |
} | |
// WINAPI WinGdi.h | |
const uint PFD_DRAW_TO_WINDOW = 0x00000004; | |
const uint PFD_SUPPORT_OPENGL = 0x00000020; | |
const uint PFD_DOUBLEBUFFER = 0x00000001; | |
const uint PFD_TYPE_RGBA = 0; | |
const uint PFD_MAIN_PLANE = 0; | |
} | |
class OpenGlContext | |
{ | |
alias extern(Windows) void function(uint n, uint *framebuffers) TYPEGLGENFRAMEBUFFERSEXT; | |
alias extern(Windows) void function(uint n, uint *renderbuffers) TYPEGLGENRENDERBUFFERSEXT; | |
alias extern(Windows) void function(uint target, uint framebuffer) TYPEGLBINDFRAMEBUFFEREXT; | |
alias extern(Windows) void function(uint target, uint attachment, uint textarget, uint texture, int level) TYPEGLFRAMEBUFFERTEXTURE2DEXT; | |
alias extern(Windows) void function(uint target, uint renderbuffer) TYPEGLBINDRENDERBUFFEREXT; | |
alias extern(Windows) void function(uint target, uint internalformat, uint width, uint height) TYPEGLRENDERBUFFERSTORAGEEXT; | |
alias extern(Windows) void function(uint target, uint attachment, uint renderbuffertarget, uint renderbuffer) TYPEGLFRAMEBUFFERRENDERBUFFEREXT; | |
alias extern(Windows) uint function(uint target) TYPEGLCHECKFRAMEBUFFERSTATUSEXT; | |
public static TYPEGLGENFRAMEBUFFERSEXT glGenFramebuffersEXT; | |
public static TYPEGLGENRENDERBUFFERSEXT glGenRenderbuffersEXT; | |
public static TYPEGLBINDFRAMEBUFFEREXT glBindFramebufferEXT; | |
public static TYPEGLFRAMEBUFFERTEXTURE2DEXT glFramebufferTexture2DEXT; | |
public static TYPEGLBINDRENDERBUFFEREXT glBindRenderbufferEXT; | |
public static TYPEGLRENDERBUFFERSTORAGEEXT glRenderbufferStorageEXT; | |
public static TYPEGLFRAMEBUFFERRENDERBUFFEREXT glFramebufferRenderbufferEXT; | |
public static TYPEGLCHECKFRAMEBUFFERSTATUSEXT glCheckFramebufferStatusEXT; | |
/* | |
alias nothrow BOOL function(HGLRC hglrc) wglDeleteContextType; | |
alias nothrow BOOL function(HDC hdc, HGLRC hglrc) wglMakeCurrentType; | |
alias nothrow HDC function() wglGetCurrentDCType; | |
*/ | |
static if( WINDOWS ) | |
{ | |
private HDC Hdc; | |
private HWND Hwnd; | |
private HGLRC Glrc; | |
private HMODULE ModuleOpenGl; | |
/* | |
private static wglDeleteContextType wglDeleteContext; | |
private static wglMakeCurrentType wglMakeCurrent; | |
private static wglGetCurrentDCType wglGetCurrentDC; | |
*/ } | |
static if( WINDOWS ) | |
{ | |
bool initForWindows(HWND Hwnd) | |
{ | |
PIXELFORMATDESCRIPTOR PixelDescriptor; | |
int FormatInfo; | |
BOOL ReturnBOOL; | |
// get all addresses | |
string OpenGlDll = "opengl32.dll"; | |
string wglCreateContextStr = "wglCreateContext"; | |
string wglDeleteContextStr = "wglDeleteContext"; | |
string wglMakeCurrentStr = "wglMakeCurrent"; | |
string wglGetCurrentDCStr = "wglGetCurrentDC"; | |
/* | |
this.ModuleOpenGl = LoadLibraryA(cast(LPCSTR)(OpenGlDll.toStringz)); | |
if( this.ModuleOpenGl is null ) | |
{ | |
return false; | |
} | |
alias nothrow HGLRC function(HDC) wglCreateContextType; | |
wglCreateContextType wglCreateContext; | |
wglCreateContext = cast(wglCreateContextType)GetProcAddress(this.ModuleOpenGl, cast(LPCSTR)wglCreateContextStr.toStringz); | |
wglDeleteContext = cast(wglDeleteContextType)GetProcAddress(this.ModuleOpenGl, cast(LPCSTR)wglDeleteContextStr.toStringz); | |
wglMakeCurrent = cast(wglMakeCurrentType) GetProcAddress(this.ModuleOpenGl, cast(LPCSTR)wglMakeCurrentStr.toStringz); | |
wglGetCurrentDC = cast(wglGetCurrentDCType) GetProcAddress(this.ModuleOpenGl, cast(LPCSTR)wglGetCurrentDCStr.toStringz); | |
*/ | |
this.Hwnd = Hwnd; | |
this.Hdc = GetDC(Hwnd); | |
if( this.Hdc is null ) | |
{ | |
return false; | |
} | |
// enumerate | |
/* | |
PixelDescriptor.nSize = PIXELFORMATDESCRIPTOR.sizeof; | |
uint NumFormats = DescribePixelFormat( this.Hdc, 1, 0, null); | |
for( int i = 1; i <= NumFormats; i++ ) | |
{ | |
DescribePixelFormat(this.Hdc, i, PixelDescriptor.nSize, &PixelDescriptor ); | |
if ( (PixelDescriptor.dwFlags & ( PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER ) ) == (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER) && | |
PixelDescriptor.iPixelType == PFD_TYPE_RGBA && PixelDescriptor.iLayerType == PFD_MAIN_PLANE) | |
{ | |
writeln("found mode i=", i); | |
writeln("ColorBits", PixelDescriptor.cColorBits); | |
writeln("DephBits", PixelDescriptor.cDepthBits); | |
} | |
}*/ | |
memset(&PixelDescriptor, 0, PIXELFORMATDESCRIPTOR.sizeof); | |
PixelDescriptor.nSize = PIXELFORMATDESCRIPTOR.sizeof; | |
PixelDescriptor.nVersion = 1; | |
PixelDescriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; | |
PixelDescriptor.iPixelType = PFD_TYPE_RGBA; | |
PixelDescriptor.cColorBits = 32; | |
PixelDescriptor.cDepthBits = 24; | |
PixelDescriptor.cAlphaBits = 8; | |
PixelDescriptor.iLayerType = PFD_MAIN_PLANE; | |
FormatInfo = ChoosePixelFormat(this.Hdc, &PixelDescriptor); | |
writeln("FormatInfo", FormatInfo); | |
if( !FormatInfo ) | |
{ | |
return false; | |
} | |
int ReturnInt = DescribePixelFormat( | |
this.Hdc, | |
FormatInfo, | |
PIXELFORMATDESCRIPTOR.sizeof, | |
&PixelDescriptor | |
); | |
if( !ReturnInt ) | |
{ | |
return false; | |
} | |
ReturnBOOL = SetPixelFormat(this.Hdc, FormatInfo, &PixelDescriptor); | |
if( !ReturnBOOL ) | |
{ | |
return false; | |
} | |
writeln(this.Hdc); | |
//ReturnBOOL = wglMakeCurrent(this.Hdc, null); | |
//writeln("... ", ReturnBOOL); | |
//return false; | |
this.Glrc = wglCreateContext(this.Hdc); | |
if( this.Glrc is null ) | |
{ | |
return false; | |
} | |
ReturnBOOL = wglMakeCurrent(this.Hdc, this.Glrc); | |
if( !ReturnBOOL ) | |
{ | |
return false; | |
} | |
// check for extension | |
immutable(char) *StringPtr = glGetString(GL_EXTENSIONS); | |
char[] String; | |
uint i = 0; | |
for(;;) | |
{ | |
if( StringPtr[i] == 0 ) | |
{ | |
break; | |
} | |
String ~= StringPtr[i]; | |
i++; | |
} | |
// find substring in string | |
bool Found = false; | |
for( i = 0; i < String.length-25; i++ ) | |
{ | |
//writeln("GL_EXT_FRAMEBUFFER_OBJECT".length); | |
//writeln(String[i..i+25].length); | |
if( String[i..i+25] == "GL_EXT_framebuffer_object" ) | |
{ | |
Found = true; | |
break; | |
} | |
} | |
if( !Found ) | |
{ | |
// error, GL_EXT_framebuffer_object not supported | |
return false; | |
} | |
glGenFramebuffersEXT = cast(TYPEGLGENFRAMEBUFFERSEXT)wglGetProcAddress("glGenFramebuffersEXT"); | |
glGenRenderbuffersEXT = cast(TYPEGLGENRENDERBUFFERSEXT)wglGetProcAddress("glGenRenderbuffersEXT"); | |
glBindFramebufferEXT = cast(TYPEGLBINDFRAMEBUFFEREXT)wglGetProcAddress("glBindFramebufferEXT"); | |
glFramebufferTexture2DEXT = cast(TYPEGLFRAMEBUFFERTEXTURE2DEXT)wglGetProcAddress("glFramebufferTexture2DEXT"); | |
glBindRenderbufferEXT = cast(TYPEGLBINDRENDERBUFFEREXT)wglGetProcAddress("glBindRenderbufferEXT"); | |
glRenderbufferStorageEXT = cast(TYPEGLRENDERBUFFERSTORAGEEXT)wglGetProcAddress("glRenderbufferStorageEXT"); | |
glFramebufferRenderbufferEXT = cast(TYPEGLFRAMEBUFFERRENDERBUFFEREXT)wglGetProcAddress("glFramebufferRenderbufferEXT"); | |
glCheckFramebufferStatusEXT = cast(TYPEGLCHECKFRAMEBUFFERSTATUSEXT)wglGetProcAddress("glCheckFramebufferStatusEXT"); | |
// Shader | |
glExt.glCreateProgram = cast(glExt.TYPEGLCREATEPROGRAM)wglGetProcAddress("glCreateProgram"); | |
glExt.glUseProgram = cast(glExt.TYPEGLUSEPROGRAM)wglGetProcAddress("glUseProgram"); | |
glExt.glAttachShader = cast(glExt.TYPEGLATTACHSHADER)wglGetProcAddress("glAttachShader"); | |
glExt.glLinkProgram = cast(glExt.TYPEGLLINKPROGRAM)wglGetProcAddress("glLinkProgram"); | |
glExt.glBindAttribLocation = cast(glExt.TYPEGLBINDATTRIBLOCATION)wglGetProcAddress("glBindAttribLocation"); | |
glExt.glBindFragDataLocation = cast(glExt.TYPEGLBINDFRAGDATALOCATION)wglGetProcAddress("glBindFragDataLocation"); | |
glExt.glGetUniformLocation = cast(glExt.TYPEGLGETUNIFORMLOCATION)wglGetProcAddress("glGetUniformLocation"); | |
glExt.glGetProgramiv = cast(glExt.TYPEGLUEIP)wglGetProcAddress("glGetProgramiv"); | |
glExt.glGetShaderiv = cast(glExt.TYPEGLUEIP)wglGetProcAddress("glGetShaderiv"); | |
glExt.glGetProgramInfoLog = cast(glExt.TYPEGLUSISIPCP)wglGetProcAddress("glGetProgramInfoLog"); | |
glExt.glGetShaderInfoLog = cast(glExt.TYPEGLUSISIPCP)wglGetProcAddress("glGetShaderInfoLog"); | |
glExt.glCreateShader = cast(glExt.TYPEGLCREATESHADER)wglGetProcAddress("glCreateShader"); | |
glExt.glShaderSource = cast(glExt.TYPEGLSHADERSOURCE)wglGetProcAddress("glShaderSource"); | |
glExt.glCompileShader = cast(glExt.TYPEGLU)wglGetProcAddress("glCompileShader"); | |
glExt.glUniformMatrix4fv = cast(glExt.TYPEGLUNIFORMMATRIX4FV)wglGetProcAddress("glUniformMatrix4fv"); | |
// Buffer | |
glExt.glGenVertexArrays = cast(glExt.TYPEGLGENVERTEXARRAYS)wglGetProcAddress("glGenVertexArrays"); | |
glExt.glBindVertexArray = cast(glExt.TYPEGLU)wglGetProcAddress("glBindVertexArray"); | |
glExt.glVertexAttribPointer = cast(glExt.TYPEGLVERTEXATTRIBPOINTER)wglGetProcAddress("glVertexAttribPointer"); | |
glExt.glEnableVertexAttribArray = cast(glExt.TYPEGLU)wglGetProcAddress("glEnableVertexAttribArray"); | |
glExt.glDeleteVertexArrays = cast(glExt.TYPEGLDELETEVERTEXARRAYS)wglGetProcAddress("glDeleteVertexArrays"); | |
glExt.glBindBuffer = cast(glExt.TYPEGLBINDBUFFER)wglGetProcAddress("glBindBuffer"); | |
glExt.glBufferData = cast(glExt.TYPEGLBUFFERDATA)wglGetProcAddress("glBufferData"); | |
glExt.glGenBuffers = cast(glExt.TYPEGLGENBUFFERS)wglGetProcAddress("glGenBuffers"); | |
glExt.glDeleteBuffers = cast(glExt.TYPEGLDELETEBUFFERS)wglGetProcAddress("glDeleteBuffers"); | |
if( | |
glExt.glCreateProgram is null || | |
glExt.glUseProgram is null || | |
glExt.glAttachShader is null || | |
glExt.glLinkProgram is null || | |
glExt.glBindAttribLocation is null || | |
glExt.glBindFragDataLocation is null || | |
glExt.glGetUniformLocation is null || | |
glExt.glGetProgramiv is null || | |
glExt.glGetShaderiv is null || | |
glExt.glGetProgramInfoLog is null || | |
glExt.glGetShaderInfoLog is null || | |
glExt.glCreateShader is null || | |
glExt.glShaderSource is null || | |
glExt.glCompileShader is null || | |
glExt.glUniformMatrix4fv is null || | |
glExt.glGenVertexArrays is null || | |
glExt.glBindVertexArray is null || | |
glExt.glVertexAttribPointer is null || | |
glExt.glEnableVertexAttribArray is null || | |
glExt.glDeleteVertexArrays is null || | |
glExt.glBindBuffer is null || | |
glExt.glBufferData is null || | |
glExt.glGenBuffers is null || | |
glExt.glDeleteBuffers is null | |
) | |
{ | |
// error, couldn't find a symbol | |
return false; | |
} | |
return true; | |
} | |
} | |
void deinit() | |
{ | |
static if( WINDOWS ) | |
{ | |
wglMakeCurrent(null, null); | |
wglDeleteContext(this.Glrc); | |
ReleaseDC(this.Hwnd, this.Hdc); | |
FreeLibrary(this.ModuleOpenGl); | |
} | |
} | |
void swapBuffers() | |
{ | |
static if( WINDOWS ) | |
{ | |
SwapBuffers(this.Hdc); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment