Wednesday, January 30, 2013

[CODE] simple bullet physics debug draw for Cinder


    Not horribly hard to figure out but if you feel like saving yourself some code time or just looking for a quick jumping off point, here you go.  You can also grab the whole project from github.  If this looks like a straight port of bullet's GLDebugDrawer, it pretty much is.

.h
#include "cinder/app/AppBasic.h"
#include "cinder/gl/gl.h"
#include "cinder/Text.h"
#include "btBulletDynamicsCommon.h"
#include "LinearMath/btIDebugDraw.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class CibtDebugDraw : public btIDebugDraw
{
    int m_debugMode;
public:
    CibtDebugDraw();
    virtual ~CibtDebugDraw();
    virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor);
    virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& color);
    virtual void drawSphere(const btVector3& p, btScalar radius, const btVector3& color);
    virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color);
    virtual void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color);
    virtual void reportErrorWarning(const char* warningString);
    virtual void draw3dText(const btVector3& location, const char* textString);
    virtual void setDebugMode(int debugMode);
    virtual int getDebugMode() const;
};

.cpp
CibtDebugDraw::CibtDebugDraw() : m_debugMode(0)
{
}

CibtDebugDraw::~CibtDebugDraw()
{
}

void CibtDebugDraw::drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
{
    gl::begin(GL_LINES);
    gl::color(Color(fromColor.getX(), fromColor.getY(),
        fromColor.getZ()));
    gl::vertex(from.getX(),from.getY(),from.getZ());
    gl::color(Color(toColor.getX(), toColor.getY(), toColor.getZ()));
    gl::vertex(to.getX(),to.getY(),to.getZ());
    gl::end();
}

void CibtDebugDraw::drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
{
    drawLine(from,to,color,color);
}

void CibtDebugDraw::drawSphere(const btVector3& p, btScalar radius, const btVector3& color)
{
    gl::color(Color(color.getX(), color.getY(), color.getZ()));
    gl::drawSphere(Vec3f(p.getX(),p.getY(),p.getZ()), radius);
}

void CibtDebugDraw::drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color)
{
    gl::color(Color(color.getX(), color.getY(), color.getZ()));
    gl::drawStrokedCube(AxisAlignedBox3f(
        Vec3f(bbMin.getX(),bbMin.getY(),bbMin.getZ()),
        Vec3f(bbMax.getX(),bbMax.getY(),bbMax.getZ())));
}

void CibtDebugDraw::drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color)
{
    Vec3f from(PointOnB.getX(), PointOnB.getY(), PointOnB.getZ());
    Vec3f to(normalOnB.getX(), normalOnB.getY(), normalOnB.getZ());
    to = from+to*1;

    gl::color(Color(color.getX(),color.getY(),color.getZ()));
    gl::begin(GL_LINES);
    gl::vertex(from);
    gl::vertex(to);
    gl::end();
}

void CibtDebugDraw::reportErrorWarning(const char* warningString)
{
    console() << warningString << std::endl;
}

void CibtDebugDraw::draw3dText(const btVector3& location, const char* textString)
{
    TextLayout textDraw;
    textDraw.clear(ColorA(0,0,0,0));
    textDraw.setColor(Color(1,1,1));
    textDraw.setFont(Font("Arial", 16));
    textDraw.addCenteredLine(textString);
    gl::draw(gl::Texture(textDraw.render()),
        Vec2f(location.getX(),location.getY()));
}

void CibtDebugDraw::setDebugMode(int debugMode)
{
    m_debugMode = debugMode;
}

int CibtDebugDraw::getDebugMode() const
{
    return m_debugMode;
}

Here's a quick shot of the debug drawer in action with a single body:

Sunday, January 27, 2013

[TUTORIAL] Getting tweets into Cinder


    Hmm...the notion of "getting something into Cinder" may be a bit of a misnomer, but then, you are pulling data into a framework/environment, so maybe it is.  Ah well, point being we're moving on from the previous installment wherein we walked through the steps required to build the twitcurl library so we could tweet in C++.  Now we need to actually use the darn thing, yeah?  So let's get to...err...Tweendering? (Cindweeting?  Cindereeting?  Sure, ok).  I'm assuming we all know how to use Tinderbox to setup a Cinder project, if not, just hit up <your cinder root>\tools\TinderBox.exe, it's pretty self-explanatory after that.    Here we gooo...

1.a) Once we've got an initial project tree, let's move some files and folders around to make setting up dependencies a bit simpler. Starting from <your cinder project root>, let's make our project tree look something like this (completely optional):

assets/
include/
  twitcurl.h
  oauthlib.h
  curl/
    (all the curl headers)
lib/ <-- add this folder manually
  libcurl.lib
  twitcurl.lib
resources/
src/
vc10/
  afont.ttf

