Skip navigation

Monthly Archives: March 2009

! OK. Finally

Download the esnips code package to get green_man.ico!

/////////////////////////////////////////////
//                                         //
// Minimizing C++ Win32 App To System Tray //
//                                         //
// You found this at bobobobo's weblog,    //
// https://bobobobo.wordpress.com           //
//                                         //
// Creation date:  Mar 30/09               //
// Last modified:  Mar 30/09               //
//                                         //
/////////////////////////////////////////////

// GIVING CREDIT WHERE CREDIT IS DUE!!
// Thanks ubergeek!  http://www.gidforums.com/t-5815.html

#pragma region include and define
#include <windows.h>
#include <shellapi.h>
#include <stdio.h>

#ifdef UNICODE
#define stringcopy wcscpy
#else
#define stringcopy strcpy
#endif

#define ID_TRAY_APP_ICON                5000
#define ID_TRAY_EXIT_CONTEXT_MENU_ITEM  3000
#define WM_TRAYICON ( WM_USER + 1 )
#pragma endregion

#pragma region constants and globals
UINT WM_TASKBARCREATED = 0 ;

HWND g_hwnd ;
HMENU g_menu ;

NOTIFYICONDATA g_notifyIconData ;
#pragma endregion


LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);



#pragma region helper funcs
// These next 2 functions are the STARS of this example.
// They perform the "minimization" function and "restore"
// functions for our window.  Notice how when you "minimize"
// the app, it doesn't really "minimize" at all.  Instead,
// you simply HIDE the window, so it doesn't display, and
// at the same time, stick in a little icon in the system tray,
// so the user can still access the application.
void Minimize()
{
  // add the icon to the system tray
  Shell_NotifyIcon(NIM_ADD, &g_notifyIconData);

  // ..and hide the main window
  ShowWindow(g_hwnd, SW_HIDE);
}

// Basically bring back the window (SHOW IT again)
// and remove the little icon in the system tray.
void Restore()
{
  // Remove the icon from the system tray
  Shell_NotifyIcon(NIM_DELETE, &g_notifyIconData);

  // ..and show the window
  ShowWindow(g_hwnd, SW_SHOW);
}

