digitalmars.D.learn - Derelict3 running
- Stephen Jones (260/260) May 01 2012 I just got DMD2 Derelict3 (SDL2/GL3/SDL2Image) up and running.
I just got DMD2 Derelict3 (SDL2/GL3/SDL2Image) up and running. Since there is not much by way of documentation or running code floating about I thought I'd drop what worked for me here. The code is a basic c style main and functions. The code contains a cool snip of code for flipping images to get them proper with openGL by tito http://stackoverflow.com/questions/5862097/sdl-opengl-screenshot-is-black. First a brief rundown of what I found to be required and where (I am using XP): 1) a built version of Derelict3 with sc.ini properly configured (http://www.sjonesart.com/gl.php) I have a link showing how to set up DMD2 Eclipse and Derelict. 2) driver files SDL2.dll and SDL2_Image.dll both of which aldacron has provided as binaries https://github.com/aldacron/Derelict3/downloads. These files need to be placed in the same folder as your compiled .exe 3) I also required libpng15-15.dll and zlib1.dll be placed alongside the SDL2 dlls. //THE CODE~~ import std.stdio; import std.string; import std.conv; import std.path; import std.file; import derelict.sdl2.sdl; import derelict.sdl2.image; import derelict.opengl3.gl3; pragma(lib, "DerelictUtil.lib"); pragma(lib, "DerelictSDL2.lib"); pragma(lib, "DerelictGL3.lib"); SDL_Window *win; SDL_GLContext context; int w=800, h=600; bool running=true; uint shader = 0, vao = 0, tid = 0, colLoc = 0; int flags=SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_SHOWN; bool initSDL_GL(){ if(SDL_Init(SDL_INIT_VIDEO) < 0){ writefln("Error initializing SDL"); return false; } SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); win=SDL_CreateWindow("3Doodle", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, flags); if(!win){ writefln("Error creating SDL window"); SDL_Quit(); return false; } context=SDL_GL_CreateContext(win); SDL_GL_SetSwapInterval(1); glClearColor(0.0, 0.0, 0.0, 1.0); glViewport(0, 0, w, h); DerelictGL3.reload(); return true; } bool initShaders(){ const string vshader=" #version 330 layout(location = 0) in vec3 pos; layout(location = 1) in vec2 texCoords; out vec2 coords; void main(void) { coords=texCoords.st; gl_Position = vec4(pos, 1.0); } "; const string fshader=" #version 330 uniform sampler2D colMap; in vec2 coords; void main(void) { vec3 col=texture2D(colMap, coords.st).xyz; gl_FragColor = vec4(col, 1.0); } "; shader=glCreateProgram(); if(shader == 0){ writeln("Error: GL did not assigh main shader program id"); return false; } int vshad=glCreateShader(GL_VERTEX_SHADER); const char *vptr=toStringz(vshader); glShaderSource(vshad, 1, &vptr, null); glCompileShader(vshad); int status, len; glGetShaderiv(vshad, GL_COMPILE_STATUS, &status); if(status==GL_FALSE){ glGetShaderiv(vshad, GL_INFO_LOG_LENGTH, &len); char[] error=new char[len]; glGetShaderInfoLog(vshad, len, null, cast(char*)error); writeln(error); return false; } int fshad=glCreateShader(GL_FRAGMENT_SHADER); const char *fptr=toStringz(fshader); glShaderSource(fshad, 1, &fptr, null); glCompileShader(fshad); glGetShaderiv(vshad, GL_COMPILE_STATUS, &status); if(status==GL_FALSE){ glGetShaderiv(fshad, GL_INFO_LOG_LENGTH, &len); char[] error=new char[len]; glGetShaderInfoLog(fshad, len, null, cast(char*)error); writeln(error); return false; } glAttachShader(shader, vshad); glAttachShader(shader, fshad); glLinkProgram(shader); glGetShaderiv(shader, GL_LINK_STATUS, &status); if(status==GL_FALSE){ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); char[] error=new char[len]; glGetShaderInfoLog(shader, len, null, cast(char*)error); writeln(error); return false; } return true; } bool initVAO(){ uint vbov, vboc; const float[] v = [ -0.75f, -0.75f, 0.0f, 0.75f, 0.75f, 0.0f, -0.75f, 0.75f, 0.0f]; const float[] c = [ 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f]; glGenVertexArrays(1, &vao); assert(vao > 0); glBindVertexArray(vao); glGenBuffers(1, &vbov); assert(vbov > 0); glBindBuffer(GL_ARRAY_BUFFER, vbov); glBufferData(GL_ARRAY_BUFFER, v.length * GL_FLOAT.sizeof, v.ptr, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, null); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &vboc); assert(vboc > 0); glBindBuffer(GL_ARRAY_BUFFER, vboc); glBufferData(GL_ARRAY_BUFFER, c.length * GL_FLOAT.sizeof, c.ptr, GL_STATIC_DRAW); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, null); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); return true; } bool initUniforms(){ colLoc=glGetUniformLocation(shader, "colMap"); if(colLoc == -1){writeln("Error: main shader did not assign id to sampler2D colMap"); return false;} glUseProgram(shader); glUniform1i(colLoc, 0); glUseProgram(0); return true; } bool initTex(){ assert(exists("MaoriPartyTransforms.png")); SDL_Surface *s=IMG_Load("MaoriPartyTransforms.png"); assert(s); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glGenTextures(1, &tid); assert(tid > 0); glBindTexture(GL_TEXTURE_2D, tid); int mode = GL_RGB; if(s.format.BytesPerPixel == 4) mode=GL_RGBA; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexImage2D(GL_TEXTURE_2D, 0, mode, s.w, s.h, 0, mode, GL_UNSIGNED_BYTE, flip(s).pixels); SDL_FreeSurface(s); return true; } //thanks to tito http://stackoverflow.com/questions/5862097/sdl-opengl-screenshot-is-black SDL_Surface* flip(SDL_Surface* sfc) { SDL_Surface* result = SDL_CreateRGBSurface(sfc.flags, sfc.w, sfc.h, sfc.format.BytesPerPixel * 8, sfc.format.Rmask, sfc.format.Gmask, sfc.format.Bmask, sfc.format.Amask); ubyte* pixels = cast(ubyte*) sfc.pixels; ubyte* rpixels = cast(ubyte*) result.pixels; uint pitch = sfc.pitch; uint pxlength = pitch*sfc.h; assert(result != null); for(uint line = 0; line < sfc.h; ++line) { uint pos = line * pitch; rpixels[pos..pos+pitch] = pixels[(pxlength-pos)-pitch..pxlength-pos]; } return result; } int main(){ try{ DerelictSDL2.load(); }catch(Exception e){ writeln("Error loading SDL2 lib"); return false; } try{ DerelictGL3.load(); }catch(Exception e){ writeln("Error loading GL3 lib"); return false; } try{ DerelictSDL2Image.load(); }catch(Exception e){ writeln("Error loading SDL image lib ", e); return false; } writeln("Init SDL_GL: ", initSDL_GL()); writeln("Init shaders: ", initShaders()); writeln("Init VAO: ", initVAO()); writeln("Init uniforms: ", initUniforms()); writeln("Init textures: ", initTex()); while(running){ SDL_Event e; while(SDL_PollEvent(&e)){ switch(e.type){ case SDL_KEYDOWN: running=false; break; default: break; } } glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shader); glBindVertexArray(vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tid); glDrawArrays(GL_TRIANGLES, 0, 6); glBindTexture(GL_TEXTURE_2D, 0); glBindVertexArray(0); glUseProgram(0); SDL_GL_SwapWindow(win); } SDL_GL_DeleteContext(context); SDL_DestroyWindow(win); SDL_Quit(); return 0; }
May 01 2012