Skip navigation

Monthly Archives: February 2009

I’m CONFUSED about what I am doing, if the object hierarchy I’m defining makes ANY sense at all, and what ASS BITERS i’m planting for myself as I develop this code.

This is where hindsight is 20/20, but I have none, so I’m literally pushing ahead in the pitch black dark.

codeproject example

msdn tutorial / example

Modified msdn example, notes below

// events1.cs
using System;
using System.Collections;

namespace Example1
{
  // 1.  DECLARE A DELEGATE TYPE
  // that will be used to 
  public delegate void ChangedEventHandler( object sender, EventArgs e );



  public class ExtList : ArrayList
  {
    // 2.  DECLARE THE EVENT to be the type
    // of the delegate that you declared.
    public event ChangedEventHandler Changed;
    // An event IS an instance of a delegate
    // only several instances of the delegate
    // can be chained to execute in order.


    ///
    // Invoke the Changed event by explicitly
    // asking the Changed function to execute
    // (by a simple function call).
    protected virtual void OnChanged( EventArgs e )
    {
      if( Changed != null )
        Changed( this, e );
    }

    // Override some of the methods that can change the list;
    // invoke event after each
    public override int Add( object value )
    {
      int i = base.Add( value );

      // Trigger the OnChanged event.
      OnChanged( EventArgs.Empty );

      // This also could have been achieved by
      // simply invoking:
      //if( Changed != null )
      //  Changed( this, EventArgs.Empty ) ;
      // However the extra step above allows
      // a deriving class to actually add additional
      // functionality by overriding OnChanged
      // and then calling base.OnChanged( e ) when done.
      ////


      return i;
    }

    public override void Clear()
    {
      base.Clear();
      OnChanged( EventArgs.Empty );
    }

    public override object this[ int index ]
    {
      set
      {
        base[ index ] = value;
        OnChanged( EventArgs.Empty );
      }
    }
  }


  class Test
  {
    // This will be called whenever the list changes.
    private void ListChanged( object sender, EventArgs e )
    {
      Console.WriteLine( "This is called when the event fires." );
    }

    private void ListChanged2( object sender, EventArgs e )
    {
      Console.WriteLine( "SO WILL THIS, SUCKER." );
    }

    // Test the ExtList class.
    public static void Main()
    {
      // Create a new list.
      ExtList list = new ExtList();
      

      // Attach functions to execute.
      list.Changed += new ChangedEventHandler( list_Changed );
      list.Changed += new ChangedEventHandler( list_Changed2 );



      
      // Create a class that listens to the list's change event.
      Console.WriteLine("Adding an item");
      list.Add( "item 1" );
      
      // remove the first response function
      list.Changed -= new ChangedEventHandler( list_Changed ) ;


      Console.WriteLine( "Adding another item" ); 
      list.Add( "item 2" );
      

      list.Clear();
    }

    static void list_Changed2( object sender, EventArgs e )
    {
      Console.WriteLine( "INDEED IT HAS CHANGED!" );
    }

    static void list_Changed( object sender, EventArgs e )
    {
      Console.WriteLine( "THE LIST HAS CHANGED!" );
    }
  }
}

The point of event handlers is they are like a chain of functions that will execute in rapid succession on your command.

The msdn example is pretty good. In their example, they take a normal ArrayList and extend it with a Changed event. Now anytime the ArrayList is changed (through an addition, or a deletion, or totally clearing the list) the Changed event is TRIGGERED (basically, the Changed event is CALLED like a function would be), and so the SERIES of functions that were attached to the Changed event are executed immediately, in rapid succession. If there are no functions attached to the Changed event, then simply nothing happens.

What’s the difference between a C# event and just a normal function, you ask? Why can’t we just define a private function Changed() that executes on addition, on deletion, on clearing the list? WE COULD. But then we would have to MANUALLY provide some kind of List object that would be able to hold a series of delegates… it would just be more cumbersome.

But you are right. Events and event handlers don’t provide anything special above and beyond normal functions. The only thing good about them is how they provide a REALLY NICE mechanism to cause a set of functions to execute when certain things happen.

Creation of a custom event requires TWO things:

  1. A public delegate, which effectively specifies the type of function (argument list, return type) that can be chained onto the event
  2. Declaration of the event itself, inside the class that the event can “happen to”

The above two items look like this:

// Declare the delegate outside so any class can see it:
public delegate void ChangedEventHandler( object sender, EventArgs e );

public class ExtList : ArrayList
{
// DECLARE THE EVENT to be the type
// of the delegate that you want to be
// “attachable” this event.
public event ChangedEventHandler Changed;

// the WHOLE POINT of this “Changed” variable
// is that it will be like a queue that can accept
// a series of ChangedEventHandler objects
// (which are really going to be references to functions!)
}

So again, an event … is like a CHAIN OF FUNCTIONS.

A programmer attaches ANY NUMBER of functions to line up for execution simply by using += syntax:

class Test
{
// This will be called whenever the list changes.
private void ListChanged( object sender, EventArgs e )
{
Console.WriteLine( “This is called when the event fires.” );
}

private void ListChanged2( object sender, EventArgs e )
{
Console.WriteLine( “SO WILL THIS, SUCKER.” );
}

// Test the ExtList class.
public static void Main()
{
// Create a new list.
ExtList list = new ExtList();

// Attach functions to execute.
list.Changed += new ChangedEventHandler( list_Changed );
list.Changed += new ChangedEventHandler( list_Changed2 );

// now trigger their execution by adding an item:
Console.WriteLine(“Adding an item”);
list.Add( “item 1” ); // we see output from BOTH ListChanged
// and ListChanged2(), in the order that we attached them.
}
}

So in the above, WHEN list.Changed() gets EXECUTED, what will automatically happen is, list_Changed (which is a function) will execute first, followed by list_Changed2.

OK OK, so now HOW DID WE TRIGGER THE EVENT TO FIRE?

You trigger execution of that “queue” of functions (first one chained on gets executed first.. all the way to the last one you chained on there) by INVOKING THE NAME OF THE event:

Changed() ;

HOWEVER, CALLS TO YOUR event MUST BE WITHIN THE CLASS IN WHICH THE event IS DEFINED

So, re-emphasizing this point:

Changed() ;

CANNOT BE CALLED OUTSIDE THE CLASS. This is when you get an error of the form

Error 1 The event ‘Example1.ExtList.Changed’ can only appear on the left hand side of += or -= (except when used from within the type ‘Example1.ExtList’)

The whole thing about “appearing only on the left hand side of += or -=” is that, TO EXTERNAL CLASSES, an event CANNOT BE DIRECTLY INVOKED.

An EVENT, what constitutes FIRING of that event is meant to be completely INTERNAL to the class that declares the event. Any public function of the class may fire the event, but code from outside the class MAY NEVER invoke the event directly (unless you actually provide a public function, that all it does, is invoke the event). There is an example of this in System.Windows.Forms.Button: button1.PerformClick(). All it does is invoke the Click event handler, which you are NOT free to do because you are NOT inside the Button class, ever.