// Initialize the NOTIFYICONDATA structure.
// See MSDN docs http://msdn.microsoft.com/en-us/library/bb773352(VS.85).aspx
// for details on the NOTIFYICONDATA structure.
void InitNotifyIconData()
{
  memset( &g_notifyIconData, 0, sizeof( NOTIFYICONDATA ) ) ;
  
  g_notifyIconData.cbSize = sizeof(NOTIFYICONDATA);
  
  /////
  // Tie the NOTIFYICONDATA struct to our
  // global HWND (that will have been initialized
  // before calling this function)
  g_notifyIconData.hWnd = g_hwnd;
  // Now GIVE the NOTIFYICON.. the thing that
  // will sit in the system tray, an ID.
  g_notifyIconData.uID = ID_TRAY_APP_ICON;
  // The COMBINATION of HWND and uID form
  // a UNIQUE identifier for EACH ITEM in the
  // system tray.  Windows knows which application
  // each icon in the system tray belongs to
  // by the HWND parameter.
  /////
  
  /////
  // Set up flags.
  g_notifyIconData.uFlags = NIF_ICON | // promise that the hIcon member WILL BE A VALID ICON!!
    NIF_MESSAGE | // when someone clicks on the system tray icon,
    // we want a WM_ type message to be sent to our WNDPROC
    NIF_TIP;      // we're gonna provide a tooltip as well, son.

  g_notifyIconData.uCallbackMessage = WM_TRAYICON; //this message must be handled in hwnd's window procedure. more info below.
  
  // Load da icon.  Be sure to include an icon "green_man.ico" .. get one
  // from the internet if you don't have an icon
  g_notifyIconData.hIcon = (HICON)LoadImage( NULL, TEXT("green_man.ico"), IMAGE_ICON, 0, 0, LR_LOADFROMFILE  ) ;

  // set the tooltip text.  must be LESS THAN 64 chars
  stringcopy(g_notifyIconData.szTip, TEXT("Green man.. here's looking at ya!"));
}
#pragma endregion

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR args, int iCmdShow )
{
  TCHAR className[] = TEXT( "tray icon class" );

  // I want to be notified when windows explorer
  // crashes and re-launches the taskbar.  the WM_TASKBARCREATED
  // event will be sent to my WndProc() AUTOMATICALLY whenever
  // explorer.exe starts up and fires up the taskbar again.
  // So its great, because now, even if explorer crashes,
  // I have a way to re-add my system tray icon in case
  // the app is already in the "minimized" (hidden) state.
  // if we did not do this an explorer crashed, the application
  // would remain inaccessible!!
  WM_TASKBARCREATED = RegisterWindowMessageA("TaskbarCreated") ;

  #pragma region add a console
  // add a console, because I love consoles.
  // To disconnect the console, just comment out
  // the next 3 lines of code.
  //// AllocConsole();
  //// AttachConsole( GetCurrentProcessId() ) ;
  //// freopen( "CON", "w", stdout ) ;
  #pragma endregion
  
  #pragma region get window up
  WNDCLASSEX wnd = { 0 };

  wnd.hInstance = hInstance;
  wnd.lpszClassName = className;
  wnd.lpfnWndProc = WndProc;
  wnd.style = CS_HREDRAW | CS_VREDRAW ;
  wnd.cbSize = sizeof (WNDCLASSEX);

  wnd.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  wnd.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  wnd.hCursor = LoadCursor (NULL, IDC_ARROW);
  wnd.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE ;
  
  if (!RegisterClassEx(&wnd))
  {
    FatalAppExit( 0, TEXT("Couldn't register window class!") );
  }
  
  g_hwnd = CreateWindowEx (
    
    0, className,
    
    TEXT( "Using the system tray" ),
    WS_OVERLAPPEDWINDOW,
    
    CW_USEDEFAULT, CW_USEDEFAULT, 
    400, 400, 

    NULL, NULL, 
    hInstance, NULL
  );

  // Add the label with instruction text
  CreateWindow( TEXT("static"), TEXT("right click the system tray icon to close"), WS_CHILD | WS_VISIBLE | SS_CENTER,
                  0, 0, 400, 400, g_hwnd, 0, hInstance, NULL ) ;
  
  // Initialize the NOTIFYICONDATA structure once
  InitNotifyIconData();


  ShowWindow (g_hwnd, iCmdShow);
  #pragma endregion

  MSG msg ;
  while (GetMessage (&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }


  // Once you get the quit message, before exiting the app,
  // clean up and remove the tray icon
  if( !IsWindowVisible( g_hwnd ) )
  {
    Shell_NotifyIcon(NIM_DELETE, &g_notifyIconData);
  }

  return msg.wParam;
}


LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  if ( message==WM_TASKBARCREATED && !IsWindowVisible( g_hwnd ) )
  {
    Minimize();
    return 0;
  }

  switch (message)
  {
  case WM_CREATE:

    // create the menu once.
    // oddly, you don't seem to have to explicitly attach
    // the menu to the HWND at all.  This seems so ODD.
    g_menu = CreatePopupMenu();

    AppendMenu(g_menu, MF_STRING, ID_TRAY_EXIT_CONTEXT_MENU_ITEM,  TEXT( "Exit" ) );

    break;
  
  case WM_SYSCOMMAND:
    switch( wParam & 0xfff0 )  // (filter out reserved lower 4 bits:  see msdn remarks http://msdn.microsoft.com/en-us/library/ms646360(VS.85).aspx)
    {
    case SC_MINIMIZE:
    case SC_CLOSE:  // redundant to WM_CLOSE, it appears
      Minimize() ; 
      return 0 ;
      break;
    }
    break;


  // Our user defined WM_TRAYICON message.
  // We made this message up, and we told
  // 
  case WM_TRAYICON:
    {
      printf( "Tray icon notification, from %d\n", wParam ) ;
      
      switch(wParam)
      {
      case ID_TRAY_APP_ICON:
        printf( "Its the ID_TRAY_APP_ICON.. one app can have several tray icons, ya know..\n" ) ;
        break;
      }

      // the mouse button has been released.
      
      // I'd LIKE TO do this on WM_LBUTTONDOWN, it makes
      // for a more responsive-feeling app but actually
      // the guy who made the original post is right.
      // Most apps DO respond to WM_LBUTTONUP, so if you
      // restore your window on WM_LBUTTONDOWN, then some
      // other icon will scroll in under your mouse so when
      // the user releases the mouse, THAT OTHER ICON will
      // get the WM_LBUTTONUP command and that's quite annoying.
      if (lParam == WM_LBUTTONUP)
      {
        printf( "You have restored me!\n" ) ;
        Restore();
      }
      else if (lParam == WM_RBUTTONDOWN) // I'm using WM_RBUTTONDOWN here because
      {
        printf( "Mmm.  Let's get contextual.  I'm showing you my context menu.\n" ) ;
        // it gives the app a more responsive feel.  Some apps
        // DO use this trick as well.  Right clicks won't make
        // the icon disappear, so you don't get any annoying behavior
        // with this (try it out!)

        // Get current mouse position.
        POINT curPoint ;
        GetCursorPos( &curPoint ) ;
        
        // should SetForegroundWindow according
        // to original poster so the popup shows on top
        SetForegroundWindow(hwnd); 

        
        
        // TrackPopupMenu blocks the app until TrackPopupMenu returns
        printf("calling track\n");
        UINT clicked = TrackPopupMenu(
          
          g_menu,
          TPM_RETURNCMD | TPM_NONOTIFY, // don't send me WM_COMMAND messages about this window, instead return the identifier of the clicked menu item
          curPoint.x,
          curPoint.y,
          0,
          hwnd,
          NULL

        );
        printf("returned from call to track\n");


        // Original poster's line of code.  Haven't deleted it,
        // but haven't seen a need for it.
        //SendMessage(hwnd, WM_NULL, 0, 0); // send benign message to window to make sure the menu goes away.
        if (clicked == ID_TRAY_EXIT_CONTEXT_MENU_ITEM)
        {
          // quit the application.
          printf("I have posted the quit message, biatch\n");
          PostQuitMessage( 0 ) ;
        }
      }
    }
    break;

  // intercept the hittest message.. making full body of
  // window draggable.
  case WM_NCHITTEST:
  {
    // http://www.catch22.net/tuts/tips
    // this tests if you're on the non client area hit test
    UINT uHitTest = DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam);
    if(uHitTest == HTCLIENT)
      return HTCAPTION;
    else
      return uHitTest;
  }

  case WM_CLOSE:
    printf( "Got an actual WM_CLOSE Message!  Woo hoo!\n" ) ;
    Minimize() ;
    return 0;
    break;

  case WM_DESTROY:
    printf( "DESTROY!!\n" ) ;
    PostQuitMessage (0);
    break;

  }

  return DefWindowProc( hwnd, message, wParam, lParam ) ;
}



Download esnips code package (thanks esnips! :)

(donation should be to bill.sherif@gmail.com)

Here’s a perfect example of token pasting in C++.

On about line 427 of WinNT.h, we see:

#define __TEXT(quote) L##quote

Now what this does is basically take any string you pass __TEXT( “some string” ) and prepend an L.

So in short it turns

__TEXT( "some string" )

into

L"some string"

So, its the magic of ## that makes it work. Basically when you write

#define __TEXT(quote) L##quote

You’re saying, ok, treat quote like a variable. In the last part of the #define we see ##quote, basically that is HOW YOU BACKREFERENCE the quote “variable” of the macro that was used earlier, in a “token pasting” way – basically you know that if you tried to write:

#define __TEXT(quote) Lquote

Then it would try and look for some symbol called Lquote, which basically doesn’t exist. What you want is to PREPEND AN L in front of (whatever quote is).