Given this tree, setting up the rest of the dependencies for the project should be pretty straightforward.  I should point out that putting the font file directly into the vc10 folder is a bit of a hack and not at all the proper way to set up a Cinder resource, but for now I just want to get something functional.  Much respect to the Cinder team for their solution to cross-platform resource management though, I'll probably cover that once we start getting into building the final project.  Feel free to do some independent study, though, and check out the documentation on Assets & Resources in Cinder (and send me a pull request if you do!). 

1.b) So...let's code (and test out the new style sheet I wrote for syntax-highlighting)!  If you're interested in taking a peek at what the finished result might look like, check out the web version of Jer Thorp's tutorial, and if you're reading this Jer, no disrespect, I'm totally not meaning to steal your work for profit or some nefarious purpose, it's just a great, simple example that's super straightforward and easy to understand.  Had to get that off my chest, all credit where it's due.  If you haven't checked out the original tutorial, it goes (a little something) like this:

1) Do a twitter search for some term, we'll use "perceptualcomputing"
2) Split all the tweets up into individual words
3) Draw a word on screen every so often at a random location
4) Fade out a bit, rinse, repeat steps 3 and 4

1.c) Easy-peasy!  'Right, so first we need to get some credentials from twitter so we can access the API.  Not a hard process, just login to Twitter Developers, go to My Applications by hovering over your account icon on the upper-right, then click the Create a new application button, also on the upper-right.  Fill out all the info, then we'll need to grab a few values once the application page has been created.  The Consumer Key and Consumer Secret at the top of the page are the first two values we'll need, then we'll scroll down to the bottom of the page, click the Create Access Token button, and grab the Access Token and Access Token Secret values.  For now we'll just stick these in a text file somewhere for future reference.

1.d) Finally the moment we've all been waiting for, getting down with cpp (yeah you know m...ok, ok that's enough of that).  As with most C++ projects, we'll start with some includes and using directives:

#include <iostream>
#include "cinder/app/AppBasic.h"
#include "cinder/gl/gl.h"
#include "cinder/gl/TextureFont.h"
#include "cinder/Rand.h"
#include "cinder/Utilities.h"
#include "json/json.h"
#include "twitcurl.h"

using namespace ci;
using namespace ci::app;
using namespace std;

Outside of the normal Cinder includes, we'll be using Rand and TextureFont to draw our list of tweet words on screen, and we'll be using Utilities, twitcurl, and json to fetch, parse, and set up our twitter content for drawing.

1.e) Let's set up our app class next, should be no surprises here:

class TwitCurlTestApp : public AppBasic
{
public:
    //Optional for setting app size
    void prepareSettings(Settings* settings);

    void setup();
    void update();
    void draw();

    //We'll parse our twitter content into these
    vector<string> temp;
    vector<string> words;

    //For drawing our text
    gl::TextureFont::DrawOptions fontOpts;
    gl::TextureFontRef font;

    //One of dad's pet names for us
    twitCurl twit;
};

Ok, so I may have lied just a tiny bit.  If you're coming from the processing or openFrameworks lands, notice we need to do a little bit of setup before drawing text, but it's nothing daunting.  We'll see this a bit with Cinder as we get into more projects, there's a little more setup and it does require a little bit more C++ knowledge to grok completely, but it's nothing that should throw anyone with even just a little scripting experience.  That said, a little bit of C++ learnings can never hurt.

1.f) Time to implement functions!  If we're choosing to implement a prepareSettings() method, let's go ahead and clear that first.  For this tutorial, I'm going with a resolution of 1280x720, so:

void TwitCurlTestApp::prepareSettings(Settings* settings)
{
    settings->setWindowSize(1280, 720);
}

1.g) Onward!  Let's populate our setup() method now.  The first thing we'll want to do is setup our canvas and drawing resources, which means loading our font and setting some GL settings so our effect looks cool-ish:

gl::clear(Color(0, 0, 0));
gl::enableAlphaBlending(false);
font = gl::TextureFont::create(Font(loadFile("acmesa.TTF"), 16));

1.h) Now it's time to warm up the core, or I guess you could we could call it setting up our twitCurl object, so let's get out those Consumer and Access tokens and do something with them:

//Optional, i'm locked behind a corporate firewall, send help!
twit.setProxyServerIp(std::string("ip.ip.ip.ip"));
twit.setProxyServerPort(std::string("port"));

//Obviously we'll replace these strings
twit.getOAuth().setConsumerKey(std::string("Consumer Key"));
twit.getOAuth().setConsumerSecret(std::string("Consumer Secret"));
twit.getOAuth().setOAuthTokenKey(std::string("Token Key"));
twit.getOAuth().setOAuthTokenSecret(std::string("Token Secret"));

//We like Json, he's a cool guy, but we could've used XML too, FYI.
twit.setTwitterApiType(twitCurlTypes::eTwitCurlApiFormatJson);

Hopefully this all makes sense and goes over without a hitch.  Never a bad idea to scroll through everything and look for the telltale red squiggles, or if you're lazy like me, just hit the build button and wait for errors.



    Since we're only going to be polling twitter once in this demo, we'll do all of our twitter queries in the setup() method as well.  Let's take a look at the main block of code first, then we'll go through the major points:

