Skip navigation

Category Archives: graphics

Well, the diablo 3 trailer gave me an electric sensation of awesome.

The flavor — indian / arabic / somehow it always plays on ancient religion.

While the older Diablo installments seemed to play mostly on Christian tradition, it appears that Diablo 3 will have a middle eastern / indian / more exotic flavour.

Excited to see it

OpenGL Windows

How do you get OpenGL to run in a Windows app WITHOUT using GLUT?

Here’s an example, commented in detail, showing how. Emphasis on “easy to understand.”

//////////////////////////////////////////
//                                      //
// OpenGL in a PROPER Windows APP       //
// ( NO GLUT !! )                       //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 9/08             //
// Last modified:  Feb 10/08            //
//                                      //
//////////////////////////////////////////

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gl/gl.h>
#include <gl/glu.h>

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")


////////////////////////
// OK, here's the deal.
//
// OpenGL is typically so hard to
// get started on Windows (what, with the
// HDC and the HGLRC and the PIXELFORMATDESCRIPTOR)
// most get turned off very quickly
// and stick with GLUT for a very long time,
// because GLUT hides away A LOT of the
// complexities of getting a window up
// and drawing into it.

// If you're still reading, you're
// probably tired of doing things the
// GLUT way, and you want to cross over
// to doing things in OpenGL using a pure
// Windows application.

// Good choice my friend!  If you want
// full control over your app, you'll 
// want to do things in pure Win32.

// Once you get used to programming in Win32,
// its not ALL THAT BAD, I promise (evil grin).

// This demo shows you how to get a basic
// window up that OpenGL can draw into,
// and explains each step in detail.

// I give some additional references at the
// bottom of the page.

//////////////////////////
// OVERVIEW:
//
// The OUTPUT of OpenGL is a two dimensional
// PICTURE of a 3D scene.

// That's right.  I said 2D.

// People often say that the process OpenGL
// goes through to render a 3D scene is just like
// a CAMERA TAKING A PHOTOGRAPH OF A REAL WORLD SCENE.
//
// So, you know obviously that a PHOTOGRAPH
// is PURELY 2D after its been developed,
// and it DEPICTS the 3D scene that it
// "took a picture" of accurately.

// That's exactly what OpenGL does.  OpenGL's JOB
// is to take all your instructions, all your
// glColor3f()'s and your glVertex3f()'s, and
// to ultimately end up DRAWING A 2D PICTURE
// from those instructions that can be displayed
// on a computer screen.

// In THIS program, our MAIN GOAL is to
// CONNECT UP the OUTPUT of OpenGL (that 2D
// image OpenGL produces)
// with YOUR APPLICATION'S WINDOW.

// Does this look familiar?

/*
     HDC hdc = GetDC( hwnd );
*/

// You should already know that the way
// you as a Windows programmer draw to
// your application's window is using
// your window's HDC.

// If this doesn't sound familiar,
// then I strongly recommend you go read up
// on Win GDI before continuing!

////////////////////////////////!
//
// So if our way to draw to our application window
// is the HDC, and OpenGL produces some 2D image
// HOW IN THE WORLD DO YOU CONNECT UP the OUTPUT
// of the OpenGL program (that 2D picture)
// WITH the HDC of a WINDOW?
//
// That's the main subject we're tackling here
// in this tutorial.
//
// And its EASY.
//
// WE'RE lucky.  Microsoft created a bunch
// of functions (all beginning with "wgl"),
// that make this job of "connecting up" the output
// of OpenGL with the HDC of our window quite easy!

/////////////////////////
// BIG PICTURE:
//
// Here's the big picture of what
// we're going to be doing here:

/*

|---------|  draws to   |-------|  copied out   |---------|  shows in  |-----------|
|         | ==========> |       | ============> |         | =========> |           |
|---------|             |-------|               |---------|            |-----------|
  OPENGL                  HGLRC                     HDC                 application
 FUNCTION                                                                 window
  CALLS                                                                     

*/

