Friday, January 25, 2013

Chrome local file access

I've been doing some things at work on a webpage for Chrome Desktop, Chrome Android and Safari. We basically need to present the same 3D content across all of these browsers.

When testing Chrome, for security reasons you cannot run pages that will load local content. There are several fixes to this. The quickest is to run Chrome with a specific argument to disable the security feature. I won't describe that fix as it isn't a good idea.

No, the good idea is to run the site you're working on via a local server. It's also very easy to do.


  • Download the latest version of Python 2.X
  • Open up the command prompt or terminal and go to the folder with the site's index.html.
  • Once in this folder, run the command [python -m SimpleHTTPServer].
  • Your folder's contents will be hosted at the web address [http://localhost:8000].
And that's it! You can safely dev your site on this python local host now. When you are done just close the terminal (or press ctrl+c in the terminal).

Remember to launch the server from the terminal once it is in the folder with the site's index.html.

Friday, January 18, 2013

OpenGL explained: Framebuffer Object & Renderbuffer

Upon looking around for some info on an issue I'm currently having, I found the following posted by user "Nicol Bolas" on StackOverflow. I've read a few of this user's posts and they are quite knowledgeable on OpenGL related things.

Also, Nicol Bolas is the name of the chaos dragon from Magic The Gathering. Coincidence? Lol.

Anyway, the description is quite concise in my opinion.


A framebuffer object is a place to stick images so that you can render to them. Color buffers, depth buffers, etc all go into a framebuffer object.
A renderbuffer is like a texture, but with two important differences:
  1. It is always 2D and has no mipmaps. So it's always exactly 1 image.
  1. You cannot read from a renderbuffer. You can attach them to an FBO and render to them, but you can't sample from them with a texture access or something.
So you're talking about two mostly separate concepts. Renderbuffers do not have to be "for depth testing." That is a common use case for renderbuffers, because if you're rendering the colors to a texture, you usually don't care about the depth. You need a depth because you need depth testing for hidden-surface removal. But you don't need to sample from that depth. So instead of making a depth texture, you make a depth renderbuffer.
But renderbuffers can also use colors rather than depth formats. You just can't attach them as textures. You can still blit from/to them, and you can still read them back with glReadPixels. You just can't read from them in a shader.
http://stackoverflow.com/questions/9850803/glsl-renderbuffer-really-required

So you can't really use a renderbuffer for anything yourself. You put it in there so the system has a place to write things.

The framebuffers are for things you plan to work with.

Friday, October 5, 2012

D Programming Error: Module conflicts with itself

This happened to me when I imported a library someone made.

I had to go through the headers and adjust each file's module path to match the path it currently had in my project hiearchy.

As in, file Bloop.d had the original "module: someLibrary.bloop;". It was now in the folder libz/someLibrary/bloop so I changed it to "module: libz.someLibrary.bloop".

That resolved it for  me.

Tuesday, October 2, 2012