if(twit.accountVerifyCredGet())
{
    twit.getLastWebResponse(resp);
    console() << resp << std::endl;
    if(twit.search(string("perceptualcomputing")))
    {
        twit.getLastWebResponse(resp);

        Json::Value root;
        Json::Reader json;
        bool parsed = json.parse(resp, root, false);

        if(!parsed)
        {
            console() << json.getFormattedErrorMessages() << endl;
        }
        else
        {
            const Json::Value results = root["results"];
            for(int i=0;i<results.size();++i)
            {
                temp.clear();
                const string content = results[i]["text"].asString();
                temp = split(content, ' ');
                words.insert(words.end(), temp.begin(), temp.end());
            }
        }
    }
}
else
{
    twit.getLastCurlError(resp);
    console() << resp << endl;
}

    This code should read pretty straightforward, there are really just a few ideas we need to be comfortable with to make sense of things:

1) Both Jsoncpp and twitcurl follow a similar paradigm (which pops up in a lot of places, truth be told) wherein we get a bool value back depending on the success or failure of the call.

2) The pattern for using twitcurl is a) make a twitter api call b) if successful, .getLastWebResponse(), if not .getLastCurlError().

3) There are a few different constructors for Json::Value, but for our purposes the default is sufficient.

4) Json members can be accessed with the .get() method or via the [] operator, es.g. jsonvalue.get("member",default), jsonvalue["member"].  I'm just using the [] operator, but either one seems to work.

That all in mind, let's walk through that last block a chunk at a time.

2.a) First, we need to make sure we can successfully connect to the twitter API, and here we see the twitcurl pattern in action.  .accountVerifyCredGet() "logs us in" and verifies our consumer and access keys, then returns some info about our account.  If all went according to plan (unlike the latest reincarnation), we should see the string representation of our jsonified twitter account info in the debug console:

if(twit.accountVerifyCredGet())
{
    twit.getLastWebResponse(resp);
    console() << resp << endl;

console() returns a reference to an output stream, provided for cross-platform friendliness.  Just think of it as Cinder's cout.

2.b) Now the fun stuff, let's get some usable data from twitter.  We'll do a quick twitter search, then get a json object from the result, provided everything goes well (from here on out, let's just assume that happens, if something goes horribly awry, email me and we'll work it out):

    if(twit.search(string("perceptualcomputing")))
    {
        twit.getLastWebResponse(resp);

        Json::Value root;
        Json::Reader json;
        bool parsed = json.parse(resp, root, false);

        if(!parsed)
        {
            console() << json.getFormattedErrorMessages() << endl;
        }

Hopefully nothing too hairy here, there's that twitcurl pattern again.  We do our search with our term of choice (note this could be a hashtag or an @name too), catch the result into a string, then call our json reader's parse() method.  The false argument for parse() just tells our reader to toss any comments it comes across while parsing the source string.  In this case, since we know what keys we're looking for, it's probably not a big deal, but if we were ever in a situation where we were going to have to query all the members to find something specific, having less noise might be a good thing.

2.c) Ok, since for the duration of this tutorial we're living in a perfect world, everything went according to plan, there were no oauth or parsing errors, and now we have a nice, pretty json egg ready to be cracked open and scrambled.  Let's get our tweets, split them up, and stash them in our string vector, then we'll be ready to make some art.

        else
        {
            const Json::Value results = root["results"];
            for(int i=0;i<results.size();++i)
            {
                temp.clear();
                const string content = results[i]["text"].asString();
                temp = split(content, ' ');
                words.insert(words.end(), temp.begin(), temp.end());
            }
        }
    }
}

Again, nothing crazy here, in fact I'm sorta starting to feel bad for making people read this since i'm not doing any crazy 3d, shadery, lighting, particle, meshy awesomeness, it's just simple parsing operations...Ah well, the sexy bullshit (as the good Josh Nimoy calls it) is coming, I promise.  One of the things to be aware of here is that Json::Value is really good about parsing data into the proper types for us.  As I mentioned earlier, the docs present a few different constructors, but we're not using any of those here.  Querying the "results" key (which contains all of our search results) gives us back a list we can iterate through in fairly simple order.  So all we do is parse that, then for every element in our array, we get its "text" key, which contains the actual body of a tweet.  Lastly, we take that text and use Cinder's built-in string splitter, which should be quite familiar to you if you've ever split a string in a different language.



    Looks like all we have left is to make some stuff happen on-screen, so same as we did with the setup() method, let's take a glance at the code first, then we'll break it down, although if you're already familiar with Cinder, there probably won't be anything new here...

void TwitCurlTestApp::draw()
{
    gl::color(0, 0, 0, 0.015f);
    gl::drawSolidRect(Rectf(0, 0, getWindowWidth(), getWindowHeight()));

    int numFrames = getElapsedFrames();
    if(numFrames%15==0)
    {
        if(words.size()>0)
        {
            int i = numFrames%words.size();

            gl::color(1, 1, 1, Rand::randFloat(0.25f, 0.75f));
            fontOpts.scale(randFloat(0.3f, 3.0f));
            font->drawString(words[i],
                Vec2f(Rand::randFloat(getWindowWidth()),
                    Rand::randFloat(getWindowHeight())),
                fontOpts );
        }
    }
}