So,

#define __TEXT(quote) L##quote

The double pound ## there just says to “concatenate” or smush together the literal L (since L backreferences no symbol, it will resolve to the literal character ‘L’ at compile time), smush on there quote, which will backreference resolve into “some strong”

Here’s another one

// this:
#define foreach( x, y, z ) for( vector<##x##>::iterator y = z.begin(); y != z.end(); ++y )

// turns:
foreach( string, iter, infoVector )
// ( foreach string iter in infoVector )

// into:
for(vector<string>::iterator iter = infoVector.begin(); iter != infoVector.end(); ++iter)

First, get wolfgang engel’s books for FREE!!. MAN. I’m so happy he released them.

More to come

I’ve been listening to stuff and watching stuff.

I JUST got The Blank Theory, and they sound remarkably like Breaking Benjamin. Its kind of odd.

I actually got this album “Beyond the Calm of the Corridor”, and its much better than I expected, on the recommendation of Amy Lee :). I found tis REALLY old intefview where she says they’re awesome so naturally i go out and get it.

Does Python have blockscoping?

We all know that Python treats blocks a little differently than { curly bracketed } languages like C or C++

But it actually treats them a lot differently. Example below shows

# python scoping
x = 5
if x is 5:
  print 'x is 5'
  y = 1000
else:
  print 'x is not 5'
  y = 19

print y  # see 1000, no errors.

# conclusion:  python does not have block scope.
# but i'm not one to rely on it.

leighton meester really has been blowing up the small screen, for me.

leighton meester in a dress

She went from a strange little girl I didn’t understand to one of my favorite characters on the show

whoo! go meester!

UnboundLocalError: local variable referenced before assignment

So that sucks

Howdya fix that?

I’ll tell you. First, a simple example of the problem:

#This is valid python 2.5 code
#My global variable:
USER_COUNT = 0


#functions:
def Main():    
  AddUser()

def AddUser():
  print 'There are',USER_COUNT,'users so far'


# actually run Main()
Main()

^ That program WORKS FINE. Function AddUser() just references the USER_COUNT variable, which was declared as a global (outside of any of the function blocks).

Here’s where it goes wrong: when we try to write to or we try to update the value of the global variable

#USER_COUNT is a GLOBAL variable
USER_COUNT = 0


def Main():    
  AddUser()

def AddUser():
  USER_COUNT = USER_COUNT + 1
  print 'There are',USER_COUNT,'users so far'
  

Main()

Then we get: UnboundLocalError: local variable ‘USER_COUNT’ referenced before assignment

So that sucks.

The reason this happens is because AS SOON AS YOU WRITE TO A VARIABLE, that variable is AUTOMATICALLY considered LOCAL to the function block in which its declared. Namely:

#USER_COUNT is a GLOBAL!
USER_COUNT = 0

def AddUser():
  USER_COUNT = USER_COUNT + 1
  print 'There are',USER_COUNT,'users so far'

EVEN THOUGH we declared USER_COUNT as a GLOBAL, the simple act of WRITING TO IT __ANYWHERE__ in the function scuzzles-up the “globalness” of the USER_COUNT variable, and like, automatically makes ANY use of USER_COUNT refer to a LOCAL VARIABLE inside of AddUser().

So howdya fix it?

Easy! You do this:

#global
USER_COUNT = 0

def Main():    
  AddUser()

def AddUser():
  global USER_COUNT ######!!! IMPORTANT !!!  Make sure
  # to use the GLOBAL version of USER_COUNT, not some
  # locally defined copy of that.  I think this
  # might be a python feature to stop functions from
  # clobbering the global variables in a program
  USER_COUNT = USER_COUNT + 1
  print 'There are',USER_COUNT,'users so far'
  
  

Main()

This is an ok-nice feature that might stop a program’s functions from clobbering the globals (since you really have this “just use it” attitude to a variable and you may have no clue that you’re clobbering a global), but really it might be nice if python were more consistent and required use of this global thing for BOTH read/write. Though I guess it could be kinda convenient behavior .. I don’t know yet, haven’t programmed in python for long enough.

Running code in python may seem a bit tricky at first…

I now understand the reason that everyone seems to use the if __name__ == ‘__main__’ HACK (and yes, it is a hack, generally when you see use of double underscored surrounded __something__ that’s accessing an internal attribute, and generally in my opinion at this point, that kind of thing __shouldn’t__ be required.)

But anyway, I’ll show you how to write a simple python program (assuming you know the general syntax) so you don’t end up with some weird spaghetti, .

Exploring what works and what doesn’t


print 'testing my script'

#f1()  # does not work here, the interpretter
         # has not "seen" the def for f1() yet
#f2()  # does not work here, f2() unseen as yet

def f1():
  print 'f1 is running'
  
f1()  # works
#f2()  # will not work here, f2 not def yet
  
def f2():
  print 'f2 is running'
    
f1()  # works, f1 has been def'd
f2()  # works, f2 has been def'd

The “right way”

print 'testing my script'

##
# begin function defs
# just put all functions up here, together
def Main():    
  f1()  # works
  f2()  # works

def f1():
  print 'f1 is running'
  
def f2():
  print 'f2 is running'
#
# end function defs
##

# just execute main now.
# because the interpretter will have "seen"
# ALL the functions that Main() references at this point,
# it doesn't matter if the definition for Main() appears
# before or after f1 and f2.
Main()

has news.. interesting news.., apparently, parrot 1.0.0 has been released. parrot has implementations of brainfuck, lolcode, and a bunch of other weird languages, as well as implementations of python and a .NET interpreter!

i wonder what the use of parrot is, really practically, what its performance is like wrt the “real” interpreters for these languages (the “real” languages I mean)

of course this news was just on slashdot, if only i just read slashdot..

You know, I find this really weird.

In C#, if you have a class

class Whatever
{
  private string unused ;
}

And you try and compile this class, of course you’ll see:

