January 17, 2012

Creating OpenGL shaders

include : glut.h, glew.h
library : glut32.lib, glew32.lib
bin : glut32.dll, glew32.dll

// initialize glew in the begging of application
glewInit();


// compile and link shader program from string
GLhandleARB InstallShaders ( const char *_vsSource, const char *_fsSource )
{
 GLuint program;
 GLuint vs, fs;
 GLint vertCompiled;
 GLint fragCompiled;
 GLint linked;

 vs = glCreateShader ( GL_VERTEX_SHADER );
 if ( vs )
 {
  glShaderSource ( vs, 1, &_vsSource, NULL );
  glCompileShader ( vs );
  glGetShaderiv ( vs, GL_COMPILE_STATUS, &vertCompiled );
  if ( !vertCompiled )
  {
   GLint infologLength = 0;
   glGetShaderiv ( vs, GL_INFO_LOG_LENGTH, &infologLength );

   if ( infologLength > 0 )
   {
    char *infoLog = (char*)malloc ( infologLength );
    glGetShaderInfoLog ( vs, infologLength, NULL, infoLog );
    int dsize = MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, -1, NULL, NULL );
    WCHAR *des = new WCHAR[dsize];
    MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, dsize, des, dsize );
    MessageBox ( g_hMain, des, L"Vertex Shader Compile Error", MB_ICONERROR );
    delete[] des;
    free ( infoLog );
   }
   glDeleteShader ( vs );
   vs = 0;
   return 0;
  }
 }

 fs = glCreateShader ( GL_FRAGMENT_SHADER );
 if ( fs )
 {
  glShaderSource ( fs, 1, &_fsSource, NULL );
  glCompileShader ( fs );
  glGetShaderiv ( fs, GL_COMPILE_STATUS, &fragCompiled );
  if ( !fragCompiled )
  {
   int infologLength = 0;
   glGetShaderiv ( fs, GL_INFO_LOG_LENGTH, &infologLength );

   if ( infologLength > 0 )
   {
    char *infoLog = (char*)malloc ( infologLength );
    glGetShaderInfoLog ( fs, infologLength, NULL, infoLog );
    int dsize = MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, -1, NULL, NULL );
    WCHAR *des = new WCHAR[dsize];
    MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, dsize, des, dsize );
    MessageBox ( g_hMain, des, L"Fragment Shader Compile Error", MB_ICONERROR );
    delete[] des;
    free ( infoLog );
   }
   glDeleteShader ( fs );
   fs = 0;
   return 0;
  }
 }

 if ( vs > 0 && fs > 0 )
 {
  program = glCreateProgram();
  if ( program )
  {
   glAttachShader ( program, vs );
   glAttachShader ( program, fs );

   glDeleteShader ( vs );
   glDeleteShader ( fs );

   glLinkProgram ( program );
   glGetProgramiv ( program, GL_LINK_STATUS, &linked );
   if ( !linked )
   {
    int infologLength = 0;
    glGetProgramiv ( program, GL_INFO_LOG_LENGTH, &infologLength);

    if ( infologLength > 0 )
    {
     char *infoLog = (char*)malloc ( infologLength );
     glGetProgramInfoLog ( program, infologLength, NULL, infoLog );
     int dsize = MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, -1, NULL, NULL );
     WCHAR *des = new WCHAR[dsize];
     MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, dsize, des, dsize );
     MessageBox ( g_hMain, des, L"Shader Link Error", MB_ICONERROR );
     delete[] des;
     free ( infoLog );
    }
    glDeleteProgram ( program );
    program = 0;
    return 0;
   }

   return program;
  }
  return 0;
 }
 return 0;
}


// clean up shader
GLint CleanUpShaders ( GLuint *_program )
{
 glDeleteProgram ( *_program );
 _program = 0;
 return 1;
}

Trace in visual studio

include : windows.h, stdio.h, stdarg.h
void Trace ( char *_format, ... )
{
 va_list args;
 va_start ( args, _format );
 int len = _vscprintf ( _format, args ) + 1;
 char *str = new char[len];
 vsprintf_s ( str, len, _format, args );
 va_end ( args );
 int dsize = MultiByteToWideChar ( CP_ACP, 0, str, -1, NULL, NULL );
 WCHAR *des = new WCHAR[dsize];
 MultiByteToWideChar ( CP_ACP, 0, str, dsize, des, dsize );
 OutputDebugString ( des );
 delete[] des;
 delete[] str;
}