//////////////////////
// In code:  this is the steps
// we'll follow.
//
// 1.  CREATE WINDOW AS USUAL.
//
// 2.  GET DC OF WINDOW.
//     Get the HDC of our window using a line like:
//          hdc = GetDC( hwnd );
//
// 3.  SET PIXEL FORMAT OF HDC.
//     You do 3 things here:
//          Create a PFD ('pixel format descriptor')
//          ChoosePixelFormat()
//          SetPixelFormat()
//
// 4.  CREATE RENDERING CONTEXT (HGLRC).
//          wglCreateContext()
//     Create the surface to which OpenGL
//     shall draw.  It is created such that
//     it shall be completely compatible
//     with the DC of our window, (it will
//     use the same pixel format!)
//
// 5.  CONNECT THE RENDER CONTEXT (HGLRC)
//     WITH THE DEVICE CONTEXT (HDC) OF WINDOW.
//          wglMakeCurrent()
//
// 6.  DRAW USING OPENGL.
//          glVertex3d(); glColor3d(); // ETC!
//     You call OpenGL functions to perform
//     your drawing!  OpenGL will spit out
//     its result picture to the HGLRC, which is
//     connected to the backbuffer of your HDC.
//
// 7.  SWAP BUFFERS.
//          SwapBuffers( hdc );	
//     Assuming you've picked a DOUBLE BUFFERED
//     pixel format all the way back in step 2, 
//     you'll need to SWAP the buffers so that
//     the image you've created using OpenGL on
//     the backbuffer of your hdc is shown
//     in your application window.

// And that's all!

// Ready for the code??? Let's go!

/////////////////////
// GLOBALS
//
/// Define a structure to hold all
/// of the global variables of this app.
struct Globals
{
    HINSTANCE hInstance;    // window app instance

    HWND hwnd;      // handle for the window

    HDC   hdc;      // handle to device context

    HGLRC hglrc;    // handle to OpenGL rendering context
    
    int width, height;      // the desired width and
    // height of the CLIENT AREA
    // (DRAWABLE REGION in Window)
};


///////////////////////////
// GLOBALS
// declare one struct Globals called g;
Globals g;
//
///////////////////////////


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