Warning 1 The field ‘Whatever.unused’ is never used

And if you assign it a value but never read from it:

class Whatever
{
  private string unused ;

  public Whatever()
  {
    unused = "blah" ;
  }
}

You get

Warning 1 The field ‘Whatever.unused’ is assigned but its value is never used

BUT, if you assign it a special value:

class Whatever
{
  private string unused ;

  public Whatever()
  {
    unused = System.Environment.NewLine ;
  }
}

The warning goes away.. . ?

WHY? I had a such unused variable that was assigned System.Environment.NewLine and I only noticed by happenstance that the variable was indeed unused. Why doesn’t the compiler flag it?

I’m inspired after having watched doug talk about javascript this morning, to extend C#.

Well, how about a repeat keyword?

I’d like this to have easy syntax like:

repeat: 50
print(‘hi’);

Instead of having to use a for loop as a repetition mechanism. Here’s how it’d work:

using System;

public delegate void Repeat( Action func, int numTimes ) ;

class Program
{
  static Repeat repeat = delegate( Action f, int n )
  {
    for( int i = 0; i < n; i++ )
    {
      f();
    }
  };

  static void Main( string[] args )
  {
    repeat(

      delegate()
      {
        Console.Write( "hi " );
      },

      5 );

  }
}

This post really helped. In this post, this guy david says:

Hi Scott,

Here is one possibility:  If the old axis is _a_ and the new axis
is _a'_, use

theta = acos(_a_ dot _a'_)    (where 'dot' means dot product)
_axis_ = _a_ cross _a'_       (cross product)

then 

RotateWXYZ(theta,axis[0],axis[1],axis[2])   

will provide the desired rotation.  Don't forget to do the 
radians-to-degrees conversion before calling RotateWXYZ.


A much more efficient way to it if the original axis _a_ is
always the x axis is to build the matrix yourself.  First,
you need to find two vectors _b'_ and _c'_ which are
perpendicular to _a'_.  You can use vtkMath::Perpendiculars()
for this if you have a recent version of VTK.

Then, build the matrix by inserting the vectors into the matrix 
columns:

   a'[0]  b'[0]  c'[0]  t[0]  
   a'[1]  b'[1]  c'[1]  t[1]
   a'[2]  b'[2]  c'[2]  t[2]
   0      0      0      1

where _t_ is the translation you wish to apply after the rotation.

 - David

I wanna personally thank the dude.

But that wasn’t enough. There was also this post posted by none other than shawn hargreaves. He says:

When you’re working in 3D it’s generally best to avoid thinking in terms of rotations as angles. Trying to extract angle rotations lands you in a world of pain working out complex trig equations, which are not at all my idea of fun! This sort of thing can generally be done much more easily using vector and matrix math.

Ultimately, you want a matrix that describes the rotation of your object, but you can get there from a couple of vectors. One vector alone is not enough to describe a full orientation, though, because that still leaves one axis of freedom that the object could rotate to any angle around that vector.

Let’s start out by choosing a front vector for our orientation: you can get this by normalizing your movement vector.

Now we need vectors pointing right and up. To avoid squashing the object, these need to be perpendicular (at right angles to) to the front vector. We could guess that up might be roughly Vector3.Up, but that might need some adjustment to make it stay perpendicular to our front vector. Here’s how to do that:

– Compute a right vector by taking the cross product of your front vector and Vector3.Up, and normalizing that result

– Compute a properly perpendicular up vector by taking the cross product of the right vector that you just calculated and your front vector.

Now you have three vectors, all perpendicular to each other, that describe the orientation of your object. Turning these into a matrix is simple: start off with Matrix.Identity, then assign your new values to its Forward, Right, and Up properties.

I might have got some of those cross products the wrong way round (I’m terrible at remembering which way they go) so if your model comes out inverted, just swap the order of the arguments to the cross product calls.

The framework actually has a built in method that does almost the same thing as the above, in the Matrix.CreateLookAt method. You could pass Vector3.Zero as cameraPosition, your movement vector as cameraTarget, and Vector3.Up as cameraUpVector, and it will give back almost the same thing as the matrix I described above, only backward. Call Matrix.Transpose on the result, and you can use that for your object orientation.

very helpful indeed. thanks shawn!

Finally for understanding this crap more, the math of viewing matrices, including an explanation of what/how do it.

I do not like the lack of flexibility in how you call a base class constructor in C#:


Example of how its limiting: I’ve inherited the BoundingFrustum:

public class MyFrustum : BoundingFrustum
{
  public MyFrustum( Matrix value ) : base( value )
  {
    
  }
}

Because passing a matrix describing your frustum to the BoundingFrustum class constructor is REQUIRED, I have to call the base class constructor IMMEDIATELY with some matrix describing the frustum.

Now I personally, created this class so that the Frustum can remember its Eye, Look, Up vectors conveniently, and its View matrix and its Projection matrix.

SO, I write:

public class MyFrustum : BoundingFrustum
{
  Vector3 eye, look, up ;  Matrix view, projection ;
  public MyFrustum( Vector3 Eye, Vector3 Look, Vector3 Up, Matrix Projection ) : base( Matrix.CreateLookAt( Eye, Look, Up ) * Projection )
  {
    eye=Eye; look=Look; up=Up;
    projection=Projection;

    // NOW I HAVE TO RECOMPUTE THE VIEW MATRIX __AGAIN__!!
    // because i LOSt the value passed to the base class ctor
    // and I can't get it back
    view = Matrix.CreateLookAt( Eye, Look, Up ) ;

  }
}

You might say, “well just pass the View matrix and get the Eye from it!”

Well, you can’t do that without an inversion which is too expensive.

Wouldn’t it be better, C#, to let me just do something like:

public class MyFrustum : BoundingFrustum
{
  Vector3 eye, look, up ;  Matrix view, projection ;
  public MyFrustum( Vector3 Eye, Vector3 Look, Vector3 Up, Matrix Projection )
  {
    eye=Eye; look=Look; up=Up;
    projection=Projection;

    // NOW I HAVE TO RECOMPUTE THE VIEW MATRIX __AGAIN__!!
    // because i LOSt the value passed to the base class ctor
    // and I can't get it back
    view = Matrix.CreateLookAt( Eye, Look, Up ) ;

    base( view * projection ) ;  // This WOULD work much better
  }
}

The maximum number of characters in a Visual Studio 2008 column before it wraps is 11524.

I feel, like, wow.

I was trying to create a simple tet in OpenGL.

I started by sitting down with a sheet of paper and I began to draw .. then I flipped to the wikipedia page and there it was.

Following links, I found some cool stuff.

polyhedron glossary

All this by accident.. started by trying to draw a simple tetrahedron. now i’m not going to be able to rest easy until I’ve explored a lot of these shapes..

I’ve been introduced to them before, but now I want like, math formulas to be able to draw these.

Especially the 59

Well she did it.

This is just a reminder to try and find and watch it for myself

The XNA docs say:

d: The distance of the Plane along its normal from the origin

However, that is wrong.

The right description is:

d is the distance you must translate the plane along its normal to get to the origin.

For example, the plane

rightBoundaryPlane = new Plane( 1, 0, 0, 1000 );

Is a plane that has a normal pointing in +x. Using the xna vague (and inaccurate) description of d, you might think that d is “the distance of the plane along its normal from the origin..” i.e. this plane should be off 1000 units in the direction of +x.

In fact, that is WRONG. This plane intersects the x axis at ( -1000, 0, 0 ). Why -1000? Because d represents the number of units you must move this plane, along its normal, to get to the origin.

Meaning, this plane must intersect ( -1000, 0, 0 ) because moving the plane 1000 units in the direction of ( 1, 0, 0 ) would take you to the origin.

So how do you get a plane at the right (+X) side?

Use:

rightBoundaryPlane = new Plane( 1, 0, 0, -1000 );

This plane intersects ( 1000, 0, 0 ) because you’d have to move it -1000 units ALONG ITS NORMAL ( in the direction of (1, 0, 0) ) to get it to the origin

Fog as a cheap depth cue

I’m trying to build something cool here. not telling what is, but you can guess from the screens, I suppose ;).

