Thursday, March 26, 2015

Make Human to Blender to UE4

I'm prototyping an FPS in UE4. I need/want a non-epic-blue-dude. I've got a good enough handle on Blender for performing basic tasks for assets, but nothing actually artistic.

So what do I do?

I created a pipeline from Make Human, to Blender, to UE4. This allows me to generate a great (albeit generic) human model that is rigged and all setup for UE4 animations. I then take it into Blender for any mesh adjustments I'd like to make. Then, I finally bring it into UE4. There, I make use of animation re-targeting. This allows me to copy/paste Unreal's free animations pack into my own model.

Essentially, I'm able to generate a model with ~60 quality FPS animations w/o actually creating any art assets! That's re-diq-you-lass.

Step-By-Step

Make Human
You need to download their latest "unstable" version. As of the time of this writing, that was the only version supporting UE4 Epic rigging.
  • Tweak your human.
    • UE4 normal person height = about 183cm. 
Make Human Exporting
  • Pose/Animate > Skeleton > Tag Filter > Game: Yes.
  • Pose/Animate > Skeleton > Rig Presets > Uengine.
  • Pose/Animate > Pose > T-Pose.
  • Export > Mesh Format > Filmbox(fbx)
  • Export > Options > Scale units > centimeter.
  • Export to UE4.
    •  Export > Options > Binary FBX: No.
  • Export to Blender.
    •  Export > Options > Binary FBX: Yes.
Importing TO Blender
  •  Export from Make Human as a "FBX Binary".
    • Blender needs it as a binary. UE4 needs it as ASCII. Remember that difference.
  • Set Scene>Metric>Degrees: 0.01
    • It's in the right-side panel (by default). Google up "Blender Set Metric Degrees".
  •  File>Import>FBX
Adjusting IN Blender

Blender will fudge things up a bit. So here's how you un-fudge it.
  •  Make sure you are in "Object" mode.
  • Select the model.
    • In the scene explorer it should be the top level of the model's hierarchy.
  • Press "N" with your mouse in the big scene view in the center of your screen (default).
    • This brings up the transforms.
  • The scale will probably be something dumb like "0.001" or w/e. Set these scales to "1.0".
  • Apply the transformations as the default to the model.
    • Crtl+A > Apply Rotation and Scale.
    • Important! Apply the Rotation AND Scale.
Exporting FROM Blender
  • File>Export>FBX.
  • Select ONLY Mesh + Armature.
  • Scale = 1.0.
  • Leave Forward/Up alone.
  • Uncheck "Default Take".
  • Toggle the pull down to ASCII and NOT Binary.
  • Everything else should be fine as is.
Importing to UE4
Only a few things to handle here...
  • Open your UE4 project.
  •  Drag your FBX file you exported INTO UE4.
  • A prompt will pop-up.
  • Mesh > Import Mesh: Yes
  • Mesh > Import as Skeletal: Yes
  • Mesh > Skeleton: None
  • Mesh > Use TPose Ref: Yes
  • Mesh > Normal Import Method: Import Normals and Tangents
  • Mesh > Create Physics Asset: No
  • Animation > Import Animations: Yes
  • Press Import All
  • Check out your imported mesh to see if it's looking right.
Re-Targeting Animations
Make sure you have the free animations pack. If you don't, download it from the Epic browser.
  • Add the animations to your project.
  • Part 1.
    • Open the HeroTPP model.
    • Select it's skeleton.
    • Open "Retarget Manager".
    • Manager Retarget Source > Current Skeleton > HeroTPP
    • Set up Rig > Select Rig > Humanoid
    • Save Pose.
  • Part 2.
    • Open your imported model.
    • Select it's skeleton.
    • Open "Retarget Manager".
    • Manager Retarget Source > Current Skeleton > None.
    • Set up Rig > Select Rig > Humanoid
    • Save Pose.
  • Part 3.
    • Find/Select the HeroTPP animation you want to steal.
    •  Right Click > Retarget Anim Assets > Duplicate Anim Assets and Retarget.
    • Pop-up.
    • You should see the HeroTPP in the left window.
    • Select the name of your model.
    • You should see your skeleton in the right window.
    • "Select".
    • Check out the new animation applied to your model!