////////////////////////////
// In a C++ Windows app, the starting point is WinMain().
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
    //////////////////
    // First we'll start by saving a copy of
    // the hInstance parameter inside our
    // "glob" of globals "g":
    g.hInstance = hInstance;

    #pragma region part 1 - create a window
    // The next few lines you should already
    // be used to:  create a WNDCLASS
    // that describes the properties of
    // the window we're going to soon create.
    // A.  Create the WNDCLASS
    WNDCLASS wc;
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );         
    wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );     
    wc.hInstance = hInstance;         
    wc.lpfnWndProc = WndProc;         
    wc.lpszClassName = TEXT("Philip");
    wc.lpszMenuName = 0; 
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

    // Register that class with the Windows O/S..
	RegisterClass(&wc);
    
    /////////////////
    // Ok, AT THIS POINT, we'd normally
    // just go ahead and call CreateWindow().
    // And we WILL call CreateWindow(), but
    // there is something I must explain to
    // you first.  That thing is the RECT structure.

    /////////////////
    // RECT:
    //
    // A RECT is just a C struct meant to represent
    // a rectangle.
    // 
    // The RECT structure WILL DESCRIBE EXACTLY WHERE
    // AND HOW WE WANT OUR WINDOW TO APPEAR WHEN WE
    // CREATE IT.
    //
    //         TOP
    //       --------
    //       |      |
    // LEFT  |      | RIGHT
    //       --------
    //        BOTTOM
    //
    // So, what we do is, we create the RECT
    // struct for our window as follows:
    RECT rect;
    SetRect( &rect, 50,  // left
                    50,  // top
                    850, // right
                    650 ); // bottom
    
    // Save width and height off.
    g.width = rect.right - rect.left;
    g.height = rect.bottom - rect.top;
    
    // Adjust it.
    AdjustWindowRect( &rect, WS_OVERLAPPEDWINDOW, false );

    // AdjustWindowRect() expands the RECT
    // so that the CLIENT AREA (drawable region)
    // has EXACTLY the dimensions we specify
    // in the incoming RECT.

    // If you didn't just understand that, understand
    // this:  "you have to call AdjustWindowRect()",
    // and move on.  Its not THAT important, but its
    // good for the performance of your app.

    ///////////////////
    // NOW we call CreateWindow, using
    // that adjusted RECT structure to
    // specify the width and height of the window.
    g.hwnd = CreateWindow(TEXT("Philip"),
                          TEXT("GL WINDOW!"),
                          WS_OVERLAPPEDWINDOW,
                          rect.left, rect.top,  // adjusted x, y positions
                          rect.right - rect.left, rect.bottom - rect.top,  // adjusted width and height
                          NULL, NULL,
                          hInstance, NULL);

    // check to see that the window
    // was created successfully!
    if( g.hwnd == NULL )
    {
        FatalAppExit( NULL, TEXT("CreateWindow() failed!") );
    }

    // and show.
    ShowWindow( g.hwnd, iCmdShow );
    #pragma endregion

    #pragma region part 2 - Get DC of window we just made
    //2.  GET DC OF WINDOW, and keep it in our global
    //    variable g.  We will NOT release this DC
    //    until our app is about to exit.
    g.hdc = GetDC( g.hwnd );

    // If this keeping-DC-for-life-of-program-thing
    // disturbs you as much as it disturbed me,
    // GOOD LUCK in finding MS-based documentation to validate
    // this practice!  All examples I've seen and
    // Astle's OpenGL gaming book do it this way,
    // so. . . I suppose its ok.

    // One of the things I make sure to do is to specify
    // CS_OWNDC when I create the window,
    // so that Windows maintains a separate device context
    // for my application's window.

    // I haven't run into problems with this.  I don't
    // think you should either.
    #pragma endregion

    #pragma region part 3 - SET PIXEL FORMAT OF HDC
    //3.  SET PIXEL FORMAT OF HDC.
    //
    // We now have to set up the PIXELFORMAT
    // of our HDC.

    // A PIXEL FORMAT just describes the
    // "qualities" that each pixel in the 
    // window will have.  Do you want your
    // OpenGL app to use 24 bit color
    // ("true color" -- really high
    // quality!)?  Or 16 bit color (can look
    // a bit washed out)?

    // There are 3 substeps here:
    //    A> create the PFD and set it up to describe
    //       the pixel format we DESIRE (dream of having!)
    //
    //    B> call ChoosePixelFormat() to make windows
    //       choose us the ID of the appropriate pixel format that
    //       is CLOSEST to our dream pixel format.
    //
    //    C> Call SetPixelFormat() using the integer ID number
    //       that ChoosePixelFormat() returned to us in step B>

    // So let's do that:

    ////////////////////
    // A> CREATE PFD:
    PIXELFORMATDESCRIPTOR pfd = { 0 };  // create the pfd,
    // and start it out with ALL ZEROs in ALL
    // of its fields.

    // A good description of the PIXELFORMATDESCRIPTOR
    // struct is under the documentation
    // for the ChoosePixelFormat() function:
    // http://msdn2.microsoft.com/en-us/library/ms537556(VS.85).aspx

    // If you look at the docs, MANY of the fields
    // are "NOT USED" and REMAIN 0.
    
    // That should be something of a relief to you!
    // Look at the number of fields in this beast!

    // So we set only the fields of the pfd we care about:
    pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );    // just its size
    pfd.nVersion = 1;   // always 1

    pfd.dwFlags = PFD_SUPPORT_OPENGL |  // OpenGL support - not DirectDraw
                  PFD_DOUBLEBUFFER   |  // double buffering support
                  PFD_DRAW_TO_WINDOW;   // draw to the app window, not to a bitmap image

    pfd.iPixelType = PFD_TYPE_RGBA ;    // red, green, blue, alpha for each pixel
    pfd.cColorBits = 24;                // 24 bit == 8 bits for red, 8 for green, 8 for blue.
                                        // This count of color bits EXCLUDES alpha.

    pfd.cDepthBits = 32;                // 32 bits to measure pixel depth.  That's accurate!

    ///////////////////
    // B> Alright!  We've filled out the pfd
    // and it describes the way we want
    // our pixels to appear on the screen.
    // 
    // Now this next step is a little bit weird.
    // The thing is, there are only a couple of
    // dozen ACCEPTABLE pixel formats in existence.
    //
    // In other words, the system MIGHT NOT
    // be able to use a pixel format the likes
    // of which you have described in your
    // PIXELFORMATDESCRIPTOR.

    // What to do?? It would be awful annoying
    // to have to keep TRYING different
    // PIXELFORMATDESCRIPTORS until we found
    // one that actually WORKED on this system.

    // So MSFT has a better solution.

    // We'll make a call to a function called
    // ChoosePixelFormat().  ChoosePixelFormat()
    // will examine the PIXELFORMATDESCRIPTOR
    // structure that you send it, then it will
    // give you back an ID for the pixel format
    // that MOST CLOSELY MATCHES the pixel format you
    // SAID you wanted.

    int chosenPixelFormat = ChoosePixelFormat( g.hdc, &pfd );
    // what comes back from ChoosePixelFormat() is
    // an integer identifier for a specific pixel
    // format that Windows ALREADY knows about.
    // If you got 0 back, then there was an error.
    if( chosenPixelFormat == 0 )
    {
        FatalAppExit( NULL, TEXT("ChoosePixelFormat() failed!") );
    }

    char b[100];
    sprintf(b, "You got ID# %d as your pixelformat!\n", chosenPixelFormat);
    MessageBoxA( NULL, b, "Your pixelformat", MB_OK );
    
    /////////////////
    // C> So finally, we call SetPixelFormat() using the integer ID number
    // that ChoosePixelFormat() returned to us previously.
    int result = SetPixelFormat( g.hdc, chosenPixelFormat, &pfd );

    if (result == NULL)
    {
        FatalAppExit( NULL, TEXT("SetPixelFormat() failed!") );
    }
    // and that's all there is to setting
    // the pixel format!
    //////////
    #pragma endregion

    #pragma region part 4 - CREATE THE RENDERING CONTEXT
    //4.  CREATE RENDERING CONTEXT (HGLRC).

    // What's a rendering context?
    // Its the "surface" that OpenGL
    // will DRAW to.
    
    // The HGLRC will be created
    // such that it is COMPATIBLE
    // with the hdc.

    g.hglrc = wglCreateContext( g.hdc );
    // Created the rendering context
    // and saved handle to it in global 'g'.
    //
    // Wasn't that awfully easy to create
    // such a complicated sounding thing?
    ///////////////
    #pragma endregion

    #pragma region part 5 - CONNECT THE RENDERING CONTEXT WITH THE DEVICE CONTEXT OF THE WINDOW
    //5.  CONNECT THE RENDER CONTEXT (HGLRC)
    //    WITH THE DEVICE CONTEXT (HDC) OF WINDOW.
    wglMakeCurrent( g.hdc, g.hglrc );

    //
    // OPEN GL INIT COMPLETED!!
    ////////////////////////////
    #pragma endregion

    #pragma region message loop
    MSG msg;

    while( 1 )
    {
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
        {
            if( msg.message == WM_QUIT )
            {
                break;
            }
            
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
        {
            //6.  DRAW USING OPENGL.
            // This region right here is the
            // heart of our application.  THE MOST
            // execution time is spent just repeating
            // this draw() function.
            draw();
        }
    }
    #pragma endregion

    //////////////
    // clean up
    #pragma region clean up
    // UNmake your rendering context (make it 'uncurrent')
    wglMakeCurrent( NULL, NULL );

    // Delete the rendering context, we no longer need it.
    wglDeleteContext( g.hglrc );

    // release your window's DC
    ReleaseDC( g.hwnd, g.hdc );
    #pragma endregion

    // and a cheesy fade exit
    AnimateWindow( g.hwnd, 200, AW_HIDE | AW_BLEND );

    return msg.wParam;
}