3.a) No messing around, let's get right to it.  If you've ever done anything in processing, you're probably familiar with the technique we're implementing with these two lines of code to fade the foreground a bit between frames, i.e. set the fill color to black with some amount of transparency and draw a rectangle the size of the screen.

    gl::color(0, 0, 0, 0.015f);
    gl::drawSolidRect(Rectf(0, 0, getWindowWidth(), getWindowHeight()));

3.b) The last step then, is to draw some words to the screen.  We'll grab a new word every 15 frames, set the fill color to white (also with some amount of transparency), scale the font by a random amount, and draw the word to a random location in the window. 

    int numFrames = getElapsedFrames();
    if(numFrames%15==0)
    {
        if(words.size()>0)
        {
            int i = numFrames%words.size();

            gl::color(1, 1, 1, Rand::randFloat(0.25f, 0.75f));
            fontOpts.scale(Rand::randFloat(0.3f, 3.0f));
            font->drawString(words[i],
                Vec2f(Rand::randFloat(getWindowWidth()),
                    Rand::randFloat(getWindowHeight())),
                fontOpts );
        }
    }
}

At this point, we should be able to build/run the project and hopefully see something similar to this:


If something has gone horribly awry, send me an e-mail or hit me up on github.  I've put the project up on github as well, but be advised you may have to change some of the project settings to reflect your own build environment.  For the scope of my project, I've got quite a bit more twitter to learn, including how to manage tweets, maybe how to deal with the streaming API, and a few other things, but that's all down the road.  Next up:

Wednesday, January 16, 2013

building twitcurl in visual studio 2010

UPDATE 20130122.1330: Verified this build chain does let you query twitter from Cinder, that being the goal.  Yeah, yeah, i should've tested that too;P  I don't have a really fun tutorial yet, just printing to the app::console(), but yeah, it works, so go forth and...uhh...twinderifiy?

    If you're wondering where the next round of C4CNC is, fear not, the manuscript is actually done and waiting to get some design and formatting love.  I wasn't kidding when I said this is probably a bad time to embark on a project that required some time and attention, but I'm committed to delivering on that.  Just got back from a great weekend of openFrameworkshops with Reza Ali and Josh Nimoy at GAFFTA, so i'm...not charged, but definitely refreshed and ready to keep cranking on creative coding related work, and especially C++ work.  I've really been dragging my feet on C++, but this year we're doing it live.  Seriously, my brain is so full of things i want to explore, prototype, visualize, maaaan...


    To that end, it's time to get cracking on an installation for GDC, my favorite time of year. Hopefully since I'm getting started sooner on this than I did for my ill-fated CES installation attempts, this one will go all the way. We've decided to do a twitter visualizer, and since I've decided that this year I'd like to do much more work in C++, I'm going with Cinder (of course).

    The first bump-in-the-road I came across is the lack of any official C++ support for twitter, but there are a few different twitter c++ libraries that have been written by various external parties. I've settled on twitcurl because it seems like the lightest, most straightforward version. The current download doesn't support Visual Studio 2010 though, which means the whole dependency chain needs to be rebuilt. It's not a terribly hard process, but there aren't a ton of good directions on the website, and in fact I got more out of the directions for building and using libcurl. I'm going to try and present a condensed version here, mainly for my own reference if I have to do this again, but also for anyone else trying to get up and running with C++/twitter in short order.


    I'm going to assume you've got some experience setting up Visual Studio projects, so I'm not going to go too deep into the specifics of that. First up, we need to grab the source distros:

openssl - Download (1.0.1c is latest as of this writing)
libssh2 - Download (1.4.3 is latest as of this writing)
libcURL - Download (7.28.1 is latest as of this writing)
twitcurl - Checkout SVN

    Now before we get down to business, I'm going to recommend a little bit of housekeeping.  These projects are all rather noisy, i.e. there are a lot of folders, a lot of files, solutions, workspaces, and support files for different IDEs, and...well you get the idea.  This may be 101 for some folks, but it's worth jotting down.  I've set my folder structure up so, feel free to adopt this or something similar (or ignore completely):

CPP/
  libs/
    src/
      curl-7.28.1/
      libssh2-1.4.3/
      libtwitcurl/
      openssl-1.0.1c/
    build/
      libcurl/
        include/
        lib/
          Debug/
          Release/
      libssh2/
        include/
        lib/
          Debug/
          Release/
      libtwitcurl/
        include/
            curl/
        lib/
          Debug/
          Release/
      openssl/

    Again, this is really just a suggestion based on how i store all my libraries on my machine, it's just for convenience.  That all in place, let's get to building some dependencies.

    All the directions are taken from the following document, which I HIGHLY recommend reading.  There are some really important points here that make all the difference between odd linker errors and not.

openssl