Thoughts

 The feet and hands get to look pretty f'd up? Also, the neck can be quite stretched out with the head way in front of the chest and the shoulders pulled back. So lol, yea, be aware of that.

Tuesday, March 24, 2015

Upcoming topics for 2015!

It's been forever!!!

But, I do have some entries I'm planning to write up. They'll be tutorials and guides on how-to for a few topics in Unity and UE4.

They will include (at least):
  • Unity C#
    • Creating Event Triggers
    • Creating a hex tile system
    • Dynamically "stamping" to a terrain splat texture
    • Manually positioning a particle system's individual sprites
    • Maybe.... Implementing HTML Logging with screenshot support
    • Infinite Scrolling Parallax Backgrounds using 1-D noise 
    • Using Unity with GIT
  • UE4 C++
    •  Mele Combat
    • Dynamic textures affected by gameplay
    • Procedural Mazes
    • Maybe.... Implementing HTML Logging with screenshot support

Monday, March 24, 2014

Another way to post code snippets!

Bam.

A great way to host/post code snippets is to use Github+Gist.

In short, you create a file with some code formatting, and then copy the embed link to post on your blog. It's really simple and really fast.

Here's my steps for getting from A to Z:

  1. Sign up or sign in to github.
  2. Go to the uber top of the page and click "gist".
  3. Write your code into the file.
  4. Select the file type to match your code.
  5. Save.
  6. On the left of the page will be the embed link.
  7. Copy that link and paste it as HTML in your blog post.
That's it.

In Blogger, I don't see the Gist until I "Preview", so keep that in mind.

Wednesday, May 1, 2013

Spidermonkey Nightly [March 1st, 2013]: Windows7 VS2012