////////////////////////
// DRAWING FUNCTION
void draw() 
{
    // 1. set up the viewport
    glViewport(0, 0, g.width, g.height); // set viewport
    // to be the whole width and height
    // of the CLIENT AREA (drawable region) of the window,
    // (the CLIENT AREA excludes the titlebar and the 
    // maximize/minimize buttons).

    // 2. projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0,(float)g.width/(float)g.height, 1, 1000);

    // 3. viewing transformation
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(  0, 0, 10,
                0, 0, 0,
                0, 1, 0);

    // 4. modelling transformation and drawing
    glClearColor( 0.5, 0, 0, 0 );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    static float i = 0.01f;
    // Notice that 'i' is a STATIC variable.
    // That's very important. (imagine me saying
    // that like Conchords in "Business Time")
    // http://youtube.com/watch?v=WGOohBytKTU

    // A 'static' variable is created ONCE
    // when the function in which it sits first runs.
    
    // The static variable will "LIVE ON"
    // between seperate calls to the function
    // in which it lives UNTIL THE PROGRAM ENDS.

    i+= 0.001f;     // increase i by 0.001 from its
    // it had on the LAST FUNCTION CALL to the draw() function

    float c = cos( i );
    float s = sin( i );

    glBegin (GL_TRIANGLES);
        glColor3f(  c, 0, 0 );      // red
        glVertex3f( 1+c, 0+s, 0 );

        glColor3f(  c, s, 0 );      // yellow
        glVertex3f( 0+c, 1+s, 0 );

        glColor3f(  s, 0.1f, s );   // magenta
        glVertex3f(-1+c, 0+s, 0 );
    glEnd();

    //7.  SWAP BUFFERS.
    SwapBuffers(g.hdc);
    // Its important to realize that the backbuffer
    // is intelligently managed by the HDC ON ITS OWN,
    // so all's you gots to do is call SwapBuffers
    // on the HDC of your window.
}





