Skip navigation

Monthly Archives: April 2009

WELL! That was a fun day-and-a-half.

I had a project that wasn’t working and I kept working on it for 15 minutes and leaving it for 8 hours, working on it and then leaving it again. It was a really frustrating problem stream 0 size is too small when I was trying to DrawIndexedPrimitives.

Well, now I got it.

DrawIndexedPrimitivesworks as follows:

graphicsDevice.DrawIndexedPrimitives(

  PrimitiveType.TriangleList,  // the prim type to draw

  0,
  0,

  vertexCount, // THIS is the thing
  // that I screwed up.  I kept putting INDEXCOUNT here, which is
  // WRONG.  This is the base number of vertices you will VISIT
  // in this draw call.  If 4 vertices are used to draw 4 triangles
  // (as in a tet), then this number will be 4, NOT 12.

  0,

  indexCount / 3  // now THIS is the number of primitives that
  // you will end up drawing.  So HERE you take into account
  // the number of tris you are drawing.  If drawing a tet, then
  // this number would be 4.

);

See Shawn Hargreaves hair-follicle-saving example (but its still complex, mind you) about instanced models

Drawing using the INDEX BUFFER in XNA

BEFORE READING, this post explains vertex buffers and how you download vertices to the GPU using .SetData in greater detail