January 12, 2012

Save BMP file using win32 API

include : windows.h
int SaveBMP ( const unsigned char *_buf, const char *_name, const int _width, const int _height )
{
 int i, j;
 BITMAPFILEHEADER bmfh;
 memset ( &bmfh, 0, sizeof ( BITMAPFILEHEADER ) );
 bmfh.bfType = 0x4d42;
 bmfh.bfSize = sizeof ( BITMAPFILEHEADER ) + sizeof ( BITMAPINFOHEADER ) + _width * _height * 3 + ( _width % 4 ) * _height + 2;
 bmfh.bfReserved1 = 0;
 bmfh.bfReserved2 = 0;
 bmfh.bfOffBits = sizeof ( BITMAPFILEHEADER ) + sizeof ( BITMAPINFOHEADER );

 BITMAPINFOHEADER bmih;
 memset ( &bmih, 0, sizeof ( BITMAPINFOHEADER ) );
 bmih.biSize = sizeof ( BITMAPINFOHEADER );
 bmih.biWidth = _width;
 bmih.biHeight = _height;
 bmih.biPlanes = 1;
 bmih.biBitCount = 24;
 bmih.biCompression = BI_RGB;
 bmih.biSizeImage = 0;
 bmih.biXPelsPerMeter = 0;
 bmih.biYPelsPerMeter = 0;
 bmih.biClrUsed = 0;
 bmih.biClrImportant = 0;

 FILE *bmf = NULL;
 if ( fopen_s ( &bmf, _name, "wcb" ) != 0 ) return -1;

 fwrite ( &bmfh, sizeof ( BITMAPFILEHEADER ), 1, bmf );
 fwrite ( &bmih, sizeof ( BITMAPINFOHEADER ), 1, bmf );

 unsigned char c = 0;
 int index;

 for ( i = _height-1; i >= 0; i-- )
 {
  for ( j = 0; j < _width; j++ )
  {
   index = i*_width+j;
   c = _buf[index*4+2];
   fwrite ( &c, sizeof ( unsigned char ), 1, bmf );
   c = _buf[index*4+1];
   fwrite ( &c, sizeof ( unsigned char ), 1, bmf );
   c = _buf[index*4+0];
   fwrite ( &c, sizeof ( unsigned char ), 1, bmf );
  }

  c = 0;
  switch ( _width % 4 )
  {
  case 3:
   fwrite ( &c, sizeof ( unsigned char ), 1, bmf );
  case 2:
   fwrite ( &c, sizeof ( unsigned char ), 1, bmf );
  case 1:
   fwrite ( &c, sizeof ( unsigned char ), 1, bmf );
  case 0:
   break;
  }
 }

 c = 0;
 fwrite ( &c, sizeof ( unsigned char ), 1, bmf );
 fwrite ( &c, sizeof ( unsigned char ), 1, bmf );

 fflush ( bmf );
 fclose ( bmf );
 bmf = NULL;

 return 1;
}

Read image from file in win32 using gdiplus

include : gdiplus.h
library : gdiplus.lib

// initialize in the begging of application
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR hgdiplusToken;
Gdiplus::GdiplusStartup ( &hgdiplusToken, &gdiplusStartupInput, NULL );


// read image from file
Gdiplus::Bitmap *bitmap = new Gdiplus::Bitmap ( L"filename.png" );
int width = bitmap->GetWidth();
int height = bitmap->GetHeight();
Gdiplus::Rect rt ( 0, 0, width, height );
unsigned char *image = new unsigned char[width*height*4];
Gdiplus::BitmapData data;
bitmap->LockBits ( &rt, Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &data );
memcpy ( image, data.Scan0, sizeof ( unsigned char ) * width * height * 4 );
bitmap->UnlockBits ( &data );
delete bitmap;
bitmap = NULL;


// release in the end of application
delete[] image;
Gdiplus::GdiplusShutdown ( hgdiplusToken );