What you’re supposed to do is provide “ins” to allow the event to be invoked.. a public function that, upon invokation, will FIRE the event.

The user of your class isn’t really supposed to think about FIRING the event though. They’re supposed to use your class like normal.. and when certain things happen (something was added to the list), the Changed() event, in this example, fires as a kind of SIDE EFFECT.

If a class does not expose a function to trigger an event, then you simply cannot cause that event to trigger yourself, unless you inherit that class and write a function in the derived class that invokes the event.

Whew. That is all I have to say about events.

My first reaction to the new sign in page

sexymicrosoft

LOL

Posted here for posterity

Microsoft is getting sexy

I wanted to be able to allow complex type to contain any element in any order.

I wanted to basically say: A farm can have any number of <pig> and <sheep>, and you can have them in any order too.

<xs:complexType name="farm">
  <xs:all minOccurs="0" maxOccurs="unbounded">
    <xs:element name="pig" type="PigType" maxOccurs="unbounded" minOccurs="0" />
    <xs:element name="sheep" type="SheepType" maxOccurs="unbounded" minOccurs="0" />
  </xs:all>
<xs:complexType>

But this stupid visual studio schema editor kept on saying that you CANNOT combine maxOccurs=”unbounded” with xs:all.

Reason:

The <all> indicator specifies that the child elements can appear in any order, and that each child element must occur only once

So what to do? Again the only 3 options are:

ALL: The <all> indicator specifies that the child elements can appear in any order, and that each child element must occur only once

CHOICE: The <choice> indicator specifies that either one child element or another can occur

SEQUENCE: The <sequence> indicator specifies that the child elements must appear in a specific order:

No, no and NO!!! NONE of these options suit what I want to say.

WHY won’t it let me just say THE ELEMENTS CAN OCCUR IN ANY NUMBER IN ANY ORDER? Shouldn’t there be another option here…

So the answer is to use xs:choice minOccurs=”0″ maxOccurs=”unbounded” on the farm:

<xs:complexType name="farm">
  <xs:choice minOccurs="0" maxOccurs="unbounded">
    <xs:element name="pig" type="PigType" />
    <xs:element name="sheep" type="SheepType" />
  </xs:choice>
</xs:complexType>

Reference: This post, and same post here as well.

Using parameterized types!

I got the idea to do this from the way the Content loader works in XNA. It seems awfully verbose to have to write the Type name so many times in the first way.. (way#1 below)

With “my way”, you don’t need to cast and you only specify the type once, <between angle brackets>.

This supports the idea that you work like the framework you work in. That is, you are inclined to provide “services” to yourself like the services your framework provides to you. Since the use of a parameterized content loader is SO useful, a parameterized enum naturally follows.

using System;

public class Enums<T>
{
  public static T Parse( string val )
  {
    return (T)Enum.Parse( typeof( T ), val );
  }
}

enum People
{
  Athlete,
  KeyMaker,
  Evil,
  Stupid
}

class Program
{

  static void Main()
  {
    // The "Normal" way.  Verbose.
    People po = (People)Enum.Parse( typeof( People ), "Athlete" );
    Console.WriteLine( po + " as int " + (int)po + " type " + po.GetType() );

    // my new way, the Enums class is defined above.
    People po2 = Enums.Parse<People>( "Athlete" );
    Console.WriteLine( po2 + " as int " + (int)po2 + " type " + po2.GetType() );
  }
}

Poor innocent you. Just trying to get started with WSH, and this is what you are greeted with:

“Input Error: There is no script engine for file extension “.js”.”

Happens because SOMETHING has hijacked your .js extension.

See what it is:

ASSOC .js

The fix:

ASSOC .js=JSFile

make a screensaver in C++ win32

citing my collective sources.

MSDN link

I’ve always wanted to create a screensaver, just never got around to it.

There are a few things on codeproject that explain how to create a screensaver in C#.

But its easier in C++, in my opinion

Finally, here it is! A starter.

You CAN hook in OpenGL or whatever, but this just uses a simple backbuffer

You could easily create something like mystify or some kind of fractal thing using this starter kit

#include <windows.h>
#include <scrnsave.h>
#include <commctrl.h>

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

#ifdef UNICODE
#pragma comment(lib, "scrnsavw.lib")
#else
#pragma comment(lib, "scrnsave.lib")
#endif
#pragma comment(lib, "comctl32.lib")




// COMPILE AND RENAME .EXE FILE TO .SCR.
// DOUBLE CLICK TO LAUNCH.
// MOVE TO C:\WINDOWS\SYSTEM32 DIRECTORY
// (AS WHATEVER.SCR) AND IT WILL AUTOMATICALLY
// APPEAR IN THE DROPDOWN MENU AS A VALID
// SCREENSAVER TO CHOOSE!

// WORKS WHEN COMPILED UNDER VISUAL STUDIO 2005.

// DOES __NOT__ WORK UNDER VISUAL STUDIO 2008.



#pragma region globals
HWND winhwnd ;
HBITMAP backBMP ;
HDC backDC ;
int backBufferCX, backBufferCY ;

int totalPoints ;


#define TIMER 1
#pragma endregion




LRESULT WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch(message)
  {
  case WM_CREATE:
    {
      // Create a compatible bitmap with the width, height
      // of the desktop.
      winhwnd = hwnd ; // save.

      backBufferCX = GetSystemMetrics( SM_CXVIRTUALSCREEN ) ;  // SM_CXSCREEN is just the primary.  this is BOTH.
      backBufferCY = GetSystemMetrics( SM_CYVIRTUALSCREEN ) ;

      //HDC desktopHdc = GetDC( NULL ) ; // give me the hdc of the desktop.
      HDC winhdc = GetDC( winhwnd ) ; // give me the hdc of this app.
      backBMP = (HBITMAP)CreateCompatibleBitmap( winhdc, backBufferCX, backBufferCY ) ;
      



      // now, you need to associate a dc with this
      // bitmap.  the DC holds all the info about brushes, etc.
      backDC = CreateCompatibleDC( winhdc ) ;
      ReleaseDC( winhwnd, winhdc ) ;


      // select it in.  here we have to associate
      // the DC we made (compatible with the window's hdc)
      // with the bitmap we made (compatible with the window's bitmap)
      SelectObject( backDC, backBMP ) ;

      
      totalPoints = 0 ;

      char buf[300] ;
      
      sprintf( buf, "desktop width:  %d     height:  %d", backBufferCX, backBufferCY ) ;
      TextOutA( backDC, 20, 20, buf, strlen( buf ) );
      //MessageBoxA( NULL, buf, "Debug info", MB_OK ) ;





      // Timer for animation
      SetTimer( winhwnd, TIMER, 24, NULL ); 
    }
    break;
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  case WM_PAINT:
    // blit the back buffer onto the screen
    {
      PAINTSTRUCT ps ;

      HDC hdc = BeginPaint( hwnd, &ps );
      BitBlt( hdc, 0, 0, backBufferCX, backBufferCY, backDC, 0, 0, SRCCOPY ) ;

      EndPaint( hwnd, &ps ) ;
    }
    break;

  case WM_TIMER:

    // draw an extra point in a random spot.
    SetPixel( backDC, rand()%backBufferCX, rand()%backBufferCY, RGB( 255,0,0 ) ) ;

    TextOutA( backDC, rand()%backBufferCX, rand()%backBufferCY, "B", 1 );
    totalPoints++ ;

    if( totalPoints > 300 )
    {
      // clear by filling out the back buffer with black rectangle
      HBRUSH oldBrush = (HBRUSH)SelectObject( backDC, GetStockObject( BLACK_BRUSH ) ) ;
      Rectangle( backDC, 0, 0, backBufferCX, backBufferCY );
      SelectObject( backDC, oldBrush ) ; // put the old brush back
      // Not keeping the system's BLACK_BRUSH

      totalPoints = 0 ;
    }

    RECT r ;
    GetClientRect( winhwnd, &r );
    InvalidateRect( hwnd, &r, false ) ;
    

    break;
  default:
    return DefScreenSaverProc(hwnd, message, wParam, lParam);
  }
  return 0;
}

BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
  return FALSE;
}

BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
  return TRUE;
}



Get the code from my esnips (thanks esnips!)

How to create a backbuffer win32

This example shows how quickly

The steps:

  1. Get a window up
  2. In WM_CREATE (or just anywhere before message loop start), initialize the backbuffer
    • BACKBUFFER_SURFACE = CreateCompatibleBitmap()
    • BACKBUFFER_DRAWTOOL = CreateCompatibleDC()
    • SelectObject() your createdCompatibleBitmap into your CreatedCompatibleDC
  3. All drawing should happen to your BACKBUFFER_SURFACE __via__ your BACKBUFFER_DRAWTOOL
  4. In a draw() routine that runs once a loop, BitBlt( BACKBUFFER_DRAWTOOL into main window DC )
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


HWND winhwnd;
HDC		backDC;
HBITMAP backBufferBMP;
int		backBufferCX;
int		backBufferCY;
TCHAR * winClassName = TEXT("backbufferwin") ;

// prototypes
LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd );


inline void draw()
{
  HDC winhdc = GetDC( winhwnd ) ;
  // Now copy the back buffer to the front buffer.
  BitBlt(

    winhdc,	// destination buffer
    0, 0,	// x, y to start writing to in the destination buffer
    // counted from top left corner of dest HDC (window)

    // Width, height to copy for
    backBufferCX, backBufferCY,

    backDC, // SOURCE buffer.  We're taking from that back canvas

    0, 0,		// x pt, y pt to START copying from
    // SOURCE.  counted from top left again

    // And we just want a straight copy.
    SRCCOPY );

  ReleaseDC( winhwnd, winhdc ) ;
}




void InitBackBuffer()
{
  backBufferCX = 512;
  backBufferCY = 300;

  HDC winhdc = GetDC( winhwnd );

  /*

  Imagine you have 2 things:
  - a canvas on which to draw (call this your HBITMAP)
  - set of brushes you will use to draw (call this your HDC)

  1.  HBITMAP.  Canvas
  ___________________
  |       *         |
  |   *             |
  |     HBITMAP     |
  |    draw here    |
  |_________________|

  2.  HDC.  Set of brushes.
  <-*
  []-*
  ()-*

  */

  // Create the HBITMAP "canvas", or surface on which we will draw.
  backBufferBMP = CreateCompatibleBitmap( winhdc, backBufferCX, backBufferCY );
  if(backBufferBMP == NULL)
    printf( "failed to create backBufferBMP" );


  // Create the HDC "device context", or collection of tools
  // and brushes that we can use to draw on our canvas
  backDC = CreateCompatibleDC( winhdc );
  if(backDC == NULL)
    printf( "failed to create the backDC" );

  // Permanently associate the surface on which to draw
  // ("canvas") (HBITMAP), with the "set of brushes" (HDC)

  // "select in" the backBufferBMP into the backDC
  HBITMAP oldbmp = (HBITMAP)SelectObject( backDC, backBufferBMP );


  // Delete the "canvas" that the backDC was
  // going to draw to.  We don't care about it.
  DeleteObject( oldbmp );



  /// Release the dc of the main window itself
  ReleaseDC( winhwnd, winhdc );
}


// Just as said every C++ program starts at main,              //
// every Windows program will start at WinMain.                //
/////////////////////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nShowCmd )
{
#pragma region get window up
  WNDCLASSEX window = { 0 } ;
  window.cbSize			= sizeof(WNDCLASSEX);
  window.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);		// BLACK_BRUSH, DKGRAY_BRUSH
  window.hCursor = LoadCursor(NULL, IDC_HAND);			// load hand cursor.. make to guitar
  window.hIcon = LoadIcon(NULL, IDI_APPLICATION);		// large icon for app
  window.hIconSm = LoadIcon(NULL, IDI_APPLICATION);		// small icon that shows up in top left of window
  window.hInstance = hInstance;							// program's instance handle that was first passed to WinMain by windows when program was first run
  window.lpfnWndProc = WndProc;								// function pointer to WndProc function
  window.lpszClassName = winClassName;							// window class name
  window.lpszMenuName = NULL;									// menu name -- but our app has no menu now
  window.style = CS_HREDRAW | CS_VREDRAW;				// window style --

  if(!RegisterClassEx( &window ))
  {
    MessageBox(NULL, TEXT("Something's wrong with the WNDCLASSEX structure you defined.. quitting"), TEXT("Error"), MB_OK);
    return 1;		// return from WinMain.. i.e. quit
  }

  // CREATE THE WINDOW AND KEEP THE HANDLE TO IT.
  winhwnd = CreateWindowEx(	0/*WS_EX_TOPMOST*/,			// extended window style.. this sets the window to being always on top
    winClassName,			// window class name.. defined above
    TEXT("Double buffering and using a backbuffer"),// title bar of window
    WS_OVERLAPPEDWINDOW,// window style
    400, 200,		        // initial x, y start position of window
    800, 600,	          // initial width, height of window.  Can also be CW_USEDEFAULT to let Windows choose these values
    NULL, NULL,			  	// parent window, window menu
    hInstance, NULL);		// program instance handle, creation params

  // now we show and paint our window, so it appears
  ShowWindow( winhwnd, nShowCmd );		// you have to ask that your Window be shown to see it
  UpdateWindow(winhwnd);					// paint the window
#pragma endregion

#pragma region message loop

  MSG			msg;

  while(1)
  {
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
      if(msg.message == WM_QUIT)
      {
        PostQuitMessage(0);
        break;
      }
      TranslateMessage(&msg);	// translates 'character' keyboard messages
      DispatchMessage(&msg);	// send off to WndProc for processing
    }
    else
    {
      // could put more update code in here
      // before drawing.
      draw();
    }
  }