////////////////////////
// WNDPROC
// Notice that WndProc is very very neglected.
// We hardly do anything with it!  That's because
// we do all of our processing in the draw()
// function.
LRESULT CALLBACK WndProc(   HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) 
{
    switch( message )
    {
    case WM_CREATE:
        Beep( 50, 10 );
        return 0;
        break;

    case WM_PAINT:
        {
            HDC hdc;
            PAINTSTRUCT ps;
            hdc = BeginPaint( hwnd, &ps );
                // don't draw here.  would be waaay too slow.
                // draw in the draw() function instead.
            EndPaint( hwnd, &ps );
        }
        return 0;
        break;

    case WM_KEYDOWN:
        switch( wparam )
        {
        case VK_ESCAPE:
            PostQuitMessage( 0 );
            break;
        default:
            break;
        }
        return 0;

    case WM_DESTROY:
        PostQuitMessage( 0 ) ;
        return 0;
        break;
    }
 
    return DefWindowProc( hwnd, message, wparam, lparam );
}



////////////////
// END NOTES:
//
// Some good references:
// WGL function ref on MSDN:
// http://msdn2.microsoft.com/en-us/library/ms673957%28VS.85%29.aspx

// MSDN example from 1994 (but still good!)
// "OpenGL I: Quick Start"
// http://msdn2.microsoft.com/en-us/library/ms970745.aspx


//////////////////
// QUICK Q&A (make sure you know what's going on):
//
// QUESTION:  What's the means by which we can draw
//            to our window itself?
//
// ANSWER:  The HDC (HANDLE TO DEVICE CONTEXT).

// QUESTION:  What's the means by which OpenGL can
//            draw to the window?
//
// ANSWER:  USING that SAME HDC WE woulda used
//          to draw to it!! (more to come on this now).

/////////////////////
// It IS possible to access the bits
// of the output of OpenGL in 2 ways:
//      1)  Use glReadPixels() to obtain
//          the arrayful of pixels on the
//          screen.  You can then save this
//          to a .TGA or .BMP file easily.

//      2)  Render to a BITMAP, then
//          blit that bitmap to your HDC.
//          There's a 1995 msdn article on this:
//          "OpenGL VI: Rendering on DIBs with PFD_DRAW_TO_BITMAP"
//          http://msdn2.microsoft.com/en-us/library/ms970768.aspx



/* 
     ____   __   __      __   __  ___
    / _  \ /  / /  /    /  /  \ \/  /
   / _/ / /  / /  /    /  /    \   /
  / _/ \ /  / /  /__  /  /__   /  /
 /_____//__/ /______//______/ /__/

*/

Download the Visual Studio 2005 project files hosted by esnips! (thanks esnips!)

GLUT files

//////////////////////////////////////////
//                                      //
// MOST BASIC GLUT APPLICATION          //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 9/08            //
// Last modified:  Feb 9/08             //
//                                      //
//////////////////////////////////////////

// GLUT is short for "OpenGL Utility Toolkit".
//
// GLUT was originally created by a genius named Mark Kilgard.
//
// GLUT exists only to allow you to easily create a
// window and draw your really cool 3D graphics into that
// window using OpenGL function calls.

// GLUT is NOT really suited to create full blown games,
// and you really should take a look at programming Windows
// if you want to do that.

// BUT, GLUT is a good place to start to understand
// OpenGL in a really simple way.

// GLUT is GREAT for simple projects and demos.

// Its clean, its simple, and it pretty much does
// all the stuff you wanna do in a demo of a short
// program.

///////////////////////////
// GLUT in Visual Studio 2005.

// Here I am explaining how to get GLUT running
// ASSUMING you're using Visual Studio 2005.

// BEFORE STARTING TO RUN THIS PROGRAM:  You must
// first INSTALL GLUT onto your system.
//      TO INSTALL GLUT on your Windows system:
//      1.  Get glut-3.7.6-bin.zip from:
// http://www.xmission.com/~nate/glut.html
//
//      2.  Unzip the file and copy glut32.dll file to:
//C:\Windows\system32
//
//      3.  Copy glut32.lib to:
//C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Lib
//
//      4.  Copy glut.h to:
//C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include\gl

/////////
// Got it installed?  Good!  Let's continue.
/////////


// The first thing we're going to do in our GLUT application is import the
// libraries we'll need:
#include <iostream>  // include the standard
// input/output, so we can write text to the console window
using namespace std;    
#include <glut.h>  // include the OpenGL Utility Toolkit
// -- (Remember, you HAVE TO to follow instructions above
// and INSTALL GLUT first!)