So I needed to make sure my frustum cull was working right. I could never tell which objects were further away or closer in orthographic mode (naturally), so I wanted a solution for this.

Yesterday and the day before I discovered Bryce and I was following some really good tutorials on it. It was very painful to go through ALL THAT UI stuff in one day, but I did it.

So like there’s a depth cue in Bryce which is just simple fog. DUH!!!! Fog makes things that are further away appear grayer. (Well bryce actually fades it out so you can’t see it anymore).

I like to be able to see everything all the time, so I just left the background default corny-blue and made the fog color gray. The spheres are supposed to be black, frustum lines yellow.

fog_is_a_very_nice_depth_cue

It really helps!

I just noticed this a few days ago, but I was dressed normally, but I was carrying a tube of pringles EXTREME chips. I don’t know why, but suddenly EVERYONE, including the pretty girls, were much more friendly to me.

I really didn’t realize the power of pringles, but attracting women is apparently one of them

where are they?

Here they all are

Rendering a skybox in xna

apparently you CANNOT change textures while in between BasicEffect.Begin() and BasicEffect.End().

What SEEMS to happen is you actually end up “queuing” a change to another texture, but the change doesn’t happen until you call .End()

Example: I was trying to render a skybox. The position of the textures kept coming out ALL wrong. After a long time spent looking for a bug in the texture load or vertices code, I found out that it was just the call to change the texture was in the wrong place.

Wrong way:

    for( int i = 0; i < 6 ; i++ )
    {

      basicEffect.Begin();
      basicEffect.CurrentTechnique.Passes[ 0 ].Begin();
      {
        basicEffect.Texture = walls[ i ]; // apparently QUEUES until you End() / Begin() again.
        GraphicsDevice.DrawUserPrimitives( PrimitiveType.TriangleStrip, wallQuads[ i ], 0, 2 );
      }
      basicEffect.CurrentTechnique.Passes[ 0 ].End();
      basicEffect.End();
    }

Right way:

    for( int i = 0; i < 6 ; i++ )
    {
      basicEffect.Texture = walls[ i ]; // THIS will change the texture before going in to render.
      
      basicEffect.Begin();
      basicEffect.CurrentTechnique.Passes[ 0 ].Begin();
      {
        GraphicsDevice.DrawUserPrimitives( PrimitiveType.TriangleStrip, wallQuads[ i ], 0, 2 );
      }
      basicEffect.CurrentTechnique.Passes[ 0 ].End();
      basicEffect.End();
    }

Granted, this probably isn’t a very efficient way to do this at all. I’m thinking of using a cubemap to avoid having to .Begin() and .End() that basic effect 6 times to draw this thing. But I guess it makes sense, because in OpenGL you can NOT bind a texture inside glBegin() and glEnd(), you have to do it before or after glBegin(). So I guess that makes sense, but it seems a bit inefficient.

I’m currently looking for a suitable skybox to use in a space sim

This pov-ray script thing sounds promising but like too much work.

I’ve installed pov-ray but never really bothered to use it.

Remarkably Terragen can’t do it, but here’s a nice terragen tutorial anyway, and another (Carol Brooksbank’s – from web archive)

Weird program but pretty cool nonetheless but its pay software and it makes a flat image not a box

XNA texture draws all black when I try and draw it

OK, after about 2 hours of struggling with this problem, I discovered it was this:

basicEffect.VertexColorEnabled = false ;

Basically, it is an ERROR to have VertexColorEnabled on your BasicEffect and at the same time attempt to draw something using texturing.

So you are NOT ALLOWED to have VertexColorEnabled if you try and draw with a texture.

Check this out too, really useful tools for debugging DirectX apps are installed by default, you just have to explore them.

Shouldn’t the docs say SOMETHING about this in a really obvious place?