#pragma endregion

  return 0;	// end program once we exit the message loop
}




////////////////////////////////////////////////////////////////////////
// WndProc - "Window procedure" function
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch(message)
  {
  case WM_CREATE:
    {
      // As soon as the window is first created, create
      // the back buffer.
      InitBackBuffer() ;

      // now just draw something into it for fun
      char buf[300];
      sprintf( buf, "HELLO.  Left click to add stars.  Right click to clear." );
      TextOutA( backDC, 20, 20, buf, strlen(buf) );

      return 0;
    }
    break;

  case WM_PAINT:
    {
      PAINTSTRUCT	ps;

      HDC winhdc = BeginPaint(hwnd, &ps);

      // Do nothing here.  All drawing happens in draw(),
      // and you draw to the backbuffer, NOT the
      // front buffer.

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

  case WM_LBUTTONDOWN:	// this message occurs when the left mouse button is clicked in our window's client area
    {
      int xPos = LOWORD( lParam );
      int yPos = HIWORD( lParam );

      // Set pixel @ pos of click IN BACK BUFFER
      // to red.
      SetPixel( backDC, xPos, yPos, RGB( 255, 0, 0 ) );

      return 0;
    }
    break;

  case WM_RBUTTONDOWN:
    {
      // clear by filling out the back buffer with black rectangle
      HBRUSH oldBrush = (HBRUSH)SelectObject( backDC, GetStockObject( BLACK_BRUSH ) ) ;
      Rectangle( backDC, 0, 0, backBufferCX, backBufferCY );
      SelectObject( backDC, oldBrush ) ; // put the old brush back, not bothering
      // to catch the system BLACK_BRUSH
    }
    break;

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

  // If message was NOT handled by us, we pass it off to
  // the windows operating system to handle it.
  return DefWindowProc(hwnd, message, wParam, lParam);
}





You know, its amazing how BASIC the inner workings of the windows o/s can be.

The way the o/s offers you screensavers is if the filename has the extension .scr.

What’s even more amazing is it seems to launch from a dos/mode 8-character maximum archaic launcher.

fake-screensaver

The filename was Fake_screensaver.scr. The launcher launched it as its 8 character alias fake_s~1.scr. Isn’t that amazing??? Like somewhere down there is 8 character mode stuff.. right in winxp.

Maybe Raymond Chen would know

There’s a few ways to do this, but this is the best way I’ve come across so far.

In your draw function, just add this code ( AFTER base.Draw(), other wise any DrawableGameComponents in your project won’t appear in the shot ):

// variable screenShot gets set to true
// in Update() if someone presses spacebar
if( screenShot == true )
{
ResolveTexture2D rt = new ResolveTexture2D( 
  GraphicsDevice,
  graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight,
  1,
  SurfaceFormat.HalfVector4 ); // this format works with my GPU.  Yours may be different.
  // If not working, try a few different ones.

  // actually grab the current set of color values from the back buffer
  GraphicsDevice.ResolveBackBuffer( rt );

  // Save out to disk.
  rt.Save( "screenshot.png", ImageFileFormat.Png ); // saves into same dir as .exe

  screenShot = false ;
}

Of course you could timestamp the screen shot using DateTime.Now.ToString(“format string”).

How to draw triangles, lines etc in XNA?

user primitives are the ones that DON’T need a vertex buffer

Here’s how. This example isn’t commented, but if you’re familiar with OpenGL and glVertex3f and glColor3f, this should make a lot of sense to you!

Copy and paste into a new XNA project. There is a Main method here already, so you’ll need to delete the one that comes with your XNA project.

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

class G : Game
{
  GraphicsDeviceManager g;
  BasicEffect r;
  Vector3 eye = new Vector3( 2, 2, 2 ); // put the user @ (2,2,2)
  Vector3 look = new Vector3( 0, 0, 0 ) ; // have him stare into the origin.
  Vector3 up = new Vector3( 0, 1, 0 ) ; // define UP as +y.
  VertexPositionColor[] tris = new VertexPositionColor[ 3 ];
  VertexPositionColor[] axisLines = new VertexPositionColor[ 6 ];  // 6 verts for axis lines

  public G()
  {
    g = new GraphicsDeviceManager( this );
  }

  protected override void LoadContent()
  {
    r = new BasicEffect( GraphicsDevice, null );
    r.VertexColorEnabled = true;

    // Set up vertices.  Remember d3d wants clockwise.
    tris[ 0 ] = new VertexPositionColor( new Vector3( -0.5f, -0.25f, 0 ), Color.Black );
    tris[ 1 ] = new VertexPositionColor( new Vector3( 0, 0.5f, 0 ), Color.GreenYellow );
    tris[ 2 ] = new VertexPositionColor( new Vector3( 0.5f, -0.25f, 0 ), Color.Red );

    int axisLength = 2 ;
    axisLines[ 0 ] = new VertexPositionColor( -axisLength * Vector3.UnitX, Color.Red );
    axisLines[ 1 ] = new VertexPositionColor( axisLength * Vector3.UnitX, Color.Red );

    axisLines[ 2 ] = new VertexPositionColor( -axisLength * Vector3.UnitY, Color.Green );
    axisLines[ 3 ] = new VertexPositionColor( axisLength * Vector3.UnitY, Color.Green );

    axisLines[ 4 ] = new VertexPositionColor( -axisLength * Vector3.UnitZ, Color.Blue );
    axisLines[ 5 ] = new VertexPositionColor( axisLength * Vector3.UnitZ, Color.Blue );
  }

  protected override void Draw( GameTime gameTime )
  {
    GraphicsDevice.Clear( Color.Black );
    GraphicsDevice.RenderState.CullMode = CullMode.None ; // don't discard
    // triangles that are ccw.  d3d has opposite winding order (cw) than openGL.

    // Set look.
    r.View = Matrix.CreateLookAt( eye, look, up );
    
    r.Projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(45.0f), 1.0f, 1.0f, 1000.0f ) ;

    r.GraphicsDevice.VertexDeclaration = new VertexDeclaration( GraphicsDevice, VertexPositionColor.VertexElements ) ;
    r.Begin();
    foreach( EffectPass pass in r.CurrentTechnique.Passes )
    {
      pass.Begin();
      

      r.GraphicsDevice.DrawUserPrimitives( PrimitiveType.TriangleList, tris, 0, 1 );

      r.GraphicsDevice.DrawUserPrimitives( PrimitiveType.LineList, axisLines, 0, 3 );


      pass.End();
    }
    r.End();
    base.Draw( gameTime );
  }

  static void Main( string[] args )
  {
    G game = new G();
    game.Run();
  }
}

Warning: uncommented

A lot of the time people starting in XNA want to get a grip of things and just DRAW A TRIANGLE. Unfortunately a lot of the MSDN examples don’t show you how to do that, and they jump straight into VertexBuffer and stuff like this without just showing the user the sort of equivalent of just plain old glVertex3f() and glColor3f() calls.