1) Install Perl.  I used ActivePerl, but any distribution should be sufficient, really you just need it to run some build configuration scripts.  The doc also recommends using NASM, but I haven't seen any disadvantage of not using it.  That said, I can't really comment, because I haven't seen the advantages of using it either.

2) Open a Visual Studio command line and switch over to your openssl source root directory. You may need to add perl to your path, which you can do by issuing the command:

path=%PATH%;<your perl executable folder>

3) Now we can configure and kick off our build. Issue the following commands (there'll be a pause in between as the scripts run):

perl Configure VC-WIN32 --prefix=<your openssl build path's root>
ms\do_ms
nmake -f ms\nt.mak
nmake -f ms\nt.mak test
nmake -f ms\nt.mak install

<your openssl build path's root> should be just that, the root folder of your desired openssl build with forward slashes.  In fact, if you jump back up and look at how I've laid out my folder, you'll see I have no folders under my openssl folder by design.  This is because the openssl build process creates include, lib, and a few other folders for you.  Also, pay close attention to the output of the test step, you shouldn't see any errors, but if you do, retrace your steps and try the build again.

From here on out, it's all in Visual Studio, so let's get the rest of our libraries built. So long, command line environment!

libssh2


1) Open the Visual Studio project, located at <your libssh2 source root>\win32\libssh2.dsp and take the project through the Visual Studio 2010 conversion process.

2) Now we need to configure the LIB Debug build configuration.  We need to add openssl as a dependency, so first, add the path to the openssl include folder to the C/C++ > General > Additional Include Directories.

3) We also need to set the C/C++ > Code Generation > Runtime Library option to Multi-threaded Debug (MTd).  This is easily the most important step in the whole process, every other project will need to have this set, or you'll get some weird linker errors.

4) Next, we need to add the openssl libraries to our linker dependencies.  Add libeay32.lib and ssleay32.lib to the Librarian > General > Additional Dependencies field; Be sure to also add <your openssl build root>\lib to the Librarian > General > Additional Library Directories field.

5) The last bit of configuration is to set the Librarian > General > Output File field to wherever you'd like the final lib file to end up.  In my case, the value is lib\build\libssh2\lib\Debug\libssh2.lib.  Be sure to configure the LIB Release configuration as well. The steps are all the same, save the output file settings.

6) Build the project and ignore the LNK4221 warnings, they won't affect anything here.

Whew!  Halfway done, now comes the main event, libcurl.  Twitcurl and any projects you build with twitcurl depend on this, so let's plow through and get tweeting from C++ (and Cinder (or ofx, or whatever your C++ framework of choice be)).


bro::comeAt(&me);

libcurl


1) For libcurl, we need to setup libssh2 as a dependency, so open the Visual Studio project <your curl source root>\lib\libcurl.vcproj and add the include path, the library, and the library path for your libssh2 build to the appropriate fields.

2) Remember to also set the C/C++ > Code Generation > Runtime Library to Multi-Threaded Debug (MTd) and stay odd linker error free!

3) libcurl requires a few preprocessor definitions.  To set these up, open the C/C++ > Preprocessor > Preprocessor Definitions window and copy-paste the following block below the existing definitions:

CURL_STATICLIB
USE_LIBSSH2
CURL_DISABLE_LDAP
HAVE_LIBSSH2
HAVE_LIBSSH2_H
LIBSSH2_WIN32
LIBSSH2_LIBRARY

4) If you've setup a custom folder structure, remember also to set your output file settings to wherever you'd like libcurl to sit after it gets built.

5) Hit build and you should be good to go.  All that's left now is to build twitcurl and you'll (we'll, i'll) be tweeting in style, because C++ never goes out of style.  Weird style fads and convoluted paradigms might, but that's a whole other conversation.

twitcurl


The twitcurl project page and wiki are a little odd and convoluted, so I would say those may not the best places to go for information on the project.  Probably a good idea to just checkout the source and make like Kenobi talking to storm troopers talking to Kenobi...(yo, dawg)


1) We'll need to do a little more housekeeping, this time with the twitcurl source.  In the <your twitcurl source root>\libtwitcurl folder, you'll see two subfolders, curl and lib. These folders contain the libcurl dependencies for twitcurl, but as we mentioned earlier, these are out of date.  At this point, we can take a few different approaches.  The end goal is to replace the existing libcurl dependencies with the ones we built previously, so we can replace the contents of the curl and lib folders with the contents from our libcurl build, or we can ignore these and change the project configurations. I chose to change the project configurations so I wouldn't have duplicates floating around.  Ultimately, we're going to need to change some configuration settings anyway, so I'm not sure there's much value in keeping the old dependencies around.

2) Once we've got a plan of action (keep,delete,etc), let's pop open libtwitcurl/twitcurl.sln in Visual Studio and replace all the references to curl with the paths to our previously built libcurl.  We need to update a few fields with the relevant info:

C/C++ > General > Additional Include Directories
Librarian > General > Additional Dependencies
Librarian > General > Additional Library Directories
Librarian > General > Output File (optional)
Librarian > General > Additional Dependencies (also add ws2_32.lib to this field)