// IMPORTANT:  YOU MUST #include <iostream> BEFORE <glut.h> BEFORE 
// OTHERWISE you will get an 'exit' : redefinition error.

/// render function.  This is THE function that
/// TELLS openGL what to DRAW inside our Window.
void render()
{
    glClear( GL_COLOR_BUFFER_BIT );

	#pragma region drawing code
	glPushMatrix();
		glColor3d( 1.0, 1.0, 1.0 );
		glutSolidTeapot( 0.5 );

		glColor3d( 0.0, 0.0, 1.0 );
		glTranslated( 0.0, 0.6, 0.0 );
		glutSolidTeapot( 0.25 );
	glPopMatrix();
	#pragma endregion

    glutSwapBuffers() ;
}

// Next, we'll write our main() function:
int main( int argc, char** argv )
{


/*
A note about argc and argv — CAN skip, but is good to know

Notice that main() has 2 parameters between the brackets. You might not be used to that, because normally we’d just write int main(). It turns out that when you write a GLUT application, you have to have (int argc, char** argv) between the brackets there. Now, you can take my word for it, because its not REALLY important to understanding OpenGL as to why you need argc and argv, or you can read the paragraph below to understand.

argc and argv are the command line arguments. Here’s an example.

Open the Windows command prompt (to open cmd prompt, go to START->Run, then type cmd in the box that appears there. You should see a black console window, like the one that your basic console C++ apps run in. In the black window, after the C:\Documents and Settings> type in this line:
explorer

What should happen is your windows file explorer should pop up.

Now go back to the command prompt and type in
explorer “C:\Program Files”

Notice now that the Windows disk explorer now opens in the folder “C:\Program Files”

In the above example, “C:\Program Files” is a command line argument that modifies the behaviour of the disk explorer upon its launch.

In the same way, your GLUT app will accept a string or two from the operating system environment that tell it how it should set itself up. We never have to deal with argc and argv DIRECTLY in our GLUT apps, but its good to know.
*/


    // Ok, now for the actual code of our program:

    // these next few lines "speak" to GLUT.
    // Think of GLUT like a living entity.
    // Each time you write a function call
    // that begins with glut___(something),
    // you are COMMANDING GLUT to DO SOMETHING.

    // We're going to write SEVEN (7) commands to GLUT in this program.

    glutInit(&argc, argv);              // initialize GLUT!
// (ask GLUT to
// initialize itself and get ready
// to draw graphics)

    glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);      // Tell GLUT to
// be prepared to draw in all of red, green and blue
// colors (mixes of red, green and
// blue get you all 16 million
// colors available), Also double buffer the display (REQUIRED windows 7)

    glutInitWindowPosition(120,260);    // this tells GLUT
// that WHEN I decide to create a window,
// I want that Window to start
// up 120 pixels from the left
// edge of the screen, and 260
// pixels from the top edge
// of the screen.

    glutInitWindowSize(600,600);        // This tells GLUT
// that WHEN I create a window, I want
// that window to have a width
// of 600 pixels (first number is
// width), and a height of 600
// pixels (second # is height)


// Next, actually CREATE the window.  Will use
// all the information I specified above about
// window position and window size to
// create this window.
    glutCreateWindow("WOO HOO!  This is my GLUT Window!");

    glutDisplayFunc( render );          // "attach" the
// function with name "render" to 
// the "draw" event.  WHENEVER
// my window needs to be "drawn",
// AUTOMATICALLY, GLUT will CALL
// the render() function.

// When does my window need to be
// drawn you ask??  Why, whenever
// it receives a PAINT EVENT from
// the Windows O/S, of course!
// (a window gets a paint event whenever
// the windows O/S recognizes that
// a part of it needs to be redrawn.
// For example, if another window blocks
// your window, and then that
// other window is removed, then
// your window will get a paint event.)

    glutMainLoop();     // START RUNNING THE APP.
    // GOTO render() function.
    // Program is now WAITING for 'messages'
    // from the user, or from the Windows O/S.
    // _PROGRAM CONTROL NEVER RETURNS
    // TO THIS LINE OF CODE AGAIN FOR THE
    // LIFE OF THIS PROGRAM!!_
}





/* 
     ____   __   __      __   __  ___
    / _  \ /  / /  /    /  /  \ \/  /
   / _/ / /  / /  /    /  /    \   /
  / _/ \ /  / /  /__  /  /__   /  /
 /_____//__/ /______//______/ /__/

*/

Check out the Visual Studio project files on esnips