This example is pretty much the equivalent of d3d hello world. Its the most basic way to draw and its not computationally efficient at all (it is more efficient to use vertex buffers!). But it is a nice starting point and lets you get something on the screen right away.

Also notice that it isn’t really 3d. This is speaking to the graphics card barebones.. to make it look 3d, you need a few transformation matrices. You’ll notice here that it won’t draw anything out side of this “canonical view volume” box: (-1,-1,-1) to (1,1,0). That is what the GPU draws in reality. Everything else isn’t drawn.

If you want to see perspective in action in less than 80 lines of code, check this example out.

Anyway, enjoy!

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

class G : Game
{
  GraphicsDeviceManager g;
  BasicEffect r;

  public G()
  {
    g = new GraphicsDeviceManager( this );
  }

  protected override void LoadContent()
  {
    r = new BasicEffect( GraphicsDevice, null );
    r.VertexColorEnabled = true;
  }

  protected override void Draw( GameTime gameTime )
  {
    GraphicsDevice.Clear( Color.Black );
    GraphicsDevice.RenderState.CullMode = CullMode.None ; // don't discard
    // triangles that are ccw.  d3d has opposite winding order (cw) than openGL.

    r.GraphicsDevice.VertexDeclaration = new VertexDeclaration( GraphicsDevice, VertexPositionColor.VertexElements ) ;
    r.Begin();
    foreach( EffectPass pass in r.CurrentTechnique.Passes )
    {
      pass.Begin();
      VertexPositionColor[] tris = new VertexPositionColor[ 3 ];

      // d3d wants clockwise.
      tris[ 0 ] = new VertexPositionColor( new Vector3( -0.5f, -0.25f, 0 ), Color.Black );
      tris[ 1 ] = new VertexPositionColor( new Vector3( 0, 0.5f, 0 ), Color.GreenYellow );
      tris[ 2 ] = new VertexPositionColor( new Vector3( 0.5f, -0.25f, 0 ), Color.Red );

      r.GraphicsDevice.DrawUserPrimitives( PrimitiveType.TriangleList, tris, 0, 1 );
      pass.End();
    }
    r.End();
    base.Draw( gameTime );
  }

  static void Main( string[] args )
  {
    G game = new G();
    game.Run();
  }
}

Well, XNA is a lot different than OpenGL.

I like it, though.

* XNA does NOT have glVertex3f() or glColor3f() equivalents. That is, you can’t specify a drawing by specifying a series of vertex points and colors like you might be used to in OpenGL.

glBegin( GL_LINES ) ;   // has
glVertex3f( 0, 0, 0 ) ;  // no
glVertex3f( 1, 0, 0 ) ;  // xna
glEnd() ; // equivalent.

* Strangely (and goodly, I suppose), the above method is used when batching calls to draw textures. Kind of neato, actually.

spriteBatch.Begin() ;
  spriteBatch.Draw( texture1 ... ) ;
  spriteBatch.Draw( texture2 ... ) ;
spriteBatch.End() ;

* You can’t specify line width in XNA.

glLineWidth( 4.0f ) ; // sorry, no xna equivalent.

* To simulate this (and accomodate for the deficiency), take a look at Manders vs machine thick lines demo, or consider drawing rotated rectangular textures instead of true lines, if working strictly in 2d.

* Here is how you handle it. The following Game1 class can be copy/pasted into a new project.


#region using...
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
#endregion

public class Game1 : Microsoft.Xna.Framework.Game
{
  GraphicsDeviceManager graphics;
  
  ////
  // To draw, we'll need 3 basic objects:
  //   1.  A BasicEffect
  //   2.  A VertexBuffer
  //   3.  A VertexDeclaration

  // The BasicEffect will draw the vertices in the
  // VertexBuffer using the VertexDeclaration to
  // understand the type of vertices that are in 
  // the VertexBuffer.
  //
  ////


  //// The BasicEffect.
  // The BasicEffect object will be our rendering workhorse.
  // It will remember all the information about our model,
  // view and projection matrices.
 
  // Basically the renderer will take points from anywhere in space
  // and translate them into the canonical view volume (-1,-1,0), (1,1,1)
  BasicEffect renderer ;

  //// The VertexBuffer
  // Ah, a "vertex buffer".  What is a vertex buffer?
  // Its just a fancy name for "arrayful of vertices".
  // Isn't that just an arrayful of Vector3's, you say?
  // Well, no.  It will actually be an arrayful of
  // VERTICES which EACH have a COLOR __and__ a position
  // in space.

  // What's more is whatever you store inside this vertexbuffer
  // will actually go down and sit IN THE GPU.  That's right.
  // You will write code that downloads vertex data
  // directly into your graphics card!  Isn't this exciting?

  // When you call the renderer object to draw
  // your shapes, you will pass it your collection of
  // vertices that you place inside the vertex buffer.
  VertexBuffer vb ;
  

  //// The VertexDeclaration.
  // Ok, you know how above we said that the VertexBuffer
  // was going to be this collection of vertices that
  // sat in the GPU?

  // Well, the GPU isn't THAT smart.  UNless you tell it,
  // it will actually NOT KNOW which points in your VertexBuffer
  // are meant to be positions, and which points are meant to be colors.

  // So you need to tell it.  The VertexDeclaration
  // says WHAT KIND OF DATA is in the VertexBuffer.
  // Does each vertex have:
  //   * Just a position?
  //   * A position and a color?
  //   * A position and a color AND a texture coordinate?

  // The vertex declaration object is how you specify
  // exactly what data is IN that VertexBuffer.
  VertexDeclaration vd ;

  // And that's all!  With these 4 objects, we'll
  // be able to draw basic primitives to the screen.
  ////


  public Game1()
  {
    graphics = new GraphicsDeviceManager( this );
    Content.RootDirectory = "Content";
  }

  protected override void Initialize()
  {
    base.Initialize();
  }