I built and packaged the dependencies for playing with spidermonkey (I think it's ionmonkey at the moment) within VS2012 on Windows 7.

I'm not sure if it's 32 or 64 but I basically built the Firefox nightly from source and then pulled out the Spidermonkey stuff for use.

Hopefully it runs for you right away! Took me a while to get it right:
https://bitbucket.org/brownw1/spidermonkey_vs2012

Thursday, April 18, 2013

Why singletons are "Bad Patterns"

I made a point for my new years resolution of 2013 to use more design patterns. I wanted to start making more conscious and judicious design decisions and to stop "slinging code".

So I started using the singleton pattern for things like caches and input in my projects.

Of course, I then find out that these convenient things are "bad practice" and that I should stop using them. I didn't really get why they are bad though until I crawled around some Stack Overflow posts on the topic.

What it boils down to is...

  1. Singletons hide dependencies
  2. Singletons make it hard to test
  3. Singletons aren't automatically cleaned up and are thus liabilities
I really do enjoy the concept of keeping things scoped so that they can just get destructed and neatly go away.

That being said, a decent "solution" to the "problem" seems to be to create your potential singleton object high up in the design hierarchy as a scoped object. Then, just have every object below it in the hierarchy that needs it receive a reference to it in their construction.

Doing that, you have a clear dependency, a scoped object, and defined initialization order (I believe that's the right way to say it?).

Maybe you could just define a base class that constructs to take reference of potential singleton resources like a cache manager or input manager. Then, the dependency would just be a way normal thing in your design.

Monday, March 4, 2013

GLFX Build with VS2012

If you get an error about a version 1600 not being 1700 when you use MSVC2012 to build a project with GLFX, then it means you need to compile GLFX for yourself.

So, here is how I did it (like 1 minute ago).


  1. Grab the glfx source.
  2. Open the vs2010 project in vs2012.
  3. In the solution, right click on the bold project "glfx".
  4. Goto "Resources".
  5. Note the project referenced, "glew_static".
  6. You'll need to get the glew source and add the project to the glfw solution, then add it as a reference.
  7. So, remove the old glew static reference inside of glfx references.
  8. Add your own, "my_glu\build\vc10\glew_static.vcxproj".
  9. Add a glfx reference to the project you just added to the solution.
  10. Your build should now work.
  11. Goto glfx/Debug (or Release if you built that?), and grab a copy of the .lib to use in your project.
Whamo, that should do it.

Wednesday, February 20, 2013

iOS Note: Panoramic Hotspots

This is just a note on some of the solutions I've implemented for features on a project we are doing at my job.

So we have a panoramic viewer on the iPad. There is an image mapped to a sphere and a camera in the center of the sphere. You can rotate around and zoom in on things.

The designers wanted the functionality to click on specifically designated areas to trigger events. For instance, touch this painting and you get info on the piece.

In the legacy code I inherited for the project( it was already roughed out in prototype ), these triggers were detected via point-radius calculations. Here is an XYZ-position, here is it's radius, do BLAH when a touch hits in that radius. This works fine to some level of accuracy but they quickly found that they needed not only more accuracy but a more flexible way for other designers on the team to author these areas without reaching into the compiled code.

So they asked me, and I said to move the problem from model space to image space. Drop the positions and distances and just work with the pixels since that's what you are interacting with anyway.

My solution was basically to modify the rendering pipeline a bit, and to add a message queue.

For the pipeline, setup framebuffer rendering so that you aren't only writing to the screen but also to an offscreen buffer. Note that this will be a framebuffer not a renderbuffer. What do we draw to this offscreen buffer? We will have the artists/designers copy the panoramic texture and draw, in solid 1 color colors (no gradients or whatnot) the areas they would like to respond to touch. They will paint on their touch areas. With rgb 255-255-255 you get around 16,000,000 colors? That's 16 million unique touch areas. Plenty.

Now you can just glReadPixels a single pixel at the touch screen position from the offscreen bufer to get the color they touched.

What I do is, on a touch, I push a "request" for a sampling into queue-A. Queue-Ais the "request mailbox", the renderer's "inbox". The renderer checks this when it's submitting render calls and if it see's any requests in it's inbox it it calls glReadPixels and puts the result into queue-B, the "response mainbox", this is the renderer's "outgoing box". The rest of the application checks this outgoing box regularly to see if anything is in it. It will take any mail from it, which will be an rgb color, and will check a table it has to see what event trigger given the color. And that is it.

The users don't see this rainbow collision map because it's drawn offscreen. You don't have to transform any coordinates because all of that is done in the shaders. The transforms are the exact same as those performed on the screen image also so the collisions match up 1-1 regardless of any zoom or w/e features you do. The designers get per-pixel accuracy. It's a solid solution (has been so far at least ).

Caveats include not working in the simulator. I believe this is because the technique is hardware accelerated and thus dependent on. well. hardware and not just simulated architecture.

Tuesday, February 19, 2013

UDK Note: Take Damage Events

<This note is intended for people who know about UDK Kismet TakeDamageEvents but can't seem to get the thing to work>...

Let's say you want to shoot a light to turn hide a light shaft, or shoot a barrel to make it explode into flames.

Right click your object to shoot, and if it's a static mesh convert it to a mover (Convert>Mover). With the object selected go to it's properties (press F4), go to Collision, set "Collision Type" to "Block All".

Now your object should get hit and the event's target should process.

Moral of the story is to make sure your static meshes are at least movers with block all collision so the take damage event triggers.

Wednesday, February 6, 2013

How To: Obj-C Set Mouse Position

Reference: http://stackoverflow.com/questions/8059667/set-the-mouse-location

Code:
 CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
  CGEventRef mouse = CGEventCreateMouseEvent (NULL, kCGEventMouseMoved, CGPointMake( X, Y), 0);
  CGEventPost(kCGHIDEventTap, mouse);
  CFRelease(mouse);
  CFRelease(source);
Include:
 #include <ApplicationServices/ApplicationServices.h>

You just set the X and Y.

Tuesday, February 5, 2013

UDK How To: How to detect Alternative Fire on Custom Weapons

Alt fire is when you press the right mouse button to shoot.

For instance, the Link Gun in UT has an alt fire of a beam.

If you are creating a Custom weapon you can access this functionality quite easily.

Note that there are other ways to do this (such as creating your own exec function for the "DefaultInput.ini" file to refer to). This allows you to access alt-fire without modifying anything other than your own Custom Weapon Class.

You will need to work with:

  • Your Weapon script
You may read the following scripts:

  • PlayerController.uc
  • Pawn.uc
  • Weapon.uc
  • DefaultInput.ini


TL;DR
You will go to your weapon and overwrite the function:
  • simulated function StartFire(byte FireModeNum)
FireModeNum 0 means primary, 1 means alt.

So you can have functionality execute or not execute depending on the 0 or 1 value.

SOME EXPLINATION
If you check out the UDK\UDKGame\Config\DefaultInput.ini, you can scroll around until you find the player input for alt fire:
  • .Bindings=(Name="GBA_AltFire",Command="StartAltFire | OnRelease StopAltFire")
We can see that an exec function get's called to handle the business, "StartAltFire ".

This means in the PlayerController script this function get's called.

When we check out the script ourselves we see that it then calls:
  • Pawn.StartFire( FireModeNum );
In Pawn.uc, we see this in turn calls:
  • Weapon.StartFire(FireModeNum);
...which is what we took advantage of.

Do you see? By tracing the desired info from the input we were able to find the scripts related to our result and utilize the fuck out of the necessary functions.

This can be a good way to debug your UDK designs (that is, to find out what is going on this huge system).


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.


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.
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.

Wednesday, August 22, 2012

Windows 7: Eclipse CDT + OpenGL + MinGW Part 3

First, pick a place that you won't delete and create the following folders:

  • include
  • lib
  • bin
Now, what are these things going to be for?

FreeGLUT is an up-to-date version of the popular GLUT kit. It makes OpenGL easier to work with by providing windows and some other functionality for you (making the windows is a platform specific thing that is just plain lame and a fucking drag to do in order to get a spinning fucking cube. Fuck.). It's cross platform but doesn't work well on OSX I believe.

GLFW is an alternative to FreeGLUT. It provides windowing and input and some other stuff. Works well on Windows/Linux/OSX. My favorite (o^_^)b.

GLEW allows you to easily enable any extensions you may need. The alternative is sheer torture (maybe not at first but eventually). GLEW it.


FreeGLUT

  1. Go to :  http://www.transmissionzero.co.uk/computing/using-glut-with-mingw/.
  2. Click: "freeglut MinGW Package".
  3. Alternatively, you can follow this link: http://files.transmissionzero.co.uk/software/development/GLUT/freeglut-MinGW.zip
  4. Get the zip file and expand it.
  5. Copy the freeGLUT bin .dll's to your bin folder you made.
  6. Copy the freeGLUT include contents ( copy the entire GL folder ) and put it into the include folder you made.
  7. Copy the freeGLUT lib contents into the lib folder you made.
GLFW
  1. Go to  http://www.glfw.org/download.html.
  2. Download the latest zipped version.
  3. Unzip the package.
  4. Open up the console (WindowsKey + R).
  5. In the windows explorer go to the folder and copy the path from the top of the window.
  6. Go back to the console.
  7. Type "cd ". Space after the cd.
  8. Paste the path you copied and press enter to travel to the folder in the console.
  9. In the console, go to the unzipped folder where the Makefile is.
  10. Run the command "make win32-msys".
  11. If the command errors out then check the "readme.html" for instructions on what other commands to use. I'm pretty sure the error will tell you the options for running the make.
  12. After a few seconds, the console should spew info about the build.
  13. Copy the include/bin/lib stuff like you did before.
  14. Note that you should add the new include/GL stuff to the folder you've already made.
GLEW
  1. Go to  http://glew.sourceforge.net/ and download the latest ZIP.
  2. Don't get the binaries, you will be building it yourself yo.
  3. Unzip the package, console to it, make.
  4. Copy the bin/lib/include stuff like before.

Windows 7: Eclipse CDT + OpenGL + MinGW Part 2

Eclipse CDT C++ plugin( 4.2.0 = Juno )
  1. Open Eclipse.
  2. Go to Help > Install new software > Work with.
  3. Paste in: http://download.eclipse.org/tools/cdt/releases/juno
  4. Press Enter.
  5. Expand "CDT Main Features".
  6. Turn on "C/C++ Development Tools"
  7. Expand "CDT Optional Features"
  8. Turn on: " C/C++ GCC Cross Compiler Support", "C/C++ GDB Hardware Debugging", "C/C++ Memory View Enhancements", "C/C++ Unit Testing Support", "C99 LR Parser", "CDT Visual C++ Support".
  9. Press Next, Finish, w/e. Just go through the installation steps, accept things, until it tells you that it needs to restart.
  10. Allow Eclipse to restart.
MinGW
  1. Go to: http://sourceforge.net/downloads/mingw/MinGW/
  2. Click on (The link will look something like this)"Download mingw-get-inst-20120426.exe (662.7 kB)"
  3. Run the installer.
  4. Say that you want the latest version from teh webz.
  5. Let it do it's thing. Go grab a drink or something.
  6. Go to wherever you installed it and make note of the path to the mingw bin (by default this is C:\MinGW\bin).
  7. Also make note of the mingw msys bin (by default this is C:\MinGW\msys\1.0\bin).
  8. Copy these 2 paths onto the end of your system PATH.
  9. To append these to the path, go to windows start and enter the string "advanced".
  10. Click "View advanced system settings".
  11. Click "Environment Variables".
  12. Go to the "System variables" region at the bottom.
  13. Scroll down to "PATH" and click edit.
  14. Go to the end of this possibly long bigass string and enter a semicolon ";" to separate the last entry from the ones you want to add.
  15. Add the two paths to mingw bin and msys bin (separate these by ";").
  16. Test if you have mingw working now by opening up the console and running make.
  17. Press WindowsKey + R. This will open up RUN.
  18. Type cmd.
  19. Press enter.
  20. Run the command: "make --version".
  21. Run the command: "g++ --version".
  22. If these commands don't error out and complain about something then you are good to go with mingw!

Windows 7: Eclipse CDT + OpenGL + MinGW Part 1

So, I get tired of Visual Studio.

I get tired of it in general, I get tired of it's look, I get tired of it bugging out... And with all the Windows 8 stuff I've been reading about with the "you will develop for Metro or gtfo" what not, I just feel like now is a good time to take my OpenGL preferring self and get away from Visual Studio.

I really like Eclipse. It's easy to work with, it's free, it's got ton's of plug-ins, and it's easy to change the look with templates that don't break everything. Also the code completion is great. In Visual Studio I use Wild Tomato's Visual Assistant X. In Eclipse, I get a free and awesome code completion solution. Score.

Anyway, setting up Eclipse to develop C++ meant installing the CDT plugin. Painless.
Getting OpenGL's spinning cube hello world working... Painful.

But, it always is painful to get OpenGL started up on some dev environment you aren't experienced at working with yet.

So, let me distill the knowledge I have acquired by mentally cartwheeling nude through numerous forums and guides to you, the consumer, so that you may immediately get an OpenGL Spinning Cube application up and working using not only FreeGLUT, but also GLFW and GLEW.