Many, many people, when starting out with DirectX or other Microsoft technologies, go and look for a simple book on the topic.

Many newbies do not know about MSDN. Or, if they do know about MSDN, they don’t know just HOW GOOD and complete it is, simply because they’ve never tried to use it before.

The MSDN documentation CAN BE a bit annoying, simply because its so damn huge.

It is very well organized though, and if you browse through the tree hierarchy on the left (once you’ve got a good starting point!), then its very useful indeed.

The search tool doesn’t always find you the article you’re looking for though, so sometimes trying different search strings can help. Just because a bunch of weird irrelevant stuff turns up in an MSDN search, doesn’t mean that MSDN doesn’t have what you’re looking for!

IN FACT, MOST OF THE BOOKS out there on DirectX SIMPLY ADAPT OR EXPAND ON THE MSDN DOCUMENTATION. A LOT of the time, the book just provides you a subset of what MSDN provides, while not making the material all that much clearer. SOME of the books on DirectX out there are like drinking from a murky pond, while the clearer (not 100% clear, though) lake is right next to it.

As I mentioned, it can be a TAD annoying to have to LOOK FOR the appropriate MSDN article.

So here’s a pageful of links:

MAIN LINK TO DirectX SDK DOCUMENTATION, (NOVEMBER 2007) C++

The rest of these links you can find by simply following the above DirectX links, but I’m including them here for convenience.

MSDN docs on DirectInput

MSDN docs on DirectSound

More interesting stuff from MS. . .

Microsoft XNA presentations – has stuff from Gamefest, SIGGRAPH, and GDC (near the bottom of the page)

VGA, SVGA, XGA, MAC, SXGA, SXGA+, UXGA, QXGA and QSXGA resolutions

also this

Note that there IS a huge difference between d3dx9.lib and d3d9.lib.

Getting error LNK2019: unresolved external symbol _D3DXVec3Normalize@8 referenced in function?

Do this

  1. In visual studio 2005, Go to TOOLS->OPTIONS.

    In that window that comes up, in the left hand side of the window, pick “PROJECTS AND SOLUTIONS” -> VC++ DIRECTORIES from the tree.

    d3d linker error fix

    ALSO do this:
    d3d include

  2. In every code file, include a line at the top that says:

    #pragma comment(lib, "d3dx9.lib")   // d3dx9.lib contains actual code for D3DX functions (like D3DXVec3Normalize)
    

Why?

Although d3dx9.h contains the function prototypes and signatures for the D3DX functions, it DOES NOT contain the actual implementation code.

The implementation code is provided IN “d3dx9.lib” which is why you have to LINK it to the executable at compile time.

No, its not a joke!

Open Inventor

really old but good article on DirectX

some very cool cg stuff

wild assortment of artistic cg tutorials

CG References & Tutorials

Cg is cool, but how do you set it up?

If you’re getting errors like

fatal error C1083: Cannot open include file: ‘Cg/cg.h’: No such file or directory

Or

error LNK2019: unresolved external symbol __imp__cgGLLoadProgram referenced in function _main myCgProgram.obj

you probably don’t have your Visual Studio environment variables set up properly.

Below is a quick explanation of why the error occurs, then simple steps to follow to fix it.

WHY does fatal error C1083: Cannot open include file: ‘Cg/cg.h’: No such file or directory happen, even though I’ve installed the Cg Toolkit?

  • COMPILER ERROR: (“FATAL ERROR”) Cannot include ‘Cg/cg.h’. Happens because Visual Studio CAN’T FIND “Cg.h” because you didn’t tell Visual Studio WHERE to find it. I explain how to tell Visual Studio where to find “Cg.h” later on, in the “DO THIS” section near the bottom of this page.