3) Next, let's not forget to set the C/C++ > Code Generation > Runtime Library to...Yep, Multi-threaded Debug (MTd).

4) Lastly, let's add CURL_STATICLIB to C/C++ > Preprocessor > Preprocessor Definitions and build the project. If everything's setup correctly and all your previous builds of the dependency chain succeeded, congrats!  You now have everything you need to send tweets in C++.  Take a moment and be awesome (or keep being awesome if you already are)!


    So now it's pretty much just using twitcurl in a project.  Building the included twitterClient is pretty simple, we just need to:

1) Add our builds of libtwitcurl and libcurl as dependencies
2) Add ws2_32.lib as a dependency
3) Add the CURL_STATICLIB Preprocessor Definition
4) Set the C/C++ > Code Generation > Runtime Library option to...whaaaat?
5) Build that muthah (out).  We'll need to change some of the URLs in the project, but otherwise it should be a straight ahead process.

    Step one down, and trust me when I say this is monumental.  If I learned anything from this process it's RTFM!!!  TWICE!!!!  I had the hardest time getting things to build because I glossed over a step here and there and didn't read all the little details about what settings needed to be which specifically.  But that's all behind us now, so next we need to get tweeting from Cinder.  For the next segment, I'll probably recreate Jer Thorp's twitter and processing tutorial in Cinder just to get up and running.  Stay Tuned!

Saturday, December 29, 2012

C4CNC101 - Section 1: Intro To Functions

DISCLAIMER:
(1) If you are already familiar with functions, variables, types, otherwise coding basics, C4CNC101 is not for you.  I'd recommend taking a look at something like The Nature Of Code if you're interested in getting up and running with processing.
(2) A familiarity with digital art in general, including coordinate systems, pixels, etc will be extremely helpful.  If you've ever used Photoshop, Illustrator, or any other digital art program, 2d or 3d, you should be good to go.
(3) If you're a programmer, you'll probably find tons of inconsistencies or things i'm glossing over.  My goal here is not to teach programming, it's more to get people who want to get into using code as a tool to create or augment the creation of art up and running, enough to give them the foundation knowledge to research deeper if they so choose.  I've done alot of thinking about this and I believe the information as I've presented it is true in spirit and in the scope of processing.

header
    Ok, so hopefully by now you've downloaded and installed processing, signed up for an OpenProcessing account, and joined the C4CNC Classroom on OpenProcessing.  The first step is really the only requirement, but i do recommend at least peeking around OpenProcessing to get an idea of what's possible.  I'll warn you in advance that if you're just starting out, it can be pretty easy to get overwhelmed by the breadth and depth of content therein, but fear not!  Hopefully by the time we're through these first five lessons, you'll know enough to read through some of the sketches and even build your own sketches based off of them.  As I mentioned in the last post, if you come across any sketches or effects you'd like to remix, breakdown, or dive into deeper, let me know and I'll work something out for a future set of tutorials.  Alright, so let's begin!

    First, let's conceptualize a computer program as nothing more than a set of commands or instructions that processes information and produces results based on the specifics of the information and the commands.  While that's a bit of an oversimplification, on some level this holds true for any program, from the small visualization sketches we'll be writing here, all the way up to full on operating systems like Windows or Linux.  We call these instructions functions and we call the information data.  So let's write our first program.  Open processing and type the following function:

ellipse(50, 50, 50, 50);

    Once that's in place, press the Run button (it looks like a 'Play' button) in the upper left hand corner.  Alternately, you can check out the sketch on OpenProcessing(1-1: Basic Functions), although I highly recommend you follow along by typing the code yourself to get the most out of these lessons.  Either way, you should see something like the following:

Step1_0

CODERSPEAK: When we issue a command in a program, we say we are calling the function or making a function call, and when we provide data to a function, we say we are passing an argument (or arguments).  So when we issue a command and give it some information, we are calling a function with arguments.

    This may not look like much, but it's actually a valid processing sketch, so congrats.  In some languages, Python for example, a single function like this could also comprise a valid and complete program, so not bad for a first step!  Sure, it's not very exciting and doesn't do much, but we'll get there.

    Now, let's take a moment and break down our function call.  For our intents and purposes, every function call will be a name followed by a set of parentheses.  If we're passing arguments to the function, they'll be between the parentheses, separated by commas.  And finally, we end our function call with a semicolon, so processing knows to move on to the next function.  Thus, the skeleton for any function call is:

functionName(argument1, argument2, argument3, etc);

    Recall that we started out by defining a program as a set of commands(functions) that processes information(data) to produce a result.  Arguments are how we provide the data to a function.  In cases where we're passing multiple arguments, each argument is used by the function to perform a specific task along the way to producing the final result.  So in the case of our first sketch here, as the programmer we're telling processing to:

Draw an ellipse with a position of 50 pixels along the x-axis and 50 pixels along the y-axis, and a size of 50 pixels along the x-axis and 50 pixels along the y-axis.

    Most, if not all, publicly available coding tools and environments have references that describe (some in more detail than others) what each argument does.  For example, take a look at the reference page for the ellipse() function, which not only details the arguments, but also provides some useful tips on calling ellipse().

    Alright, so let's practice a bit by adding a few more functions.  Add another function before the ellipse() call, so your sketch contains the following function calls.  Note that we're changing some of the arguments to the ellipse() call, and you should feel free to change any of the arguments to any of the functions.  Experimentation is a key to learning!

size(400, 400);
ellipse(200, 200, 50, 50);

    As you can probably tell from the result, the size() function sets the size in pixels of our sketch's window.  Even though both functions take a different number of arguments and produce markedly different results, you can see that they both follow the same skeleton we outlined above, i.e.:

functionName(argument1, argument2, argument3, etc);

    Before we get a little more advanced, let's add a few more basic processing functions, again for practice, and also to see how we can affect what we're drawing on-screen so we can start getting an idea of the kind of drawing functionality that processing makes available to our sketches.  We're going to add three more function calls in-between our size() call and our ellipse() call: background(), stroke(), and fill().  Type these functions in as presented below:

size(400, 400);
background(0, 0, 0);
stroke(255, 255, 255);
fill(0, 128, 255);
ellipse(200, 200, 100, 100);

    As the saying goes, the more things change, the more things stay the same.  As we add functions, we see the results compound and the output become more complex, but in the end, all functions are called in the same manner using the same syntax.  Feeling comfortable typing in functions?  Then give the following exercises a try and see what you come up with.  Questions?  Please post them in the comments!

footer
EXERCISE 1: Draw 5 different ellipses with different radii and in different locations.  Be sure to check out the Processing Language Reference for ellipse() for more details on how the ellipse() function works.  Try changing some of the arguments to the other functions as well!
Exercise 1-1

EXERCISE 2: Take a look at the Language Reference for background(), stroke(), and fill().  Now, take the previous exercise and change the stroke and fill color for each ellipse. While you're at it, change the background color to something a bit friendlier than black, it's getting a bit gloomy in here...
Exercise 1-2

CODERSPEAK: You might be wondering how processing knows what to do when we call any of the functions presented here.  Well, most, if not all programming languages and environments come with a set of pre-existing functions and data that we use to build up our programs initially, which you'll often hear referred to as built-ins or library functions.  When writing programs, you'll use a combination of both built-in functions and data, as well as functions and data you define yourself.  We'll discuss this process in the next couple lessons.






PREVIOUS ARTICLES
Foreword
Project Preview

Friday, December 28, 2012

C4CNC: The Road Ahead...

    If you've already stopped over to the OpenProcessing Classroom, you'll notice there's not a ton of really exciting stuff there (yet).  The idea is that we're going to ramp into more advanced sketches from simple concepts, so we'll start slow-ish to get folks comfortable with both the ideas and just the act of typing code, then we'll start to speed up as we build the actual project.  That all said, I figured I'd toss up a quick preview of where we're going to end up by the end of C4CNC 201.

Step1_0
We'll start here...

teaser ...and end up here.
Watch the sketch in action

    If in your travels through OpenProcessing (or elsewhere) you see one or more effects you're interested in learning about, let me know! Given my limited creativity, I'm always looking for new project inspiration for tutorials, would be fun to piece together a tutorial from a few different effects/sketches. I guess I could just do that myself, but i'm curious as to the nature of other people's aesthetic sense...in a non-creepy way. Anyway, back to work, I should have the first lesson up later today.

Thursday, December 27, 2012

Coding For Creative Non-Coders

    I'm going to stop short of saying I've become a bad programmer over the last year, but I will definitely say I've written alot of bad code.  Well, alright, that's actually not true on two counts:
  • It hasn't been bad code, just poorly, well, no, lazily architected code.
  • I didn't really become a bad programmer, i just maintained my level of already not good programmering.


records_top
    That said, it's been really interesting making the transition from tools...eh...programmer to software prototyper/artist.  It's gotten me thinking quite a bit about what elements of coding are important to me as an artist and more than that, how I would present the idea of programming to someone who was interested in software art, or creative coding as it were.  I've often ranted about how the reason more people don't get into programming is not because the act itself is hard, but more because of how it's taught.  That's the problem I know I had with learning C++ especially, all the books start out with variables, then move onto simple functions, then eventually get to the meat of the language, but by then I'm just bored.  One could argue that people need to be introduced to the concepts slowly, which I agree with, but I think it's the order of the presentation and the way we connect concepts to each other that's up for review.  For example, when I'm in my (somewhat questionable) artist mind, I'm a very visual learner, I like to see things happen.  So when I have to read chapters that drone endlessly on about simple variables, of course I get bored.  In the same vein, I like building things.  I feel like if programming were presented in the context of building something, rather than a set of disjointed programs/code listings that just focus on single concepts, it would be easier for people to make the connection from theory to application.