  protected override void LoadContent()
  {
    /////
    // Initialization.
    // This is a really long set of steps we need to do
    // to load vertex data INTO THE GPU.

    // The way drawing happens in XNA is you kind of
    // "preload" the GPU up with all the vertices
    // you want it to draw.  Like, you place the
    // data DIRECTLY into the GPU card itself.

    // Then, in your Draw() function, you just
    // tell it what to draw, using data that you
    // previously already loaded into its memory.

    //////
    // Initialize the renderer as a BasicEffect:
    renderer = new BasicEffect(
      
      GraphicsDevice,  // represents the GPU.  We must tie
      // our renderer object to the physical GPU.

      null             // We do not need pooling.
    
    ) ;
    renderer.VertexColorEnabled = true ;  // make it actually
    // use the colors we specify to color the verticies.
    // 
    //////

    //////
    // Next, we will create and set up a bunch of vertices
    // that we can draw.

    // I've decided to go with 3 vertices.
    // You can change this if you like.
    /////////////////////////////
    int NUM_VERTICES = 3;      //
    /////////////////////////////



    // Now to make some vertices.  Here we go!
    // I'm using the native C# type VertexPositionColor because
    // I want each Vertex to have BOTH a POSITION IN SPACE,
    // AND a color specified for it.  There are other types,
    // like VertexPositionColorTexture if you want to add in
    // some tex coords.
    VertexPositionColor[] pointList = new VertexPositionColor[ NUM_VERTICES ];


    // Now, I'm going to actually go in and give each vertex
    // some point value.
    pointList[ 0 ] = new VertexPositionColor(

      new Vector3( 0, 0, 0 ),
      Color.Black

    );

    pointList[ 1 ] = new VertexPositionColor(

      new Vector3( 0.5f, 0, 0 ),
      Color.Red

    );

    pointList[ 2 ] = new VertexPositionColor(

      new Vector3( 0, 0.5f, 0 ),
      Color.GreenYellow

    );
    //
    ///////

    // ARE WE DONE YET???  We specified the vertices.  Can't
    // we just draw them?

    // NOT QUITE!!  We specified the vertices in C#, system
    // memory.  However, the GPU doesn't have them yet.
    
    // So, how are we gonna flush out the vertex
    // specification above out the GPU itself?

    /////
    // We first need to allocate memory for (ON THE GPU!!) our vertices.

    // Notice how this memory allocation statement doesn't 
    // seem to have have normal C# form.
    
    // Yes we are creating a VertexBuffer object, but nowhere
    // do you see normal array creation (new VertexColor[5] or something
    // like that).  However given the parameters, enough memory
    // will be allocated to store an arrayful of vertices,
    // each with its own position and color.
    
    vb = new VertexBuffer(
      
      GraphicsDevice,  // this is the GPU onto which to store
      // this actual vertex buffer.  Remember, we're writing
      // directly to the GPU here!

      VertexPositionColor.SizeInBytes * NUM_VERTICES, // AWKWARD!!
      // What an awkward way to say how many vertices we
      // want this vertex buffer to eventually hold.  Nonetheless,
      // this is how you do it.
      // Its pretty straightforward, no?
      
      BufferUsage.None  // This doesn't mean we AREN'T GOING TO
      // USE the buffer.  No.  Instead, it means that we have
      // "no special instructions" about how this buffer will
      // be used.

      // The two other options are BufferUsage.Points, which
      // says to XNA that the VertexBuffer we're creating here
      // is actually going to be used to render POINTS in space,
      // and not triangles or lines, so to be prepared for that.

      // The OTHER option is BufferUsage.WriteOnly, which is
      // to say to XNA that our software program will only
      // WRITE to this buffer and never directly read from it
      // (though the GPU itself will obviously read from it
      // to actually draw what we put in there).
      // Though .WriteOnly is a reasonable setting to use here
      // for this example, we're not going to bother.  In case
      // you're wondering, there is a method VertexBuffer.GetData<>
      // which you would use to "read" from a vertex buffer.
    
    );

    ////
    // Finally we need to SET IN that set of vertices we
    // declared above into the actual GPU VertexBuffer.

    // So the way we do that is by using
    vb.SetData<VertexPositionColor>( pointList ) ;

    //
    /////

    // OK ALMOST done here.  Just ONE LAST THING.

    // At draw time, the GPU will want to be notified AGAIN
    // what kind of vertex data you're trying to draw.

    // For this reason, we must initialize a VertexDeclaration
    // object:

    /////
    // The VertexDeclaration will tell
    // the GPU what KIND of vertex data it
    // shall be reading when it attempts to read
    // the VertexBuffer we just sent it in the 
    // lines of code above
    vd = new VertexDeclaration(

      GraphicsDevice,  // tie to the GPU

      VertexPositionColor.VertexElements  // its
      // going to be a bunch of vertices that
      // have a Position and a Color.

      // Autocomplete help is a bit misleading here:
      // "An array of vertex elements" - but this is
      // NOT the place to pass in your vertex data.
      // We already did that above.
    );

    // And DONE!
    //////
  }


  protected override void Update( GameTime gameTime )
  {
    // Esc. to exit.
    if( Keyboard.GetState().IsKeyDown(Keys.Escape) )
      this.Exit();

    base.Update( gameTime );
  }


  protected override void Draw( GameTime gameTime )
  {
    GraphicsDevice.Clear( Color.DarkGray );
    ////

    // Tell GPU again what kind of vertices it should
    // expect to be getting.
    renderer.GraphicsDevice.VertexDeclaration = vd ;


    renderer.Begin(); // start rendering.


    // Enter a loop.  You'll see this loop a lot,
    // basically the reason for it is some "EFFECTS" (aka "shaders")
    // have multiple passes.. that is, they actually draw out
    // each vertex more than one time.  They do this to achieve
    // neato effects like weird shell hulls in a light shaded purple
    // color around an object, etc.
    foreach( EffectPass pass in renderer.CurrentTechnique.Passes )
    {
      // begin this rendering pass.
      pass.Begin();

      // Set the size of the points
      renderer.GraphicsDevice.RenderState.PointSize = 8.0f ;

      // Tell the GPU what vertex array to pull vertex data from.
      renderer.GraphicsDevice.Vertices[0].SetSource( vb, 0, VertexPositionColor.SizeInBytes );

      // Actually draw.
      #region note
      // !! Note:  There is a mistake in the MSDN sample @
      // http://msdn.microsoft.com/en-us/library/bb196414.aspx
      // In that example, they use GraphicsDevice.DrawUserPrimitives<VertexPositionColor>
      // and that's wrong because DrawUserPrimitives doesn't draw
      // from a vertex buffer.
      #endregion
      renderer.GraphicsDevice.DrawPrimitives(
      
        PrimitiveType.PointList,  // they are points ...
        0, // ... start at the beginning of the list ...
        3  // ... and pull 3 points out of it.
        
      );

      // end the rendering pass.
      pass.End();
    }

    // Stop rendering.
    renderer.End();


    ////
    base.Draw( gameTime );
  }

  static void Main( string[] args )
  {
    Game1 game = new Game1() ;
    game.Run();
  }
}


I almost forgot this very important observation.

I was trying to figure out WHY people never seemed to complain to me. In a previous life, they would complain to my underling, who continually sabotaged and undermined me using their complaints.

I couldn’t seem to figure out how to be the first contact for these complaints, so I could deal with and rectify situations before __my__ superior finding out from my underling.


   B<<<
      ^
   M  ^
      ^
   A>>>
   ^
*****

* = complainer
A = my underling
M = me
B = my boss
^, < > = complaint routing

How could I achieve this picture?


   B

   M<<<
      ^
   A  ^
     ^
*****

* = complainer
A = my underling
M = me
B = my boss
^, < > = complaint routing

I couldn’t figure it out.

FINALLY yesterday I realized something.

The reason my underling would receive all of the complaints was precisely because he was so critical of me.