WHY do I get a linker error?

  • LINKER ERROR: The list of about 50,000 errors that come up saying something about “unresolved external symbol”. This happens because Visual Studio doesn’t know where to find the Cg library files (cg.lib and cgGL.lib)
  • Now if you’re impatient for the answers to fix this ASAP, just skip down to the “DO THIS” section.

    But why do the NVIDIA examples work while the new projects I create don’t?

    We’re going to first examine what Nvidia did to get theirs to work, then we’re going to show how to make yours work easily.

    Open one of the projects that generous Nvidia gives you when you install the Cg toolkit (in the “Cg Toolkit” -> “Explore Cg Toolkit” directory from your start menu)

    Once you have that open, do this:

    Project Property pages

    You get this dialog:

    Dialog

    Now click “C/C++” -> General:

    Additional include directory

    NOTICE under “Additional Include Directories” they’ve ADDED

    $(CG_INC_PATH);c:\Program Files\NVIDIA Corporation\Cg\include

    Ok? NOTICED that? THAT is how NVIDIA is telling Visual Studio where to find “Cg.h” and that will get rid of the FATAL ERROR. However, there’s an easier way that I’ll explain in the “DO THIS” section below.

    NEXT, click “Linker->General”.

    Additional library for linker

    NOTICE there that they have ADDED under “Additional Library Directories”

    $(CG_LIB_PATH);c:\Program Files\NVIDIA Corporation\Cg\lib

    THAT is how NVIDIA tells Cg how to find the library files, which is the first step to fixing the linker errors.

    FINALLY, let’s NOTICE one last thing. Under “Linker->Input”:

    Additional dependencies

    NOTICE under “Additional Dependencies” they’ve added:

    cg.lib cgGL.lib

    So how to fix?

    Well you could go and for every single one of your Visual Studio projects that use Cg, make the same changes that I’ve just shown you pictorally above.

    But that’s painstaking and annoying to do for every project.

    There’s a way to do this that’s better.

    Do this

    To make that part of your default settings in Visual Studio, you have to do the following. Open the Tools->Options menu in Visual Studio:

    Options menu in Visual Studio

    You get window:

    Options dialog in Visual Studio 2005

    On the left hand side of the window, choose “Projects and Solutions”, then choose “VC++ Directories”

    Now do this:

    Add include dirs to env variables

    Next, do this:

    Add lib dirs

    FINALLY, YOU MUST ADD the following 2 lines of code

    #pragma comment( lib, "cg.lib" )
    #pragma comment( lib, "cgGL.lib" )
    

    ANYWHERE in your C program (I usually put them just after #include <Cg/cg.h>).

    Those 2 #pragmas work to do the same thing as the

    cg.lib cgGL.lib

    addition under “additional dependencies”.

    What about using the CGC compiler?

    How do you use the cgc compiler?

    Its actually easy.

    1. Set up cgc environment variable. To do this, see “Adding the Cg Compiler Environment Variable” here
    2. Open up the command line in windows by pressing WINDOWS_KEY+R to get the RUN dialog, then type in “cmd”.

      You get this black window.

      Then, try this.

      cgc -help
      

      To compile a cg program in general using cgc that has filename vertexShader.cg and entry function vertexShaderFunction():

      cgc vertexShader.cg -entry vertexShaderFunction -o vertexShader.vp
      

      vertexShader.cg – name of vertex shader program to compile

      -entry vertexShaderFunction – tells cg the name of the vertex shader function. if you don’t specify the entry function name, then cg looks for an entry function named main(). If there is no main() function in vertexShader.cg and you don’t specify the entry function, then the compilation fails.

      -o vertexShader.vp – the output file. If you open this after compilation, you’ll see all the assembly language that will be sent to the graphics card. Aren’t you glad you don’t have to write that!

    3. and this

Rasterization
The process of determining the set of pixels covered by a geometric primitive.
Framebuffer
Think “frame” as in “single frame of a movie.” The framebuffer is the 2D array of pixels that stores a complete “frame” that the viewer will see on the next refresh cycle of the monitor. Continuously updated, somewhere around 60 times per second.

In a “dumb” framebuffer, the CPU has to update all the pixels. In modern programs, the job of updating of pixel values in the framebuffer is left entirely to the GPU. That frees up the CPU to do other things (AI, process game logic, etc).

Pixel
Look really closely at your monitor. You’ll find that its really made up of thousands and thousands of tiny squares. Each of these tiny squares is called a “pixel”. “Pixel” stands for “picture element.” An average laptop monitor today has something like 1024×768 pixels on it.
Fragment
A fragment is a “piece” of a pixel. Every final pixel that you see on your screen might be the result of blending together many different FRAGMENTS. That’s how you get cool looking images.

For instance, say you’re drawing a complex image from a computer game.

Imagine we’re looking through a water fall at some rocks.

We generate the pixels that should be shown on the monitor, we’ll actually TWO FRAGMENTS for each pixel. One fragment for the WATER at each pixel (which is partly see through), and other fragment for the color of the rock.

At a later stage, we will “blend” the fragments that resulted from drawing the water (which, like I said, are going to be partly see through) and the fragments from drawing the rock to form a single final PIXEL at each little square of the monitor. Every pixel in the end will just have regular RGB color values, even though FRAGMENTS can have some transclucency.

stanford scanning repo

page on the history of the stanford bunny

the stanford bunny was from range images