iGraphics.h header file contains some drawing functions that can be used to draw basic graphical shapes in C++. These functions are implemented in OpenGL. Users of iGraphics do not need any knowledge of OpenGL to use it. Simply calling the drawing functions a user can draw any 2D shape on screen. This library also provides easy ways for animation, keyboard and mouse event handling.
It was originally created by Shahriar Nirjon on 2009 with limited functionalities and only for Windows. This is an extended version of the original iGraphics library with support for multiple image formats, custom fonts, sound engine, sprite management, collision detection and advanced mouse-keyboard control. The library is now cross-platform and works on both Windows and Linux. Updates will be added incrementally based on requests.
Feature | Original iGraphics (2009) | Modern iGraphics (2025) |
---|---|---|
Cross-Platform Support | โ Windows only | โ Windows & Linux |
Image Formats | โ BMP only | โ Multiple formats |
Audio Formats | โ WAV only | โ Multiple formats |
Font Support | โ Limited bitmap fonts | โ Custom TTF fonts |
Sound Integration | โ Single Channel | โ Multi-Channel |
Input Handling | โ Basic | โ Enhanced controls |
Transparency Support | โ Not available | โ Full RGBA color support |
Image Manipulation | โ No transformations | โ Rotate/Scale/Flip/Wrap |
Image rendering | โ Slow | โ Fast (Texture-based + Caching) |
Sprite Management | โ Manual implementation | โ Built-in sprite system |
Collision Detection | โ Not available | โ Pixel-perfect collision |
You can find executable games here
Modern-iGraphics-main.zip
file from here and extract it.MINGW.zip
file from here and extract it.MINGW
folder to the extracted Modern-iGraphics-main
folder.Modern-iGraphics-main
โโโ MINGW
โ โโโ bin
โ โโโ include
โ โโโ lib
โ โโโ ....
โ โโโ share
โโโ OpenGL
โโโ assets
โโโ bin
โโโ obj
โโโ examples
โโโ iGraphics.h
โโโ iGraphics.cbp
โโโ iMain.cpp
โโโ ....
Change the compiler path of Code::Blocks as following:
Settings
โ Compiler
โ Go to Toolchain executables
tab โ Change the Compiler's installation directory
to the MINGW
directory in the iGraphics folder. You can do that by clicking the three dots (...
) on right. After you change the compiler, clear the .o
files inside obj
folder (If there is any).
Open iGraphics.cbp
in Code::Blocks. The project is already configured with all the necessary settings. You can directly run the project. By default, the main file is iMain.cpp
. You can remove it and add a different file if you want.
You can find the slides with step-by-step screenshots here.
Download the Library: Clone or download the iGraphics library from the repository.
git clone https://github.com/mahirlabibdihan/Modern-iGraphics
cd Modern-iGraphics
Alternatively, you can download the ZIP file from here and extract it.
Running the Example:
Ensure that g++
is installed on your system and available in your PATH. Then, run the following command to compile and execute the example program:
.\runner.bat examples\BallDemo.cpp
sudo apt install libglu1-mesa-dev freeglut3-dev mesa-common-dev
sudo apt install libsdl2-dev libsdl2-mixer-dev
sudo apt install libfreetype6-dev
./runner.sh examples/BallDemo.cpp
pacman -S mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_mixer
pacman -S mingw-w64-x86_64-freeglut mingw-w64-x86_64-gcc
pacman -S mingw-w64-x86_64-freetype
./runner.sh examples/BallDemo.cpp
For quick project setup, use the provided project creation scripts:
Windows:
.\create_project.bat MyGameName
Linux/Unix:
./create_project.sh MyGameName
These scripts will automatically generate a complete starter template with:
Organize Your Assets
Save Files
Run the Release Script
.\release.bat iMain.cpp
Check the Output
release โ windows โ x86
game.exe
to ensure your game runs properly.iMain.cpp
Users of iGraphics
only have to edit, compile and run iMain.cpp. See the listing of iMain.cpp
below:
#include "iGraphics.h"
/*
function iDraw() is called again and again by the system.
*/
void iDraw()
{
//place your drawing codes here
iClear();
}
/*
function iMouseClick() is called when the user presses/releases the mouse.
(mx, my) is the position where the mouse pointer is.
*/
void iMouseClick(int button, int state, int mx, int my)
{
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
//place your codes here
}
if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
//place your codes here
}
}
/*
function iMouseMove() is called when the user moves the mouse.
(mx, my) is the position where the mouse pointer is.
*/
void iMouseMove(int mx, int my)
{
//place your codes here
}
/*
function iKeyPress() is called whenever the user hits a key in keyboard.
key- holds the ASCII value of the key pressed.
*/
void iKeyPress(unsigned char key)
{
switch (key)
{
case 'q':
// do something with 'q'
iCloseWindow();
break;
// place your codes for other keys here
default:
break;
}
}
/*
function iSpecialKeyPress() is called whenver user hits special keys likefunction
keys, home, end, pg up, pg down, arraows etc. you have to use
appropriate constants to detect them. A list is:
GLUT_KEY_F1, GLUT_KEY_F2, GLUT_KEY_F3, GLUT_KEY_F4, GLUT_KEY_F5, GLUT_KEY_F6,
GLUT_KEY_F7, GLUT_KEY_F8, GLUT_KEY_F9, GLUT_KEY_F10, GLUT_KEY_F11,
GLUT_KEY_F12, GLUT_KEY_LEFT, GLUT_KEY_UP, GLUT_KEY_RIGHT, GLUT_KEY_DOWN,
GLUT_KEY_PAGE_UP, GLUT_KEY_PAGE_DOWN, GLUT_KEY_HOME, GLUT_KEY_END,
GLUT_KEY_INSERT */
void iSpecialKeyPress(unsigned char key)
{
switch (key)
{
case GLUT_KEY_END:
// do something
break;
// place your codes for other keys here
default:
break;
}
}
int main(int argc, char *argv[])
{
// Initialization code before opening the window
iOpenWindow(400, 400, "iGraphics");
// Execution will continue from here once iCloseWindow() is called.
return 0;
}
iGraphics.h
void iOpenWindow(int width=500, int height=500, char* title="iGraphics")
width
: Width of the window.height
: Height of the window.title
: Title of the window.iOpenWindow(300, 300, "iGraphics");
void iCloseWindow()
void iKeyPress(unsigned char key)
{
switch (key)
{
case 'q':
iCloseWindow();
break;
default:
break;
}
}
void iClear()
iClear();
void iSetColor(int r, int g, int b)
r
: Red component of color (0-255).g
: Green component of color (0-255).b
: Blue component of color (0-255).iSetColor(255, 0, 0); // Red
void iSetTransparentColor(int r, int g, int b, double a)
r
, g
, b
: RGB values (0-255).a
: Alpha value (0.0 to 1.0). iSetTransparentColor(255, 0, 0, 0.5); // Semi-transparent red
void iGetPixelColor(int x, int y, int rgb[])
(x, y)
.x
, y
: Coordinates of the pixel.rgb[]
: Array to store RGB values.iGetPixelColor(100, 120, array);
void iPoint(double x, double y, int size=0)
(x, y)
using current color.x
, y
: Coordinates.size
: Optional size.iPoint(10, 20);
void iLine(double x1, double y1, double x2, double y2)
x1
, y1
: One end.x2
, y2
: Other end.iLine(10, 20, 100, 120);
void iCircle(double x, double y, double r, int slices=100)
x
, y
: Center.r
: Radius.slices
: Segments to draw.iCircle(10, 20, 10);
void iFilledCircle(double x, double y, double r, int slices=100)
iCircle
.iFilledCircle(10, 20, 10);
void iEllipse(double x, double y, double a, double b, int slices=100)
x
, y
: Center.a
, b
: Axes lengths.slices
: Segments to draw.iEllipse(10, 20, 10, 5);
void iFilledEllipse(double x, double y, double a, double b, int slices=100)
iEllipse
.iFilledEllipse(10, 20, 10, 5);
void iRectangle(double left, double bottom, double dx, double dy)
left
: x-coordinate of bottom-left.bottom
: y-coordinate of bottom-left.dx
: Width.dy
: Height.iRectangle(10, 20, 10, 5);
void iFilledRectangle(double left, double bottom, double dx, double dy)
iRectangle
.iFilledRectangle(10, 20, 10, 5);
void iPolygon(double x[], double y[], int n)
x
, y
: Arrays of coordinates of vertices.n
: Number of vertices.double xa[] = {0, 10, 5};
double ya[] = {0, 0, 10};
iPolygon(xa, ya, 3);
void iFilledPolygon(double x[], double y[], int n)
iPolygon
.double xa[] = {0, 10, 5};
double ya[] = {0, 0, 10};
iFilledPolygon(xa, ya, 3);
void iSetLineWidth(float width)
width
- Line width in pixels.iSetLineWidth(3.0); // Set line width to 3 pixels
iLine(0, 0, 100, 100); // Draw a thick line
void iShowSpeed(double x, double y)
x
, y
: Coordinates where FPS will be displayed.iShowSpeed(10, 10); // Show FPS counter at top-left corner
void iText(double x, double y, char *str, void* font=GLUT_BITMAP_8_BY_13)
x
, y
: Coordinates of the first character.str
: The text to display.font
: (Optional) Font type. Available fonts include:
GLUT_BITMAP_8_BY_13
GLUT_BITMAP_9_BY_15
GLUT_BITMAP_TIMES_ROMAN_10
GLUT_BITMAP_TIMES_ROMAN_24
GLUT_BITMAP_HELVETICA_10
GLUT_BITMAP_HELVETICA_12
GLUT_BITMAP_HELVETICA_18
iText(50, 60, "This is a text", GLUT_BITMAP_TIMES_ROMAN_10);
void iRotate(double x, double y, double degree)
x
, y
: Coordinates of the point to rotate around.degree
: Angle in degrees to rotate.iRotate(100, 100, 45); // Rotate around point (100, 100) by 45 degrees
iShowImage(50, 50, "image.png"); // This image will be rotated
iUnRotate();
void iScale(double x, double y, double scaleX, double scaleY)
x
, y
: Coordinates of the point to scale around.scaleX
: Scaling factor in the x-direction.scaleY
: Scaling factor in the y-direction.iScale(0,0, 2.0, 1.5); // Scale around the origin (0, 0) by 2.0 in x and 1.5 in y
// This will affect all subsequent drawing operations
iUnScale();
int iSetTimer(int msec, void (*f)(void))
msec
: Time interval in milliseconds.f
: Function to be executed.Example:
void func() {
//code of the task that will be repeated.
}
int main(int argc, char *argv[])
{
...
int t = iSetTimer(100, func); // //call it inside main() before iOpenWindow();
...
iOpenWindow(400, 400, "iGraphics");
}
void iPauseTimer(int index)
index
of the timer.iPauseTimer(t);
void iResumeTimer(int index)
index
of the timer.iResumeTimer(t);
void iDelay(int sec)
sec
in seconds.iDelay(5); // Pauses for 5 seconds
void iMouseClick(int button, int state, int mx, int my)
button
: Button pressed (GLUT_LEFT_BUTTON, GLUT_RIGHT_BUTTON, GLUT_MIDDLE_BUTTON).state
: State of the button (GLUT_DOWN or GLUT_UP).mx
, my
: Coordinates of the mouse pointer.void iMouseMove(int mx, int my)
mx
, my
: Coordinates of the mouse pointer.void iMouseDrag(int mx, int my)
mx
, my
: Coordinates of the mouse pointer.void iMouseWheel(int dir, int mx, int my)
dir
: Direction of scroll (1 for up, -1 for down).mx
, my
: Coordinates of the mouse pointer.void iShowCursor()
iShowCursor();
void iHideCursor()
iHideCursor();
void iKeyPress(unsigned char key)
key
: ASCII value of the key pressed.void iSpecialKeyPress(unsigned char key)
key
: Special key value (e.g., GLUT_KEY_LEFT
, GLUT_KEY_RIGHT
, etc.).void iKeyRelease(unsigned char key)
key
: ASCII value of the key released.void iSpecialKeyRelease(unsigned char key)
key
: Special key value (e.g., GLUT_KEY_LEFT
, GLUT_KEY_RIGHT
, etc.).int isKeyPressed(unsigned char key)
key
to check.1
if pressed, 0
otherwise.if (isKeyPressed('a')) {
// 'a' key is pressed
}
int isSpecialKeyPressed(unsigned char key)
key
to check.1
if pressed, 0
otherwise.if (isSpecialKeyPressed(GLUT_KEY_LEFT)) {
// Left arrow key is pressed
}
iGraphics
was originally designed for graphical applications, but it has been extended to support sound playback using the SDL2
library. The sound functions are available in iSound.h
and are shown below:
int iPlaySound(const char *filename, int loop = 0, int volume = 100)
filename
: Path to the sound file.loop
: true
for continuous play, false
for one-time play.volume
: Volume level (0-100).Example:
#include "iSound.h" // Include the sound header
...
int channel = iPlaySound("background.wav", true, 80);
void iPauseSound(int channel)
channel
.channel
of the sound.iPauseSound(channel);
void iResumeSound(int channel)
channel
.channel
of the sound.iResumeSound(channel);
void iStopSound(int channel)
channel
. Frees the channel for other sounds.channel
of the sound.iStopSound(channel);
void iStopAllSounds()
void iSetVolume(int channel, int volume)
index
: Index of the sound.volume
: Volume level (0-100).void iIncreaseVolume(int channel, int amount)
index
: Index of the sound.amount
: Amount to increase the volume by (0-100).void iDecreaseVolume(int channel, int amount)
index
: Index of the sound.amount
: Amount to decrease the volume by (0-100).Custom font rendering is supported using TrueType fonts. freetype
library is used to render text. The new text functions are available in iFont.h
and are shown below:
void iShowText(double x, double y, const char *text, const char *fontPath, int fontSize = 48)
x
, y
: Coordinates of the first character.text
: The text to display.fontPath
: Path to the TrueType font file (e.g., โassets/fonts/arial.ttfโ).fontSize
: Size of the font (default is 48).Example:
#include "iFont.h" // Include the font header
...
iShowText(50, 60, "This is a text", "assets/fonts/arial.ttf", 48);
void iShowImage(int x, int y, const char *filename)
Parameters:
x
, y
: Coordinates where the image will be displayed.filename
: Path to the image file.iShowImage(100, 200, "image.png");
int iLoadImage(Image* img, const char filename[])
Description: Loads an image from file. Supports multiple image formats (BMP, PNG, JPG, GIF) with the help of the stb_image library.
Parameters:
img
: Pointer to an Image
structure.filename
: Path to the image file.
true
if successful, false
otherwise.Image img;
if (iLoadImage(&img, "image.png")) {
// Image loaded successfully
} else {
// Failed to load image
}
typedef struct
{
unsigned char *data;
int width, height, channels;
GLuint textureID; // OpenGL texture ID
} Image;
void iShowLoadedImage(int x, int y, Image* img)
iLoadImage
.Parameters:
x
, y
: Coordinates where the image will be displayed.img
: Pointer to the loaded Image
structure.Example:
Image img;
iLoadImage(&img, "image.png");
iShowLoadedImage(100, 200, &img);
void iScaleImage(Image* img, double scale)
Parameters:
img
: Pointer to the loaded Image
structure.scale
: Scaling factor (e.g., 2.0 for double size).iScaleImage(&img, 2.0);
void iResizeImage(Image* img, int width, int height)
img
: Pointer to the loaded Image
structure.width
: New width of the image.height
: New height of the image.Example:
iResizeImage(&img, 200, 100); // Resize to 200x100 pixels
void iMirrorImage(Image* img, MirrorState state)
Parameters:
img
: Pointer to the loaded Image
structure.state
: HORIZONTAL
or VERTICAL
. Here, MirrorState is an enum.Example:
iMirrorImage(&img, HORIZONTAL); // Mirror horizontally
void iWrapImage(Image* img, int dx = 0, int dy = 0)
dx
pixels horizontally and dy
pixels vertically. This function is useful for creating infinite scrolling backgrounds.img
: Pointer to the loaded Image
structure.dx
: Horizontal shift in pixels (default is 0).
dx
shifts the image to the right.dx
shifts the image to the left.dy
: Vertical shift in pixels (default is 0).
dy
shifts the image down.dy
shifts the image up.Example:
iWrapImage(&img, 50); // Wrap the image by 50 pixels to the right
iWrapImage(&img, -50); // Wrap the image by 50 pixels to the left
iWrapImage(&img, 0, 30); // Wrap the image by 30 pixels down
iWrapImage(&img, 0, -30); // Wrap the image by 30 pixels up
void iIgnorePixels(Image* img, int ignoreColor)
img
: Pointer to the loaded Image
structure.ignoreColor
: Color to ignore in 0xRRGGBB format (e.g., 0xFF0000 for red).iIgnorePixels(&img, 0xFFFFFF); // Make white pixels transparent
void iFreeImage(Image* img)
Free sprite resources: https://craftpix.net/freebies/
Online sprite cutter: https://ezgif.com/sprite-cutter
FrameSet Structure
typedef struct
{
Image *frames;
int count;
} FrameSet;
Sprite Structure
typedef struct
{
int x, y;
FrameSet frameSet;
int currentFrame;
....
} Sprite;
int iLoadFramesFromFolder(FrameSet *frames, const char *folderPath)
Parameters:
frames
: Pointer to a FrameSet
structure.folderPath
: Path to the folder containing images.FrameSet frames;
iLoadFramesFromFolder(&frames, "sprites/"); // Load images from "sprites/" folder
int iLoadFramesFromSheet(FrameSet *frames, const char *filename, int rows, int cols)
Parameters:
frames
: Pointer to a FrameSet
structure.filename
: Path to the sprite sheet image.rows
: Number of rows in the sprite sheet.cols
: Number of columns in the sprite sheet.Returns: Number of frames loaded. -1 if failed to load the sprite sheet.
FrameSet frames;
iLoadFramesFromSheet(&frames, "spritesheet.png", 4, 4); // Load images frames a sprite sheet with 4 rows and 4 columns
void iChangeSpriteFrames(Sprite *s, const FrameSet* frames)
Parameters:
s
: Pointer to a Sprite
structure.frames
: Pointer to a FrameSet
structure representing the new frames.FrameSet frames;
iLoadFramesFromFolder(&frames, "sprites/"); // Load images from a folder
Sprite s;
iChangeSpriteFrames(&s, &frames);
void iSetSpritePosition(Sprite* s, int x, int y)
s
: Pointer to a Sprite
structure.x
, y
: New coordinates for the sprite.iSetSpritePosition(&s, 100, 200); // Set sprite position to (100, 200)
void iShowSprite(Sprite* s)
s
: Pointer to a Sprite
structure.void iAnimateSprite(Sprite* s)
s
: Pointer to a Sprite
structure.iAnimateSprite(&s); // Animate the sprite
void iScaleSprite(Sprite* s, double scale)
s
: Pointer to a Sprite
structure.scale
: Scaling factor (e.g., 2.0 for double size).void iResizeSprite(Sprite* s, int width, int height)
s
: Pointer to a Sprite
structure.width
: New width of the sprite.height
: New height of the sprite.void iMirrorSprite(Sprite* s, MirrorState state)
s
: Pointer to a Sprite
structure.state
: HORIZONTAL
or VERTICAL
.void iRotateSprite(Sprite* s, double x, double y, double degree)
(x, y)
by a specified angle in degrees.s
: Pointer to a Sprite
structure.x
, y
: Coordinates of the point to rotate around.degree
: Angle in degrees to rotate.iRotateSprite(&s, 100, 100, 45); // Rotate sprite around point (100, 100) by 45 degrees
void iFreeSprite(Sprite* s)
s
: Pointer to a Sprite
structure.int iCheckCollision(Sprite* s1, Sprite* s2)
Description: Checks for pixel-level collision between two sprites. If the bounding box of two images do not overlap, this has a time complexity of O(1)
. Otherwise, it has a time complexity of O(wh)
, where w
and h
are the width and height of the overlapping area of the two images.
s1
: Pointer to the first Sprite
structure.s2
: Pointer to the second Sprite
structure.1
if collision is detected, 0
otherwise.Sprite s1, s2;
....
if (iCheckCollision(&s1, &s2)) {
// Collision detected
}
int iGetVisiblePixelsCount(Sprite* s1)
s1
: Pointer to the Sprite
structure.Sprite s1;
...
int visiblePixels = iGetVisiblePixelsCount(&s1);
void iEnterFullscreen()
iEnterFullscreen(); // Enter fullscreen mode
void iLeaveFullscreen()
iLeaveFullscreen(); // Exit fullscreen mode
This library is for educational purposes and is typically used in academic or hobbyist OpenGL projects.