When you are viciously critical of your organization, of people above you, people below you, you definitely sit in a dangerous place. Because its very likely everyone around you will jump at the chance to criticize you. There’s a clichee you can use here I know but I’ll spare you.

People who are very critical of things around them continuously imply they know better. That everyone around them is an idiot. And this is a way to rise within an organization very fast. But it actually requires you to be really good at the same time. Otherwise you’ll be given the responsibilities, then fall hard on your face when you realize that criticizing was easy, but actually doing it is hard.

However, the benefit, the unseen benefit of being critical of everything around you is it makes people genuinely feel that you are going to help them if and when something goes wrong and you need someone to talk to, to get help against someone who you feel is wronging you.

I never suspected, guessed or knew that this was the case. But all you have to do to get people to complain to you is to criticize things around you.

It shows you’re comfortable in your own skin. It shows you think and “know better” (though there is a tendency for the most critical people to make it sound like they know better by being so critical, but in reality, they wouldn’t do half a good a job as the person they are criticizing).

It also shows you feel secure in your position, that you are strong and powerful.

If you don’t feel secure in your position, then don’t criticize. Because you can’t.

Please DO NOT criticize in a rat-like, quiet, undermining kind of way. That just makes you a rat.

You can criticize in a few ways. There’s the positive, constructive criticism, which you make a habit of just dropping on a consistent basis, every time you make an observation. This is the hardest type, obviously, because it actually requires you to think and not just bash. It sounds like, “You know it would be better if we …” or, “You know, it would be more efficient if they … I’ll let them know about that.” And then you actually do, and your suggestions actually get implemented because they are actually good.

^ This is actually probably the formula for general success. But anyway. This is a friendly, productive criticism.

If you can’t do that, then another way to criticize is to pick on minor things, that don’t really mean anything, and that nobody’s going to bother to change, just to poke fun at stuff. Keep in mind that this can make you appear annoying, naggy and petty at worst. But it can be fun to do.

And finally, the last way to criticize. I call this Leslie-style, after a coworker Leslie.

Right now there’s somebody in my office, Leslie, who is continually critical of everyone and everything around her. She blows things out of proportion, she makes lots of noise and racket about every misplaced paperclip, ripped corner and misplaced envelope.

She makes the absolutely biggest deal out of everything she can. She is an opportunist when it comes to trouble, getting someone burned, giving just about anyone a hard time. A firestarter, if you will, she seems to fight any and everyone on a continuous basis. It seems to be what makes life worth living to her. Her friend one day, she’ll be your opponent the next, then your friend again. Working with her is exhausting, because you always have to be on guard, but at the same time, you always want to hear about what/who she’s going to complain about today.

So that’s the thing. Since she is like a little mercenary, in a way, when when something goes wrong and you need to tell someone, because you want them to do something to help, guess who comes to mind?

BIG LESLIE. Yes, BIG BIG Leslie with her big mouth and her big complaints and her big deals. I never realized this, but caught in a moment of upset, slight desperation, feeling wronged, need-someone-to-tell-because-you-think-they-will-do-something-about-it, you go to the person with the biggest mouth. Because effectively, you know its like going to a PA system. Everyone will hear about it.

With people like big Leslie, lightly dropping information about a coworker’s misconduct is like sprinkling salt and pepper on their legs. Leslie is going to bite them off.

ken perlin’s original noise code

I kept trying this out again and again, fiddling with the parameters at the top, but the noise ALWAYS LOOKED THE SAME!

I kept seeing that some parameters are supposed to refer to frequency, octaves, and amplitude.

But I couldn’t figure it out.. so I gave up.

That was last year.

This year, I looked into it again, and I found this really good implementation in C++ by John Ratcliff on flipcode.

Great! NOW I get it. Specifically, its these lines (modified slightly to make more sense):

// ADD this function IN ADDITION TO the
// rest of the original Perlin noise implementation
// of course by Ken Perlin himself
float perlin_noise_2D(float vec[2], int octaves, float freq, float amp) //expected vec size: 2
{
  float result = 0.0f;

  vec[0] *= freq;
  vec[1] *= freq;

  // This is perlin's formula from http://www.noisemachine.com/talk1/21.html
  // noise(p) + 1/2*noise(2p) + 1/4*noise(4p) ...

  // to achieve this, we need to loop.  "octaves" refers to
  // the number of samples you will pick out from
  // "Perlin's noise machine"
  for( int i=0; i < octaves; i++ )
  {
    result += noise2(vec)*amp;  // pick out noise value
    // and add to result.  if we were only doing one octave,
    // then we'd only get ONE noise value from noise2,
    // just multiplied by amp.

    // now prepare for the next iteration.

    // double the frequency (as perlin's formula above
    // says to )
    vec[0] *= 2.0f;
    vec[1] *= 2.0f;

    // half the amplitude (as perlins formula above
    // says to )
    amp*=0.5f;
  }

  // adn THAT is your noise value for this
  // particular position you sent in (originally in
  // vec)
  return result;
}

But why isn’t it continuous?

BECAUSE it isn’t SUPPOSED TO BE.

I kept trying to make it continous. Right now I found a reference that will help. Going to implement it now.

well, i haven’t tried it for long, but i am now trying this:

1) keep unhealthy snackfoods (cookies, cakes) HIDDEN AWAY. Don’t keep a box of chocolates on your desk, because you might not feel like snacking at first, but a glimpse of them might make you suddenly have a sweet munchie.

2) I just ate a bag of 4 shanghai bok choy leaves. raw. It was absolutely disgusting. but after, i had this remarkable feeling like i had just finished brushing my teeth.. my teeth felt remarkably clean for just having eaten. i also felt kinda full, my burps tasted weird, and i think this is a good route to go when you’re trying to prevent yourself from snacking. eat a bagful of bok choy or something equally disgusting until you are FULL. its a punishment.

Well, I’m not used to this:

{
  int x = 5 ;
}

x = 60 ;       // not allowed, as well it shouldn't be
int x = 60 ;   // not allowed, but it really SHOULD!

Isn’t that dumb?

my supervisor tries to KILL me.

she tries to humiliate me.

I believe she does it because somehow I threaten her.

but still. this is no excuse. its just so discouraging. i try my best to make her like me and at the same time do the best job I can.

But my success, my getting applause seems to make her angry. I can’t win.

When I’m working, i mean REALLy working, I don’t really need a todo list. Because everything I wanted to do just gets done, next item.

Just cast it (int)enumVal:


enum BodyType
{
  Fat,
  Thin,
  Musclebound = 500,
  Anorexic
} ;

class Program
{
  static void Main( string[] args )
  {
    BodyType debbie = BodyType.Fat ;
    BodyType john = BodyType.Anorexic ;
    BodyType harold = BodyType.Thin ;

    Console.WriteLine( "Debbie is " + debbie + ".  Numerical value: " + (int)debbie ) ;
    Console.WriteLine( "john is " + john + ".  Numerical value: " + (int)john ) ;
    Console.WriteLine( "harold is " + harold + ".  Numerical value: " + (int)harold ) ;
  }
}
 