SpriteBatch screws up 3d drawing

SpriteBatch messes up 3d drawing

SpriteBatch spoils 3d drawing

Man. I just spent.. about 3 hours on this stupidness.

Like, it was totally erasing ALL my 3d stuff and ALL I had to do was:


    spriteBatch.Begin( SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState );

    // draw sprite-y shit
    
    spriteBatch.End();

The SaveStateMode.SaveState is EXTREMELY important because its what prevents spritebatch from DESTROYING / sabotaging the gpu renderstate.

This example just shows how to use DevIL to open, create, and save an image

Great tutorial here too

Pretty neat.

#undef _UNICODE

#include <stdio.h>
#include <stdlib.h>

#include <windows.h>


#include "il.h"
#include "ilu.h"  // for image creation and manipulation funcs.

#pragma comment( lib, "DevIL.lib" )
#pragma comment( lib, "ILU.lib" ) 

// Wow. DevIL is amazing.

// From http://gpwiki.org/index.php/DevIL:Tutorials:Basics

// The library consists of three sub-libraries:
//  * IL - main DevIL library. It allows you to load and save images to files. Every function in this library have 'il' prefixed to their name.
//  * ILU - this library contains functions for altering images. Every function in this library have 'ilu' prefixed to their name.
//  * ILUT - this library connects DevIL with OpenGL. Every function in this library have 'ilut' prefixed to their name. 

int main()
{
  ilInit();
  printf("DevIL has been initialized\n");
  
  // Loading an image
  ILboolean result = ilLoadImage( "4px.png" ) ;

  if( result == true )
  {
    printf("the image loaded successfully\n");
  }
  else
  {
    printf("The image failed to load\n" ) ;
    
    ILenum err = ilGetError() ;
    printf( "the error %d\n", err );
    printf( "string is %s\n", ilGetString( err ) );
  }

  int size = ilGetInteger( IL_IMAGE_SIZE_OF_DATA ) ;
  printf("Data size:  %d\n", size );
  ILubyte * bytes = ilGetData() ;

  for( int i = 0 ; i < size; i++ )
  {
    // see we should see the byte data of the image now.
    printf( "%d\n", bytes[ i ] );
  }


  // Other info.
  int bpp = ilGetInteger( IL_IMAGE_BITS_PER_PIXEL ) ;
  
  printf("bpp: %d   IL_IMAGE_FORMAT: %d\n",
    
    bpp,
    ilGetInteger( IL_IMAGE_FORMAT )
    
  ) ;


  ilClearColour( 0, 255, 0, 255 ) ;




  // generate image data as just array of bytes.

  // get width and height of your desktop
  int width  = GetSystemMetrics( SM_CXVIRTUALSCREEN ) ;
  int height = GetSystemMetrics( SM_CYVIRTUALSCREEN ) ;

  int bytesToUsePerPixel = 3 ;  // RGB
  // we coulda used 4, if we wanted a "transparency" component,
  // but we don't want this png to use trans.

  // duh, the size of a byte is obviously ONE BYTE,
  // but this is just a formality to PERHAPS
  // make the code a bit more clear.
  int sizeOfByte = sizeof( unsigned char ) ;

  // So this computation gets the size
  // that the image data array should be.
  // (width*height)   *   (#bytes to use per pixel) really.
  int theSize = width * height * sizeOfByte * bytesToUsePerPixel ;

  unsigned char * imData =(unsigned char*)malloc( theSize ) ;

  for( int i = 0 ; i < theSize ; i++ )
  {
    imData[ i ] = i % 255 ;
  }
  
  
  // Let's make an image now.
  // the next line "generates an image" within the
  // DevIL STATE MACHINE.

  // DevIL is cool because it has this concept of
  // your "currently selected image".

  // So, when you call all the DevIL library functions,
  // (such as ilTexImage to change an images properties),
  // notice how there's no passing of any big data struct,
  // pointer to an image, or anything like that.
  
  // That's because the ONLY reference YOU get
  // as the user of the OpenIL API IS this INT
  // value:
  ILuint imageID = ilGenImage() ;

  // there.  We just created a NEW image (which will start out
  // to being 1x1 pixels or something like that)
  // our REFERENCE to this 1x1 pixel image IS
  // the integer number imageID.

  // NOW, we "select-in" the image we just generated
  // as the one we're currently working on.
  ilBindImage( imageID ) ;

  // From HENCE FORTH (until we call ilBindImage() again)
  // WE ARE WORKING ON "imageID".  ANY calls to
  // ilTexImage, or ilGetInteger, or WHATEVER are in
  // reference to the LAST IMAGE WE LAST BOUND.

  // So the new image we just created is rather.. empty.
  printf("New image!  width=%d,  height=%d,  bpp=%d\n",

    ilGetInteger( IL_IMAGE_WIDTH ),
    ilGetInteger( IL_IMAGE_HEIGHT ),
    ilGetInteger( IL_IMAGE_BPP )
    );

  printf("About to tex up your image\n");
  ilTexImage(
    
    width,
    height,
    
    1,  // OpenIL supports 3d textures!  but we don't want it to be 3d.  so
    // we just set this to be 1
    
    3,  // 3 channels:  one for R , one for G, one for B
    
    IL_RGB,  // duh, yeah use rgb!  coulda been rgba if we wanted trans
    
    IL_UNSIGNED_BYTE,  // the type of data the imData array contains (next)
    
    imData  // and the array of bytes represneting the actual image data
    
  ) ;

  printf("Your image was texxed\n");

  printf("Now width=%d,  height=%d,  bpp=%d\n",

    ilGetInteger( IL_IMAGE_WIDTH ),
    ilGetInteger( IL_IMAGE_HEIGHT ),
    ilGetInteger( IL_IMAGE_BPP )
    );

  // allow openIL to overwrite the file
  // we created last time
  ilEnable(IL_FILE_OVERWRITE);
 
  // actually save out as png
  ilSave( IL_PNG, "output.png" ) ;

  // now try saving as jpg
  ilSave( IL_JPG, "output.jpg" ) ;
  
  // now save as bmp
  ilSave( IL_BMP, "output.bmp" ) ;


  // Look at the file sizes!  For this TYPE
  // of image, png is the best because its
  // flat colors repeated.

  // On my mahcin eht png is 94KB and the BMP is 11000kB!
  // the jpg comes out at 3000kb.

  // PNG RULES!!

  // lets give another example where jpg will
  // be better...

  // cahnge im data to being just pure noise
  for( int i = 0 ; i < theSize ; i++ )
  {
    imData[ i ] = rand()%255 ;
  }


  // now set the data in the image with this new data array
  ilSetData( imData ) ;

  // save again

  // actually save out as png
  ilSave( IL_PNG, "outputNoise.png" ) ;

  // now try saving as jpg
  ilSave( IL_JPG, "outputNoise.jpg" ) ;
  
  // now save as bmp
  ilSave( IL_BMP, "outputNoise.bmp" ) ;


  // Wowo!   So for this last test, PNG was
  // worse than jpg and bmp!  that's remarkable.
  // I actually didn't know that coudl happen.

  printf("and done");

}