#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 INDEXED primitives, we'll need 4 basic objects:
  //   1.  A BasicEffect.  Used to DRAW.
  //   2.  A VertexBuffer.  Used to STORE ALL THE VERTICES of
  //        the object we wish to draw.
  //   3.  A VertexDeclaration.  Explains to the GPU what PROPERTIES
  //        each vertex has.  In this example, each vertex will
  //        simply have a POSITION in space, and a COLOR.  Could
  //        also have had texture coordinates, but we're not using those here.
  //   4.  An INDEX BUFFER:  Explains to the GPU what
  //       ORDER the vertices in the VertexBuffer should be visited.
  //       That is what the INDEX BUFFER is for.

  //       Imagine you are a kid again going trick or treating.
  //       This is your neighbourhood:

  //     ^       ^       ^        ^        ^
  //    |_|     |_|     |_|      |_|      |_|
  //    100     102     104      106      108
  //
  //
  //
  //    101     103     105      107      109
  //     ^       ^       ^        ^        ^
  //    |_|     |_|     |_|      |_|      |_|

  // Before leaving your house, you look at this map
  // of houses and you identify the houses you know
  // NEVER have candy.  You mark the ones that
  // DO with an X.

  //     ^       ^       ^        ^        ^
  //    |X|     |_|     |X|      |_|      |X|
  //    100     102     104      106      108
  //
  //
  //
  //    101     103     105      107      109
  //     ^       ^       ^        ^        ^
  //    |_|     |X|     |_|      |X|      |_|

  // OK, so you want to tell everyone in the
  // neighbourhood what order your are visiting
  // these houses.

  // The thing is, each of these houses has
  // real space coordinates right?

  // Vertex space coordinates of the center
  // of each home:

  // House 100:  ( 10, 40, 5 )
  // House 101:  ( 20, 40, 30 )
  // House 102:  ( 30, 40, 5 )
  // House 103:  ( 40, 40, 30 )
  // House 104:  ( 50, 40, 5 )
  // .. and so on ..

  // So you could EITHER tell everyone the
  // physical location (coordinates) of each
  // house you plan to visit:

  // I am visiting:
  // ( 10, 40, 5 ), ( 40, 40, 30 ) ...

  //     ^       ^       ^        ^        ^
  //    |X|     |_|     |X|      |_|      |X|
  //    100     102     104      106      108
  //       \            /  \             /   
  //         \        /       \        /
  //            \  /             \  /
  //    101     103     105      107      109
  //     ^       ^       ^        ^        ^
  //    |_|     |X|     |_|      |X|      |_|
  //  

  // Or you could simply list the INDICES
  // ("house numbers") of the homes you
  // would like to hit.

  // Which would be:
  // 100, 103, 104, 107, 108

  // The house numbers are kind of like
  // indices ("indexes").
 

  // Does that kind of make sense?

  


  ////////////////////////
  // Lets talk more about this.

  // Now say you're crazy and you're going to fire
  // eggs at each of the houses who are participating
  // in Halloween this year using your patented
  // egg-launcher.

  // So, you have two options to pass the data
  // about the coordinates of the homes to hit
  // for your egg launcher.

  // You could:
  // 1.  Feed the egg launcher the coordinates of
  //      the homes to hit with eggs directly (looks like
  //      ( 20, 40, 30 )... etc)

  // OR 2.  Pass the egg launcher TWO arrays:
  // The array of "positions of each home" (akin to
  // a "vertex array"), and THEN, SEPARATELY, pass it
  // an array of "homes to hit, by index", (INDEX BUFFER).

  // The INDEX BUFFER basically lists the houses to HIT
  // by index, and the machine would know
  // to LOOK UP the physical coordinates of the
  // homes to hit FROM the "positions of each home" array
  // (the vertex buffer).

  // VERTEX BUFFER:
  // Positions of each home, stored in an array:
  // +---------------+----------------+---------------+
  // | ( 10, 40, 5 ) | ( 20, 40, 30 ) | ( 30, 40, 5 ) |
  // +---------------+----------------+---------------+
  //       100              101              102

  // INDEX BUFFER
  // Homes to hit (also stored in an array):
  // +-----+-----+
  // | 101 | 103 |
  // +-----+-----+
  //  

  // As you work through the INDEX BUFFER, firing
  // eggs at each home listed there,
  // to know the physical coordinates of a house
  // at fire time, you simply look it up in the
  // "VERTEX BUFFER",
  // which is that "positions of each home" array.

  // So, when drawing graphics, the VERTEX BUFFER
  // is a list of all the vertices that make up the model.
  // The INDEX BUFFER is the visitation order that the
  // GPU should use to "weave" triangle.

  // So you notice immediately that the INDEX BUFFER
  // way has a really great advantage.  Say you really
  // hate Mr. Smithers and you want his home hit (home 104) with
  // 2 eggs in a row.  Instead of passing the machine
  // data with repeated vertices like this:

  //  ( 20, 40, 30 ), ( 40, 40, 30 ), ( 50, 40, 5 ), ( 50, 40, 5 )

  // Your index buffer could look like this:
  // 
  // +-----+-----+-----+-----+
  // | 101 | 103 | 104 | 104 |
  // +-----+-----+-----+-----+

  // So that's a bit more compact notation for
  // when a certain vertex is visited more than once
  // (which happens QUITE often when drawing a model!)

  // Include the fact that each vertex in D3D gets passed with
  // texture coordinates (2 floats) AND normals (3 floats),
  // and its easy to see where the savings comes in.







  

  ///////////////////////////
  // OK, last thing, then I'll get to the code, I promise.
  // The other thing that this is like is PEGS ON A KNITTING LOOM.
  // If you've seen one of those things, it has these pegs that
  // you weave the yarn about over and over again.  A loom might
  // have 15-20 pegs or so

  // 

  /*
            3 4 5  
          2 * * * 6
        1 *       * 7
        *           *
        1 *       *
        3 1 * * * 8
          2 1 1 9  
            1 0
   
    My sweet sweet knitting loom
    with sweet numbered pegs
  
  */

  // So to knit a sock or glove or something,
  // you might visit pegs in the following order:
  // 4, 10, 5, 11, 6, 12, 7, 13.. 

  // In this example, the actual PHYSICAL PEGS are
  // the VERTEX BUFFER (the pegs have
  // actual physical space coordinates don't they?)

  // The "winding order" or the order that I want you
  // to spin the yarn about the pegs, is NOT specified
  // by physical space coordinates (I'm not giving you the
  // physical distance to travel the yarn from peg 4 to peg 10,
  // I'm not saying "start at 4 cm horizontally from the top (4, 0, 0)
  // and connect with (4, -4, 0)).

  // Same goes for drawing using an index buffer.
  // INSTEAD of directly specifying physical Vertex positions
  // in space while drawing, we specify vertex positions
  // ONCE and store them off in a VERTEX BUFFER.

  // We THEN AFTER THAT create a SECOND array called
  // the INDEX BUFFER which specifies the ORDER TO
  // VISIT THE VERTICES THAT ARE ALREADY STORED IN
  // (and numbered off!) in that VERTEX BUFFER.

  // Each VERTEX actually has a position in space.
  // So we store the vertices as this array:

  // pointList ARRAY:
  //
  // +-----------------+-----------------+-----------------+
  // |   ( 1, 1, 1 )   |   ( 2, 5, 9 )   |   ( 8, 5, 7 )   |
  // +-----------------+-----------------+-----------------+
  //          0                 1                 2

  // This forms the VERTEX BUFFER.
  // (Each triplet in the array represents a vector)

  // So, to DRAW A TRIANGLE, between the points I'd specify
  // 0, 2, 1 in the INDEX BUFFER.

  // INDEX BUFFER ibData:
  //
  // +-------+-------+-------+
  // |   0   |   2   |   1   |
  // +-------+-------+-------+
  //     0       1       2
  
  // When the GPU goes to draw that
  // it puts the two together (the INDEX BUFFER values, which
  // reference the VERTEX BUFFER values) and so it would draw
  // a triangle between (1,1,1), (8,5,7), (2,5,9), winding it
  // in that EXACT order.


  //
  ////



  // Vars for rotating the tetrahedron when you run the program.
  float rot ;
  Vector3 axis ;
  

  BasicEffect renderer;
  
  VertexBuffer vb;
  VertexPositionColor[] pointList ;

  VertexDeclaration vd;
  
  IndexBuffer ib ;
  short[] ibData ;

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

    this.IsMouseVisible = true ;

    axis = new Vector3( random( 0, 1 ), random( 0, 1 ), random( 0, 1 ) );
    axis.Normalize();
  }

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

    // "preload" the GPU up with all the vertices
    // you want it to draw.

    // 1.  Initialize the renderer as a BasicEffect:
    renderer = new BasicEffect( GraphicsDevice, null );
    renderer.VertexColorEnabled = true;

    renderer.View = Matrix.CreateLookAt( -10 * Vector3.UnitZ, Vector3.Zero, Vector3.UnitY );
    renderer.Projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.PiOver4, 1.0f, 1.0f, 1000.0f ); 
    // 
    //////

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

    // Define the vertices of a tetrahedron and put them in
    // the vertex buffer.
    float edgeLength = 1.0f ;
    float a = edgeLength / (float)( 2.0 * Math.Sqrt( 2.0 ) );

    Vector3 topFront0 = v( a, a, a );
    Vector3 bottomFront1 = v( -a, -a, a );

    Vector3 topBack2 = v( -a, a, -a );
    Vector3 bottomBack3 = v( a, -a, -a );

    pointList = new VertexPositionColor[]
    {
    
      vpc( topFront0, Color.Black ),

      vpc( bottomFront1, Color.Red ),

      vpc( topBack2, Color.GreenYellow ),
    
      vpc( bottomBack3, Color.AliceBlue )

    };

    // Load verts onto GPU
    vb = new VertexBuffer(
      GraphicsDevice, VertexPositionColor.SizeInBytes * pointList.Length, BufferUsage.None
    );
    vb.SetData<VertexPositionColor>( pointList );

    // 3.  don't forget the vertex declaration
    vd = new VertexDeclaration(

      GraphicsDevice,
      VertexPositionColor.VertexElements

    );



    // And so there we have the 4 vertices of a tetrahedron.

    // But oh!  A tet has 4 vertices, and 4 FACES!  This means
    // we need to draw _4_ triangles between these 4 vertices.

    // Now normally, you might think, "well, ok, to draw these
    // 4 triangles, we'll just issue 4 triangle-draw calls, and
    // simply REPEAT/overlap a few of those vertex."

    // Nah son.  Repeating vertices?  Nah.

    // Instead, we'll use an INDEX BUFFER.  Refer to the
    // Halloween example above for a quick understanding
    // of what we're doing here.. we're basically going to
    // list out the VISITATION ORDER of the vertices that
    // we already specified above.  So we declare the
    // vertices ONE TIME, in ONE PLACE, and then we
    // say the order that these vertices should be
    // visited at draw time.

    // Sure beats having to specify the same vertex several
    // times over, but it means that each vertex can only have
    // ONE COLOR (so coloration will be less customizable).



    // 4.  Index buffer.  First define the order in which the vertices
    // (of the VERTEX BUFFER!) will be visited

    // How did I work out this visitation order?  Using Wikipedia and a pen and paper!

    ibData = new short[]{
      
      0, 3, 1,
      0, 1, 2,
      0, 2, 3,
      2, 1, 3

    };

    // Now set them down into the GPU.
    ib = new IndexBuffer( GraphicsDevice, typeof(short), ibData.Length, BufferUsage.None );

    ib.SetData<short>( ibData );

    //end setup
  }


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

    rot += (float)gameTime.ElapsedGameTime.Ticks / TimeSpan.TicksPerSecond ;
    renderer.World = Matrix.CreateFromAxisAngle( axis, rot ) ;

    base.Update( gameTime );
  }


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

    renderer.GraphicsDevice.VertexDeclaration = vd;
    renderer.GraphicsDevice.Indices = ib ;

    renderer.Begin(); // start rendering.

    foreach( EffectPass pass in renderer.CurrentTechnique.Passes )
    {
      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.
      renderer.GraphicsDevice.DrawIndexedPrimitives(

        PrimitiveType.TriangleList,  // draw Tris, every 3 vertices
        // listed in the INDEX BUFFER are going to produce ONE TRIANGLE
        // on the screen.

        0, // ... start at the beginning of the list ...
        0, // lowest vertex index from VB that can be drawn
        
        pointList.Length,  // draw as many vertices as are specified by the VERTEX BUFFER (_NOT_ the INDEX buffer).
        // This is very important to get right, and it is a bit counter-intuitive.
        // Say we're drawing a tetrahedron (as we are in this case).  That shape
        // has 4 TRIANGLES drawn between 4 POINTS.. a total of 4 triangles
        // are drawn, so essentially that's 12 vertices that are visited.
        // HOWEVER, the value that gets passed here is __4__, NOT 12.
        // Because we visit 4 vertices, over and over again, to draw
        // the 4 triangles.

        0,
        ibData.Length / 3 // how many total triangles are we drawing?
        // we're hitting 12 vertices, to draw 4 triangles, so we
        // are drawing.. uh, 4 triangles.  DUH! :)

      );

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

    // Stop rendering.
    renderer.End();


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

  #region aux
  /// <summary>Convenience</summary>
  public static Vector3 v( double x, double y, double z )
  {
    return new Vector3( (float)x, (float)y, (float)z );
  }

  /// <summary>Convenience.  After all, Shakespeare did say
  /// that brevity is the soul of with.  He didn't say anything
  /// about efficiency, however.</summary>
  public static VertexPositionColor vpc( Vector3 p, Color c )
  {
    return new VertexPositionColor( p, c );
  }

  public static Color c( double r, double g, double b )
  {
    return new Color( (float)r, (float)g, (float)b );
  }

  static Random rand = new Random();
  public static float random( float low, float high )
  {
    return MathHelper.Lerp( low, high, (float)rand.NextDouble() ) ;
  }
  #endregion

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


This is sad. A couple lost their daughter.

She’s a cute British girl. She was lost in portugal. She was 4. She is now 6.

My feelings are for the couple.

Sorry about your girl. I hope you find her.

As soon as she has access to the Internet, she will be able to contact you.

Something that occurs to me is we should teach our children if they are abducted, to contact THE POLICE anytime, anyhow they can.

Easy to say, but how can you do that thing when you’re a kid, when the kidnappers can say anything they like to the child and the child (being a child) may believe them?

Sometime last week, I discovered Andrew Furmanczyk’s lypur’s “how to play piano” lessons on youtube.

They’re really good!

To prove he can really play (important if you’re learning from him!)

WELL.

I would write about my recent experiences, but that would be a lot of detailed.

I will just summarize my observations:

  1. beautiful women with brains do exist. This is not a myth.
  2. When you see a woman you like, talk to her immediately. DO NOT HESITATE. If you do not do this in a public place, then you’ll lose her in probably 4 seconds. She’ll leave if you make the eye contact then you shy out. In a place where you will have repeated contact, talking to her immediately avoids build up and pain and fear.
  3. Women who stick to their girlfriends and never go anywhere alone do it because they are insecure. If you’re not VERY good/persistent in your approach then you won’t be able to get anything from them. Insecure women are afraid of being rejected, passed over, or ignored. So if you look at them, a few times, and they know you have looked at them, then it quickly goes from interest to threatening to pass over, and they really do not like this, so they will run away. Solution: TALK TO THEM IMMEDIATELY. Express interest by just casual conversation. Oh, and be interesting, or SHE will drop you as uninteresting. Being interesting varies and you really need to equip yourself with things to talk about that you know they can get into.
  4. Don’t get attached. Its so easy to start to think about the girls in the room and put stupid names to them when you don’t know their actual names and get all attached and tied up into a few of them. DON’T.
  5. DO NOT LOOK ANGRY, FRUSTRATED, SCARED. Look like you just smoked a blunt. Really. I have never smoked marijuana in my life, but you need to look relaxed without trying to look relaxed. You have to be actually relaxed. DRop your facial muscles. Talk to anyone.
  6. ALREADY BEING TALKING TO SOMEONE is attractive to the girls. Stupid insecure girls won’t __approach__ two chatting people. Other girls may
  7. Intelligent girls behave differently from stupid girls. Stupid girls hang out in groups of two, and the really insecure ones talk to each other a lot. Even if you try really hard to break in on their conversation, they might respond for a few words, then drop out into conversation with their friend. They are trying to talk to you, they just don’t know how. Its too hard.
  8. WHEN YOU talk to a girl, you must LOCK HER GAZE and make extreme eye contact with her. She interprets looking away or down at the floor or around as DISINTEREST, BOREDOM, A BAD SIGN, YOU ARE UNTRUSTWORTHY, YOU ARE DANGEROUS. A girl has to be able to look into your eyes to communicate with you, and if your eyes FLIT when she looks into them, she sees a criminal and she will avoid you.
  9. When you look into her eyes, you’d be surprised at the extra degree of communication your conversation has acquired, BOTH WAYS. Watch for topics that make her eyes widen with interest, or her pupils dialate with fear. For me, I particularly noticed a bit of concern/this being an “edge” topic when I said something about parenting. I expressed disdain for high school, saying there was too much “parenting” in it. I’m not sure what the fear was, it could have been: “Does he not want children? Is he already a parent?” COuld have been either. Don’t know. Anyway.
  10. Now what you really think is in your face, and she can see it. So, if you don’t find what she’s saying interesting, and you don’t look it, you can’t just fake it with no effort like you could on the phone – your facial expression gives it all away. So she knows if you appear disinterested, she’ll quickly become disinterested as a defense mechanism.

  11. While intelligent girls .. can be a lot like birds. They used to call women birds.. they travel in flocks and they “perch” together. If several beautiful women perch, this is your chance. ENGAGE THEM. EACH. INDIVIDUALLY. OR CHOOSE ONE and capture her interest. If you are boring they will fly away. If you don’t say anything they will talk to each other, again, bad. If they start getting wrapped up in conversation with each other, its probably going to be a lot harder to “break in” (metaphor or pun not intended, and eww). The BEST TIME
  12. Smart women are every bit as driven .. by musculature and bulk, and tight buttocks and being good-looking, they just have an additional FILTER of “NO MEATHEADS”. If you are stupid, that’s fatal.
  13. COME PREPARED. BRING a “device” you can use as an excuse to exchange contact information, like an interesting website that you can totally describe whose URL you just can’t remember (offer her she can google search the keywords, or tell her, you know what, I’ll just send it to you. What’s your email address? if she likes you, she will not refuse. If she doesn’t like you, then this gives her an easy out to let you know that pretty clearly by saying she’ll just google search the keywords.)

In C++, you can serialize your data so easily by simply reading raw bytes of a struct or variable (cast base address of any variable to (unsigned char*) and you can see that variable as its underlying set of bytes that it is.)

But in C#, that ain’t so.

So in C#, you have two options when it comes to seeing the true colors of your variables.


using System;
using System.Runtime.Serialization ;
using System.IO;

public class TestBinaryOutputProgram
{
  static void Main()
  {
    // Using the BitConverter to get raw bytes of
    // any PRIMITIVE (doesn't work on a class or a struct
    // directly - would have to do member by member manually).

    float floatVar = 7.0f;
    byte[] fBytes = BitConverter.GetBytes( floatVar ) ;

    for( int i = 0; i < fBytes.Length; i++ )
    {
      Console.WriteLine( "Byte["+i+"] = "+fBytes[i] ) ;
    }


    // using a MemoryStream
    // (or some other stream object)
    // and a BinaryWriter

    MemoryStream memstream = new MemoryStream();
    BinaryWriter bw = new BinaryWriter( memstream ) ;

    // write in the var
    bw.Write( floatVar ) ; // converts to binary automatically
    byte[] memBytes = memstream.ToArray() ;

    for( int i = 0; i < memBytes.Length; i++ )
    {
      Console.WriteLine( "memBytes[" + i + "] = " + memBytes[ i ] );
    }

  }
}


well, i was a caffeine junkie for years.

then i quit. two weeks ago.

yes, i DO feel that I am somewhat.. less capable. Caffeine does something to your brain that makes it work faster. So i’m without that – naturally a bit mentally slower than I “usually” am (perpetual caffeine high).

BUT I get more work done. You know why? Because time at the computer isn’t any longer this frenetic, frenzied rush from code to website to distraction to code to website to distraction. My brain isn’t going off like that anymore – I don’t feel as distractable.

So, I AM more productive. And guess what? When I do take a mild cup of tea or two, it has a much stronger effect than the strongest coffee used to give me. It makes me feel faster, and gives me this quick boost and slight euphoria, and some focus. Because I take it when I need to focus.

I know I just said that being on caffeine all the time made time at the computer frenzied, and it does, when I’m not sure what I’m doing. But when I have a set purpose and task I must accomplish and I gulp some caffeine down to help, it does help, as long as I keep fixated on my goal.

it sucks.
mfc sucks

debugview. open it and it intercepts debug messages from system and shows them to you. very useful when debugging direct3d apps.

winspector

screen-full

/////
// Connects to MySQL database server from
// C or C++ program.
/////

/////////////////////////////////////////////
//                                         //
// Connecting C++ Win32 App To MySQL       //
//                                         //
// You found this at bobobobo's weblog,    //
// http://bobobobo.wordpress.com           //
//                                         //
// Creation date:  Apr 5/09                //
// Last modified:  Apr 5/09                //
//                                         //
/////////////////////////////////////////////



// !! Note!  I've included copies of the MySQL
// include headers and library files.. I've done this
// so that the project will compile and run
// more easily for you, but this DOES NOT mean
// that you should skip the SETUP-Y stuff section
// below!

// If you want MySQL to work easily for you in new
// projects, you really should set up Visual Studio
// as explained below.


#pragma region all the setup-y stuff
/////////
// MAKINET WORK: (any prince of persia 2 the shadow and the flame fans out there?)
//
// 1)  First, you OBVIOUSLY must install MySQL.
//     Be sure to download the 32-BIT VERSION (NOT THE x64)
//     of MySQL 5.1 - "Windows MSI Installer"
//     Located at http://dev.mysql.com/downloads/mysql/5.1.html#win32
//     DO NOT GET THE "WINDOWS ESSENTIALS" PACKAGE
//     DO NOT GET __ANY__ x64 crap EVEN IF you are on
//     windows 64 bit, ALWAYS use the NORMAL (non-64 bit)
//     stuff (see Ancient Dragon's comments for why:
//     http://www.programmingforums.org/thread16958.html)

//     Done that?  GOOD!!  Onto step 2.

// 2)  ENSURE THAT mysql.h is in your VISUAL STUDIO
//     PROJECT PATH SETTINGS.  If you don't do this,
//     then you'll may an error of the form of:

// Error	1	fatal error C1083: Cannot open include file: 'mysql.h':
//          No such file or directory


// For me, mysql.h is in :
// C:\Program Files\MySQL\MySQL Server 5.1\include

// But you have to tell VISUAL STUDIO THAT!!  IT doesn't know.

// Need to edit Visual Studio INCLUDE Directory settings.  here's how.

// SO I, click
//   1  TOOLS -> OPTIONS
//   2  PROJECTS AND SOLUTIONS -> VC++ DIRECTORIES (left hand panel)

//   3  (now in right hand panel),
//    from the two dropdowns there
//      (hanging like two microsoft eyes..), uh,

//   4  you just make sure under PLATFORM,
//      it says Win32,

//   5  and under SHOW DIRECTORIES FOR,
//      it says INCLUDE FILES.

//   6  THEN, click the SHINY YELLOW FOLDER,
//      and then click the '...'
//   7  and navigate to your MySQL INSTALL DIR\INCLUDE
//      add that folder there.

//    For me, I end up with an extra entry in that list that says:

//       C:\Program Files\MySQL\MySQL Server 5.1\include

//    yours may be slightly different, but not too different,
//    hey, don't try and be cool here by being REALLY different please.
//   

// OK?  So now the #include below should work for you.
// If it doesn't, INSTALL MYSQL FIRST!

// YOU MUST #INCLUDE WINDOWS.H FIRST IF YOU WANT MYSQL
// TO WORK ON WINDOWS!!
#include <windows.h>
#include <stdio.h>

// To get autocomplete to work, you may have to right-click
// your Header Files -> Add Existing Item... and pick
// mysql.h and add it to your project.  I've copy and pasted
// the file into this project, though.



// !!
// You may only use the form below if you have followed the
// installation instructions above.
/////#include <mysql.h>

#include "mysql_include/mysql.h"  // use this form if you haven't "installed"
// MySQL header files into visual studio as explained above.



// You must also add C:\Program Files\MySQL\MySQL Server 5.1\lib\debug
// to your Visual Studio LIBRARY directory settings (follow steps above again, except
// at step 5, you choose "SHOW DIRECTORIES FOR -> LIBRARY FILES"
// and at step 7, you add C:\Program Files\MySQL\MySQL Server 5.1\lib\debug
// (or whatever yours really is)


// !!
// You may only use the form below if you have followed the
// installation instructions above.
/////#pragma comment( lib, "libmysql.lib" )

#pragma comment( lib, "mysql_lib/debug/libmysql.lib" )  // use this form if you haven't "installed"
// MySQL header files into visual studio as explained above.

// libmysql.lib is what is termed an "import library" - basically
// it is what wires up function calls in this program to MYSQL
// functionality to the libmysql.dll file.

// So what about libmysql.dll?

// FINALLY, ENSURE TO COPY libmysql.dll to EITHER:  the \Debug folder
// of this project (WHERE THE FINAL .EXE RESIDES), __OR__, to
// C:\WINDOWS\System32 (if that doesn't work, then copy it to C:\WINDOWS\System).

// For me, libmysql.dll lives in
// C:\Program Files\MySQL\MySQL Server 5.1\lib\debug
// Its also included in the mysql_lib/debug folder of
// this project.

// To quote Charlie Charlie Petzold, Programming windows 5th ed:
// You can put a DLL file:

// A dynamic library must be present on the disk
// when a program is run that uses the library.
// When Windows needs to load a DLL module before running
// a program that requires it, the librar must be stored:
//   1.  In the directory containing the .exe program
//   2.  the current directory
//   3.  the Windows system directory
//   4.  the windows directory
//   5.  or a directory accessibel through the PATH string in the MS-DOC environment

// The directories are searched in the above order.


#pragma endregion





#pragma region CODING WITH MYSQL


////
// Globals
MYSQL mysql;    // the MYSQL global object.  Passed to mysql_init,
                // and there's only one of this.

MYSQL * conn ;  // represents connection to database
//
////

int main()
{
  // OK!!  Now that you've got all the setup-y stuff out of the way, its
  // time to connect to MySQL!!

  // here are some great references:
  // 1)  http://c-programming.suite101.com/article.cfm/using_a_mysql_databases_with_c
  // 2)  http://dev.mysql.com/doc/refman/5.1/en/windows-client-compiling.html
  mysql_init( &mysql ) ;
  
  // PLEASE SEE DOCS PAGE FOR MORE DETAILS
  // ABOUT mysql_real_connect():
  //   http://dev.mysql.com/doc/refman/5.0/en/mysql-real-connect.html
  conn = mysql_real_connect(  &mysql,
                              "localhost",// synonymous with 127.0.0.1
                              "root",     // connect as user="root".  Uh, bad security here..
                              "",         // my root password is blank.  REALLY bad security :)
                              "mysql",    // connect to the 'mysql' _database_ within MySQL itself.
                                          // if you create another database, then you can
                                          // specify you'd like to connect to that one here.

                              0,          // port.  Mine is on 3306, but you can leave it as 0
                                          // and it seems to work automatically.

                              0,          // unix_socket (not in use)

                              0 ) ;       // client flag:  usually 0, unless you want special features (see docs page)
  
  // At this point you may be wondering, ok,
  // so if this is real_connect, what's fake_connect?
  // There is a mysql_connect() function!  Which is
  // basically the "fake" connect... see docs, but
  // the "fake" functions (mysql_query(), mysql_connect()),
  // are like watered down version of their _real_ counterparts.
  // Sometimes useful, sometimes not.  Again, see docs pages.


  // Check if connection succeeded.
  if( conn == NULL )
  {
    printf("Couldn't connect to MySQL database server!\n");
    printf("Error: %s\n", mysql_error( &mysql ) ) ;
    return 1 ;
  }
  else
  {
    printf("Connect success\n") ;
  }
  


  #pragma region running an actual query
  // Here, we are connected.
  // form a sql string to execute.
  
  char * query = "select * from user" ;
  int queryState;

  queryState = mysql_query( conn, query ) ;

  if( queryState != 0 )
  {
    printf("Whoops!  The query failed.  Error:  %s\n", mysql_error( conn ) );
    return 1 ;
  }

  // here, query succeeded, so we can proceed
  // to pull out results.
  MYSQL_RES * resultset ;
  MYSQL_ROW row;  // MYSQL_ROW is #defined as (char **)
  // Data ALWAYS comes back from MySQL as
  // an array of strings.  To convert it
  // to ints or whatever is YOUR JOB as the programmer.

  // mysql_store_result basically fetches
  // the entire array of results and dumps them
  // into our local program memory space (all
  // in the resultset variable.
  resultset = mysql_store_result( conn );

  // How many rows will there be?
  int numRows = mysql_num_rows( resultset ) ;
  printf( "There are %d ROWS (records) of data\n", numRows ) ;

  
  
  // Now tell me what columns there are
  // in the result set.
  int numFields = mysql_num_fields( resultset ) ;
  printf( "There are %d FIELDS (columns) of data\n", numFields ) ;

  // Print all those column by name
  MYSQL_FIELD * fields = mysql_fetch_fields( resultset ) ;
  for( int i = 0 ; i < numFields ; i++ )
  {
    printf( "%25.25s", fields[i].name ) ;
  }

  printf( "\n" ) ;
  // print all results
  while( row = mysql_fetch_row( resultset ) )
  {
    // row is 2d array of char
    // underlying type is char **
    for ( int i = 0; i < numFields ; i++ )
    {
      printf( "%25.25s", row[ i ] ) ;
    }

    // next row
    printf( "\n" ) ;
  }

  #pragma endregion
  
  // Now free the result
  mysql_free_result( resultset );

  // And close down.
  mysql_close( conn ) ;
  return 0;
}


#pragma endregion // CODING WITH MYSQL


// Your hands quiver with power.

// You are now a MySQL GURU.


// For the record, there's also:
// Connector C++:  http://forge.mysql.com/wiki/Connector_C%2B%2B
// MySQL++:  http://tangentsoft.net/mysql++/

// I chose not to use either library because.. well, I dislike
// additional layers.



// TROUBLESHOOTING:
//
// "This application has failed to start because LIBMYSQL.dll
// was not found.  Re-installing the application may fix this problem."

// So, like internet superhero says, you have 3 options:
// [ http://blog.ulf-wendel.de/?p=215 ]
// 1.  Copy LIBMYSQL.dll into you Windows system directory (C:\Windows\system and/or C:\windows\system32, whichever spins your wheels)
// 2.  You copy LIBMYSQL.dll into the current working directory 
// 3.  You add the location of the LIBMYSQL.dll to your path setting, for example using SET PATH=%PATH%;C:\path\to\LIBMYSQL.dll

// LIBMYSQL.dll is somewhere in your MYSQL INSTALLATION directory..
// so find it, and copy LIBYMSQL.dll to C:\Windows\System32 and/or C:\Windows\System
// OR copy it to the \Debug directory for this project (where the final .exe resides)



// Final note:  static lib compiling.
//#pragma comment( lib, "mysqlclient.lib" )   // doesn't work.. produces 76 errors of the form
// Error	1	error LNK2005: __aligned_malloc already defined in MSVCRTD.lib(MSVCR90D.dll)	       (from file LIBCMTD.lib)
// 
// root of problem seems to be in the warning:
//  Warning 44 warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library

// Problem docs:
//     http://curl.haxx.se/mail/lib-2006-04/0101.html
//     http://www.codeguru.com/forum/archive/index.php/t-375084.html

// MikeAThon, at the bottom of the second post there, says
// LIBCMT is the static C-runtime library (and is multi-threaded),
// whereas MSVCRTD is the dynamic linking C-runtime. See
// "How to link with the correct C Run-Time (CRT) library" at
// http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q140584& .
// According to that KB article, "the linker will issue a warning
// (LNK4098) if a resulting module attempts to combine more than
// one copy of the CRT library"

// So go into linker -> input -> ignore all default libraries (/NODEFAULTLIB)
// See Internet Superhero again for more help http://blog.ulf-wendel.de/?p=215


Download Visual Studio 2008 project files on esnips (thanks esnips!)

I really couldn’t get it.

But now I do.

The problem traces back to this example, which I won’t say anything bad about, except:

MYSQL *connection, mysql;

Now I’m pretty good with C++. I really am. But I ( forgot ? whoops : did not know) that this declaration creates:

  1. A variable, static type MYSQL *, identifier ‘connection’
  2. Another variable, static type MYSQL, identifier ‘mysql’

Did you NOT just do a double take?

Let me further elaborate.

The following lines of code ARE NOT EQUIVALENT to the bolded line above

MYSQL *connection ;
MYSQL * mysql ;

Which is effectively what I did, and which is why I got the well deserved

Unhandled exception at 0x1000edb7 in MYSQL_CLIENT_2005.exe: 0xC0000005: Access violation writing location 0x000003b0.

So the declaration:

MYSQL *connection, mysql;

When broken into 2 lines is:

MYSQL *connection ;
MYSQL mysql ;

Really, I don’t like how that is. Basically the “pointer” part of the declaration sticks to the identifier, NOT to the type specifier at the front.

I thought I could make 10 int pointers like:

int * a,b,c,d,e,f,g,h,i,j ;

But it turns out you’ve have to do:

int *a, *b, *c, *d, *e, *f, *g, *h, *i, *j ;

We all learn..

MAN. How frustrating.

I spent the last 2 hours over this

Problem: I created a new virtual machine. VMWare WON’T BOOT FROM CD!! It keeps on trying to do a network boot

SOLUTION

HACK OPEN the .vmx file for your virtual machine (open in any text editor)


ide0:1.present = “TRUE”
ide0:1.fileName = “d:”
ide0:1.deviceType = “cdrom-raw”
ide0:1.autodetect = “FALSE”

you know, all this time i’ve seen madonna as some kind of sex-icon pop artist. but she really does have a beautiful voice.

I just got this song.. “You must love me”. its a whole other side to the madonna coin that i’ve never seen before.

you know, for a long time I never really recognized the new artist called rihanna.

but she’s actually INCREDIBLY gorgeous

rihanna-from-website

and REALLY GOOD, with 4 #1′s in the past 2 years alone. I actually love a number of her songs myself, but for SOME REASON, for the longest time, I kind of refused to acknowledge her as a great artist.

I guess now its about time

Follow

Get every new post delivered to your Inbox.

Join 37 other followers