APPARENTLY HLSL FORCES you to use global variables.

In Cg, you have to get a “handle” to each uniform parameter that you simply call

// BEGIN SHADER
void vertexShaderFunction (
            float3 incomingPosition : POSITION,
            float3 incomingColor    : COLOR,
    

    uniform float  mParam,             // this is a UNIFORM PARAMETER
                                       // Notice that it has NO SEMANTIC

        out float4 outgoingPosition : POSITION,
        out float4 outgoingColor    : COLOR
   )
{
    outgoingPosition = float4( incomingPosition, 1);

    float3 transformedColor = incomingColor * mParam;
    
    outgoingColor = float4( transformedColor, 1 );
}
// END SHADER

.
.
.

// C code:
  handleToParameter = cgGetNamedParameter( myCgVertexProgram,
                                           "mParam" );
  cgSetParameter1f( handleToParameter, 20.0f );  // set uniform parameter from C code
  // used "uniformly" across series of vertices.

In Cg GLOBALS aren’t supported.

In HLSL however, I’m finding that I CAN’T seem to get a reference to the uniform parameters. Instead, it seems as though HLSL WON’T LET YOU get the reference to those parameters. They aren’t in Effect.Parameters. The only items that show up in Effect.Parameters are the GLOBAL variables of the shader.

I can’t find it anywhere. MSDN says:

Uniform Shader Inputs

Vertex and pixel shaders accept two kinds of input data: varying and uniform. The varying input is the data that is unique to each execution of the shader. For a vertex shader, the varying data (for example: position, normal, etc.) comes from the vertex streams. The uniform data (for example: material color, world transform, etc.) is constant for multiple executions of a shader. For those familiar with the assembly shader models, uniform data is specified by constant registers and varying data by the v and t registers.

Uniform data can be specified by two methods. The most common method is to declare global variables and use them within a shader. Any use of global variables within a shader will result in adding that variable to the list of uniform variables required by that shader. The second method is to mark an input parameter of the top-level shader function as uniform. This marking specifies that the given variable should be added to the list of uniform variables.

Uniform variables used by a shader are communicated back to the application via the constant table. The constant table is the name for the symbol table that defines how the uniform variables used by a shader fit into the constant registers. The uniform function parameters appear in the constant table prepended with a dollar sign ($), unlike the global variables. The dollar sign is required to avoid name collisions between local uniform inputs and global variables of the same name.

The constant table contains the constant register locations of all uniform variables used by the shader. The table also includes the type information and the default value, if specified.

AH! I see. Because I’m working in XNA, I just don’t think those parameters are exposed. Apparently you need a ID3DXConstantTable interface and the uniform would have a prepended $to avoid name collisions between local uniform inputs and global variables of the same name.

OK. I forgive you, MSDN.

I just got notice from my employer that I wouldn’t be given authorization to use certain resources to perform a particular task, but the suggestion was, in essence, to “fake it.”

This just shows the mentality of these people who work above me. They’ll settle for hokey. They’ll tell you to “fake it”, because its good enough for them themselves.

This is the core of major issues in the organization where I work. Settling for mediocre. Accepting it. Not going the extra mile to make it authentic, real. But accepting “hokey” as something you will present to whoever you’re presenting to.

HOKEY ISN’T AN OPTION!!!

htons in c#

htonl in c#

HostToNetworkOrder function resides in the System.Net.IPAddress object (what a weird place to put it!)

3 overloads are provided:

System.Net.IPAddress.HostToNetworkOrder( short val )
System.Net.IPAddress.HostToNetworkOrder( int val )
System.Net.IPAddress.HostToNetworkOrder( long val )

Sending binary data in C#

Use the BitConverter class

using System ;
using System.Net ;

class Program
{
  static void Main( string[] args )
  {
    int val = 0x0112A380 ;
    val = IPAddress.HostToNetworkOrder( val );
    
    Console.WriteLine("Val is {0}", val ) ;
    Console.WriteLine( "Little endian? " + BitConverter.IsLittleEndian ) ;
    
    byte[] bytes = BitConverter.GetBytes( val );
    foreach( byte b in bytes )
    {
      Console.WriteLine( b );
    }
  }
}

Well, you konw there’s GetLastError(). But how can you get the last error AS A STRING? Use FormatMessage()!

/**

Please be sure to LocalFree() returned result when you are done
with the string returned.

*/
LPSTR GetLastErrorString()
{
  LPSTR buf = NULL ;

  int result = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
                 FORMAT_MESSAGE_FROM_SYSTEM,
                 0,
                 GetLastError(),
                 0,
                 (LPSTR)&buf,
                 0,
                 0 );

  return buf ;
}

// Use above function with this one, so you don't have to
// worry about calling LocalFree
void printLastError( char *msg )
{
  LPSTR error = GetLastErrorString() ;
  printf( "%s %s\n", msg, error ) ;
  LocalFree( error ) ;
}

Winsock error codes on msdn

Besides going and looking it up on MSDN, how can I get the winsock error codes in my C++ program?

#ifdef UNICODE
#undef UNICODE
#endif

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

#include <winsock2.h>
#include <windows.h>

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


int main()
{
  // Here I am purposefully messing up:  I didn't call WSAStartup()!  Oh no!
  // whatever will winsock do?
  int sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ;

  if( sock == SOCKET_ERROR )
  {
    // Uh oh!  Something bad happened.  Let's
    // get the error code...
    int errCode = WSAGetLastError();

    // ..and the human readable error string!!
    // Interesting:  Also retrievable by net helpmsg 10060
    LPSTR errString = NULL;  // will be allocated and filled by FormatMessage
  
    int size = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
                 FORMAT_MESSAGE_FROM_SYSTEM, // use windows internal message table
                 0,       // 0 since source is internal message table
                 errCode, // this is the error code returned by WSAGetLastError()
                          // Could just as well have been an error code from generic
                          // Windows errors from GetLastError()
                 0,       // auto-determine language to use
                 (LPSTR)&errString, // this is WHERE we want FormatMessage
                                    // to plunk the error string.  Note the
                                    // peculiar pass format:  Even though
                                    // errString is already a pointer, we
                                    // pass &errString (which is really type LPSTR* now)
                                    // and then CAST IT to (LPSTR).  This is a really weird
                                    // trip up.. but its how they do it on msdn:
                                    // http://msdn.microsoft.com/en-us/library/ms679351(VS.85).aspx
                 0,                 // min size for buffer
                 0 );               // 0, since getting message from system tables
     printf( "Error code %d:  %s\n\nMessage was %d bytes, in case you cared to know this.\n\n", errCode, errString, size ) ;

     LocalFree( errString ) ; // if you don't do this, you will get an
     // ever so slight memory leak, since we asked
     // FormatMessage to FORMAT_MESSAGE_ALLOCATE_BUFFER,
     // and it does so using LocalAlloc
     // Gotcha!  I guess.


  }

}