As usual, download the code from esnips! (thanks esnips!)

How do you load a PNG image in C++?

Well, most people use libpng

But WAIT!! That library is NSFDU. “NOT SAFE FOR DIRECT USE” – Yes i just made that up, but its absolutely true.

The API is AWFUL. If you don’t believe me, spend a day with it, struggle through it, THEN check out OpenIL

In less than 50 lines, I’m loading an image and looking at its raw data

Compare with bare minimal libpng direct use example. This is an example of how DIFFICULT using libpng directly is.

DevIL’s BRILLIANT API mimics OpenGL’s state-machine approach to image handling. Its fantastic, and for anyone who’s ever used OpenGL a bit at least, picking it up will be a breeze and everything is as you think (hope?) it should be.

#include <stdio.h>
#include <stdlib.h>

#undef _UNICODE
#include "il.h"

#pragma comment( lib, "DevIL.lib" )

// Wow. DevIL is amazing.

// From http://gpwiki.org/index.php/DevIL:Tutorials:Basics

// The library consists of three sub-libraries:
//  * IL - main DevIL library. It allows you to load and save images to files. Every function in this library have 'il' prefixed to their name.
//  * ILU - this library contains functions for altering images. Every function in this library have 'ilu' prefixed to their name.
//  * ILUT - this library connects DevIL with OpenGL. Every function in this library have 'ilut' prefixed to their name. 

int main()
{
  ilInit();
  printf("DevIL has been initialized\n");
  
  // Loading an image
  ILboolean result = ilLoadImage( "4px.png" ) ;

  if( result == true )
  {
    printf("the image loaded successfully\n");
  }
  else
  {
    printf("The image failed to load\n" ) ;
    
    ILenum err = ilGetError() ;
    printf( "the error %d\n", err );
    printf( "string is %s\n", ilGetString( err ) );
  }

  int size = ilGetInteger( IL_IMAGE_SIZE_OF_DATA ) ;
  printf("Data size:  %d\n", size );
  ILubyte * bytes = ilGetData() ;

  for( int i = 0 ; i < size; i++ )
  {
    // see we should see the byte data of the image now.
    printf( "%d\n", bytes[ i ] );
  }
}

Download the code (with DevIL binaries included!) on esnips! (thanks esnips!)

Well, this is what I did, developing on Win32 in Visual Studio 2008 PRO!!!.

EDIT: DO NOT USE LIBPNG DIRECTLY. USE DevIL INSTEAD. YOU WILL SAVE PLENTY OF TIME AND HEADACHES AND ALSO AVOID LOOKING AT THAT GOD-AWFUL LIBPNG API. I”M SORRY LIBPNG PEOPLE BUT YOUR STUFF IS __BRUTAL__ TO WORK WITH.

I was literally up and running in 5 minutes with OpenIL after spending the entire day struggling with libpng. Working example with loading a png file using DevIL.

Working with LibPNG directly

WHAT?? You’re still here? You mean you didn’t follow the DevIL link above? Ok. You’ve been warned.

  1. Uh, first, I got a hazelnut chocolate and ate it. not sure if this had something to do with it, but ..
  2. Second, I, uh, downloaded the binaries. I installed them, and then I MANUALLY COPIED libpng3.dll, libpng12.dll from C:\Program Files\LibPNG\bin into C:\WINDOWS\system32.
  3. I already had zlib, so if you don’t have it, install it as zlib is required for libpng to work.

Once you have it all installed and ready, you have to tell VISUAL STUDIO about libpng’s existence. That is, you must tell Visual Studio that you DO have libpng header files (.h) and the libpng .lib files.