sineart_banner

    So where am I going with this?  Well, me being the arrogant know-it-all that I am, I think I've come up with a good way to teach, not programming in full perse, but enough to get someone started down the path of creative coding.  Even though I'm convinced the world doesn't need another set of "Learn to code using processing" tutorials, I feel like I need to write this line of thinking down because it may just be useful. Or I may be crazy. Or...crazy useful, right, right? Anyway, if you're interested in following along, I'd recommend a few things before diving in:
    I'll admit i'm picking a rather lame time to kick this off, as I'm up to my nasal hairs in CES demos, but my goal is to have the first five sections done by mid-February. Stay tuned and I'll see you in the first lesson!

records_btm

Thursday, August 30, 2012

the perfect engine

        Every time i type "blogger.com" into my address bar i'm reminded of a rant penned by a game writer a while back railing against the idea of being called a "journalist" because he was, in fact, a blogger, and as such didn't need to be bound by the tenets of that horribly oppressive, creativity-killing force called "journalistic integrity".  This got me thinking about a conversation I was having a little while ago with a colleague about the death of Triple-A game development and consoles as we know them today.  I wondered at the time if that would give rise to a new form of game journalism where game writers aren't afraid to put together well thought out and well written articles that reflect the notion of an older readership, as opposed to  the current race for they eyes, hearts, and minds of 13 year old boys.  Oh well, one can dream.


Shuriken Particles

        This idea of games and misguided representation, self or otherwise, has been quite a topic of thought for me recently, especially where the term "interaction" is concerned.  Don't get me wrong, I love lying in bed playing xbox games on the ceiling (projectors, so awesome) or sitting at my PC playing whatever F2P MMO has my attention for the next month, but i've started to re-classify this sort of activity as something other than "interaction".  I mean sure, in the loosest sense of the word it is an interactive activity, but when I think of myself as an interactive developer/artist/performer, this is not what i classify as "interaction" or "interactivity".  I'll concede that games are a subset of a broader interactive media and entertainment classifier, but games do get most of the spotlight and are driving alot of the technology in that space.


Relentless, The REV

      Therein lies a problem.  We can look at things like the Wii and the Kinect and talk about how they redefined interaction, which sure, they did, but this kind of merging the physical and digital world through different interaction paradigms is based on much older work (watch Underkoffler's TED talk for the details) that most of the public is probably unaware of, or at least, has relegated to the realm of science fiction, or more recently to games and academia.  So of course, big technology hasn't had a huge incentive to make sweeping changes in how we interact with technology, but then i suppose that could be chalked up as "good business".  Unrelated, I would argue that "good business" is why the country is in such a sorry state, but that's for a different blog post by someone who isn't me.


More Shuriken Particles

        So this presents some really funny irony, at least from my perspective.  While alot of advanced interaction is being developed for and because of games, that idea of "good business" means that middleware vendors aren't necessarily rushing out to build functionality to support this sort of thing into their products, because how do you sell depth camera support to an industry and consumer base who have written depth cameras off as motion control gimmicks? Funny, this is the same ideology championed by a man who thought one of the killer features of his game was that you could pick up your own shit, but whatever.  I'm not here to skewer said vendors for not including this sort of support, but it does bring up an interesting idea, that of "graphics engines" vs "interaction engines".  It's been a running debate, the idea of Unity vs UDK vs ofx vs Cinder vs whatever, so it's alot to think about.  The distinction was solidified best to me in a post on the Cinder forums on the same topic.  Someone wrote "Life is easy if you stick to loading models (animated or not) into the scene graph, setting up transitions triggers, using basic particle emitters...", whereas "Cinder is made in a way that it's easy to import foreign technologies."  That pretty clearly outlines/sums up the difference between graphics and interaction engines in my experience. Being able to just have webcam access as a ready made call, or an easy path to adding an external SDK for some non-native hardware is key to quickly prototyping and building advanced interaction. While alot of game engines do have facilities for this, it's not always quick and easy, but I don't feel like this is the way it has to be.  I've always felt that one of the things that's really helped me think in terms of interaction design is having been around games for so long, so it seems logical that there would/could/should be some sort of convergence.  Not that there isn't already, search Vimeo and you'll find games made with Cinder and ofx sitting alongside interactive installations made with Unity.  I think if it were easier to build either type of experience on either platform, we'd truly have convergence between the idea of games and advanced interactivity/interaction.


Addition Subtraction

        Ultimately, I'm not saying Unity/UDK need gesture recognition or anything like that, just an easier way to get it into the engine.  Keep the .NET integration current, get rid of UnrealScript, etc, don't predicate everything on the idea of mouse and keyboard events, or at least give me an easier way to hook into them, that sort of thing.  No reason for game engines to stay in the dark ages of interaction and interaction engines to stay in the dark ages of rendering.

        Just some thoughts, nothing really meaningful here, i just hadn't blogged in a while and felt like writing some words.  For the record, I'm using both Unity and Cinder.  I've been playing with some new Unity stuff recently that's got me super excited, i'll be able to talk about that pretty soon here...


Cymatic Ferrofluid