D Programming: OpenGL 3.x+ (for Windon't 7) Part 3

First of all, here are some important links you need to bookmark and frequent for D/Derelict/MonoD/COOLSHIT:



Things you'll need:

  • zlib1.dll
  • SDL2.dll
  • SDL2_image.dll
  • libpng15-15.dll
You will put these into your project next to your .exe file you run.

Here is the project code...


import std.stdio;      //required libpng15-15.dll + zlib1.dll placed next to .exe
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; 
   out vec4 fragColor;

   void main(void) 
   { 
      vec3 col=texture2D(colMap, coords.st).xyz; 

      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(fshad, 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(){ 
      glUseProgram(shader); 
   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("4.png")); 
   SDL_Surface *s=IMG_Load("4.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; 
}
So just paste that into your MonoD project's "main.d" and build/compile/run it. You can exit the program by pressing the "ESC" key. Hope this helps speed up your starting up.

D Programming: OpenGL 3.x+ (for Windon't 7) Part 2

To start we need to... start.

You will need to download the D installer, the Mono IDE, the MonoD extension, Derelict3, and some things required to get SDL2 to work.

I will be hosting everything on a single page so you don't have to crawl around for it. These downloads will become outdated but should (for the foreseeable future) work together just fine.

So if you want the latest/greatest make sure you DON'T use my downloads and actually go get copies of these things yourself.

Download everything from me.

  1. https://code.google.com/p/brollace-blog-filehost/source/browse/d_pack.zip
  2. On the right of the page is the link "view raw file".
  3. Right click the link and "save as" to download the zip.
Setup a storage directory
  1. Go to your "Documents" and create a folder called "DontMove".
  2. In this folder create a folder called "D".
  3. Unpack the contents of "d_pack.zip" to "DontMove\D" so that, for instance, you can observe the following path: "DontMove\D\4.png", and NOT "DontMove\D\d_pack\4.png".
Install D Programming Language:

Uses the d_pack files:
  • dinstaller.exe
  1. Run the "dinstaller.exe".
  2. I put my installation on "C:\D\<my stuff installed here yo>"
Setup Derelict3 for OpenGL 3.X+

Now this part was painful so please do allow me to share the fruits of my labor with you to end the chain of suffering.

Uses the d_pack files:
  • aldacron-Derelict3-b4f810c.zip
  1. Unzip the aldracon package.
  2. Go to "import" so you see a folder containing "derelict".
  3. Copy the folder "derelict" with all the stuff in it and paste it into (for example on my machine) "C:\D\dmd2\src".
  4. The folder should look something like "derelict, dmd, druntime, phobos".
  5. Go to "aldracon/lib" and copy everything to (for example on my machine) "C:\D\dmd2\windows\lib".
  6. You should have just copied a bunch of .libs into a folder of other .libs.
  7. Open up "C:\D\dmd2\windows\bin\sc.ini" in some editor like Notepad++ or Scite or ConTEXT.
  8. Change the line: [1] to look something like [2]...
[1] DFLAGS="-I%@P%\..\..\src\phobos" "-I%@P%\..\..\src\druntime\import"
[2]DFLAGS="-I%@P%\..\..\src\phobos" "-I%@P%\..\..\src" "-I%@P%\..\..\src\druntime\import"

Install MonoD

Uses the d_pack files:
  • MonoDevelop-3.0.4.7.msi
  • MonoDevelop.D_0.4.1.4_MD3.0.4.7.mpack
  • ResourceCompiler.zip
.
.
.
.

You should now be able to create D programs in MonoDevelop using MonoD.

Next I will go over how to write your first D OpenGL3.X+ app using SDL2.

D Programming: OpenGL 3.x+ (for Windon't 7) Part 1

D. Just say it. D...

Mmm....

I really want to get away from C++ (lol impossible ikr).  So I'm going to invest my time and projects into developing with D.

These posts will be tutorials on how to start up D programming, and then on how to write an OpenGL 3.X+ application in D.

Thursday, August 23, 2012

Windows 7: Eclipse CDT + OpenGL + MinGW Part 4

Setting up the FreeGLUT project


  1. In Eclipse...
  2. File > New > Project > C/C++ > C++ Project
  3. Hello World C++ Project w/ MinGW GCC
  4. If you didn't see MinGW GCC then uncheck the box "Show project types and ....".
  5. Name the project and finish.
  6. Copy the lib and include folders you've been adding things to over to the eclipse_workspace folder and place them next to the project's src folder.
  7. In Eclipse, right click on the project > Properties > C/C++ Build > Settings
  8. GCC C++ Compiler > Includes > Include paths (-I)
  9. Click the button with the green plus sign and add the "workspace" path to your folder "include" that you copied into the project folder.
  10. MinGW C++ Linker > Libraries.
  11. Go to Libraries (-l) and add: "glu32", "opengl32", "freeglut".
  12. These need to be in a proper order to try to keep them in the order I just described, from the top to the bottom (glew32 on top, then glfw, then...).
  13. Go to Library search path (-L)
  14. Add the "workspace" path to the "lib" folder you copied into the project folder.
  15. Click "Apply" and "Ok".
  16. Take the .dll's you copied into your "bin" folder and copy them into the project's "debug" or "release" folder. I use "debug", and it's what I've confirmed to work, so copy them into the "debug" folder.
  17. Copy and paste the code here over the hello world code. This will run the spinning cube dude:  http://pastebin.com/RfdPESsz
  18. Right click the project and "Build" (or hit the hammer button up top).
  19. Right click the project and "Run As" > "Local C/C++ Application".
Setting up the GLFW project


  1. In Eclipse...
  2. File > New > Project > C/C++ > C++ Project
  3. Hello World C++ Project w/ MinGW GCC
  4. If you didn't see MinGW GCC then uncheck the box "Show project types and ....".
  5. Name the project and finish.
  6. Copy the lib and include folders you've been adding things to over to the eclipse_workspace folder and place them next to the project's src folder.
  7. In Eclipse, right click on the project > Properties > C/C++ Build > Settings
  8. GCC C++ Compiler > Includes > Include paths (-I)
  9. Click the button with the green plus sign and add the "workspace" path to your folder "include" that you copied into the project folder.
  10. MinGW C++ Linker > Libraries.
  11. Go to Libraries (-l) and add: "glew32", "glfw", "glu32", "opengl32".
  12. These need to be in a proper order to try to keep them in the order I just described, from the top to the bottom (glew32 on top, then glfw, then...).
  13. Go to Library search path (-L)
  14. Add the "workspace" path to the "lib" folder you copied into the project folder.
  15. Click "Apply" and "Ok".
  16. Take the .dll's you copied into your "bin" folder and copy them into the project's "debug" or "release" folder. I use "debug", and it's what I've confirmed to work, so copy them into the "debug" folder.
  17. Copy and paste the code here over the hello world code. This will run the spinning cube dude:   http://pastebin.com/yXDzXPYq
  18. Right click the project and "Build" (or hit the hammer button up top).
  19. Right click the project and "Run As" > "Local C/C++ Application".
The GLFW project will build fine but for me I have to run it from the project's debug folder. You can of course run it in debug in the editor just fine.

Here is a copy of my project folders. Everything is referenced from within the project workspaces so things should be portable: THE_PROJECTS.