In visual studio:

  1. Tools > Options
  2. LEFT PANE: Collapse “Environment” (where you start), expand “Projects and Solutions”
  3. Under “Projects and Solutions” in that left pane still, click “VC++ Directories”
  4. Download a picture of JLO and smiling (there is a full length version of these two but I can’t find them atm)
  5. Once you have “VC++ Directories” selected in the left hand pane, look at the 2 drop downs in the right hand pane. Choose PLATFORM=”WIN32″, and SHOW DIRECTORIES FOR=”Include Files”
  6. Click the picture of the shiny folder to create a new entry, then navigate to (wherever you installed libpng to). For me, I added an entry C:\Program Files\LibPNG\include.
  7. Now pick the SHOW DIRECTORIES FOR drop down again and change it to “LIBRARY FILES”. Add a new entry by clicking that shiny shiny folder and add in C:\Program Files\LibPNG\lib (or wherever yours happens to be on your local hard disk

In each project you create, be sure to:

#include <png.h>

// and link the libs!
#pragma comment( lib, “libpng.lib” )
#pragma comment (lib, “zdll.lib” )

libpng seems to come with “zlib1.dll” which is great, but it doesn’t come with “zdll.lib”, which you also need. Again, look at this post for how to install zlib. Once you install zlib, you will also have zdll.lib.

I guess the first thing that struck me about libpng is that, although powerful, it expects you to do a lot of housework on your own. I’m hoping that the libpng guys will assemble some higher level functions for the newbs to just get started in reading a png, because even their most basic example of loading a png comes in at about 250 lines of code. And its mostly housework type code that could easily be cleaned up into a single LoadPNG() function.

// FORGET IT.  DONT' USE LIBPNG.  USE INSTEAD, PLEASE.

There are a lot of source packages I just wasn’t interested in. You might also try DevIL, though I haven’t tried it yet I believe it installs libpng as well.

Well I got it to build pretty easily. but it didn’t work as a dll for me AT ALL.

First I tried the easy way and got the prebuilt binaries. But I kept getting this error:

Unhandled exception at 0x7d64d233 in Using_libpng.exe: 0xC0000005: Access violation writing location 0x00000014.

which is discussed here (but no answer is found.. he just ends up saying “it works for me!”) and an apparent answer is given here

The answer (from the second thread posting) that I believe it to be a correct synopsis of the root cause was:

So you pass the FILE* from fopen to png_init_io which will cause libpng
itself to make fread() calls on that FILE*. If libpng then crashes in
png_read_info it means that the library you used to allocate the FILE* (i.e.
the one containing the implementation of fopen which was called in (1)) is
*not* the same as the library libpng expects to call to read from the FILE*
(i.e. the library libpng.so was compiled/linked against to get the
implementation of fread).

FIX:
If you can”t change your library to match libpng and you don”t want to
compile and build libpng (statically) to change it then you have no choice
but to implement your own file IO and hope that there are no other issues (I
believe that file IO with stdio is the *only* case where an object is
allocated in the application and subject to library calls within libpng.)

basically he’s saying that libpng was built using a “different version” of file reading capability than what you have on your machine.

Probably true because i’m running the accursed x64 edition of winxp pro.

so i set out to compile my own libpng

Finally got it into a

visual studio 2008 project file

(which you can download! see I am nice!), this may help you if you can’t get it to work still.

So I built it as a big hunking .lib file (800k!) and it works now. So fuck it, I don’t care how big it is, it works, and I don’t have to worry about dll’s.

This is a nice library now, once I can get it to build.

Treating windows developers badly is not cool, btw, png team.

How can I attach a console to my win app?

A common question that usually points people to this 1997 article (which remarkably should still work!).

Besides a few codeguru or codeproject articles that do the same, here is a simple example that only takes 3 lines of code on top of your basic window creation code

All you have to know:

  // The important lines:
  AllocConsole() ;
  AttachConsole( GetCurrentProcessId() ) ;
  freopen( "CON", "w", stdout ) ;


#include <windows.h>

#include <stdio.h>
#include <stdlib.h>

// Function prototypes.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );

// In a C++ Windows app, the starting point is WinMain().
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )          
{

  // these next few lines create and attach a console
  // to this process.  note that each process is only allowed one console.
  AllocConsole() ;
  AttachConsole( GetCurrentProcessId() ) ;
  freopen( "CON", "w", stdout ) ;

  printf("HELLO!!! I AM THE CONSOLE!" ) ;


  WNDCLASSEX wc = { 0 };
  wc.cbSize = sizeof( WNDCLASSEX ) ;
  wc.cbClsExtra = 0;  // ignore for now
  wc.cbWndExtra = 0;  // ignore for now
  wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
  wc.hCursor = LoadCursor( NULL, IDC_ARROW ); 
  wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  wc.hInstance = hInstance;
  wc.lpfnWndProc = WndProc;
  wc.lpszClassName = TEXT("Philip");
  wc.lpszMenuName = 0;
  wc.style = CS_HREDRAW | CS_VREDRAW; // Redraw the window

  RegisterClassEx( &wc );

  HWND hwnd = CreateWindowEx( 0, TEXT("Philip"), TEXT("window's title!"), WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL, hInstance, NULL );      

  ShowWindow(hwnd, iCmdShow );
  UpdateWindow(hwnd);

  MSG msg;

  while( GetMessage( &msg, NULL, 0, 0 ) )
  {
    TranslateMessage( &msg );
    DispatchMessage( &msg );
  }

  return msg.wParam;    // return from WinMain
}

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
  case WM_CREATE:
    // upon creation, let the speaker beep at 50Hz, for 10ms.
    Beep( 50, 10 );
    printf("HELLO!!! I AM THE CONSOLE!" ) ;
    return 0;
    break;

  case WM_PAINT:
    {
      // we would place our Windows painting code here.
      HDC hdc;
      PAINTSTRUCT ps;
      hdc = BeginPaint( hwnd, &ps );

      // draw a circle and a 2 squares
      Ellipse( hdc, 20, 20, 160, 160 );
      Rectangle( hdc, 50, 50, 90, 90 );
      Rectangle( hdc, 100, 50, 140, 90 );
      printf("HELLO!!! I AM THE CONSOLE!" ) ;

      EndPaint( hwnd, &ps );
    }
    return 0;
    break;

  case WM_LBUTTONDOWN:
    printf("STOP POKING MEEE!!!\n") ;
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 ) ;
    return 0;
    break;

  }

  return DefWindowProc( hwnd, message, wparam, lparam );
}



Additional ref: Msdn on console handling in general

MSDN on “consoles”

Console functions on msdn

well they’re included in devIL.

Also here, uh, gives you the files via installer

The HWND of the desktop “window” is actually 0.

You can get the DC of the desktop window using:


HDC desktopDC = GetDC( HWND_DESKTOP ) ;

// or
HDC desktopDC2 = GetDC( NULL ) ;

// or
HDC desktopDC3 = GetDC( 0 ) ;

// same diff 

// don't forget to
ReleaseDC( HWND_DESKTOP, desktopDC ) ;
// when you're done!