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-1.0.0.zip
file from here and extract it.MINGW.zip
file from here and extract it.MINGW
folder to the extracted Modern-iGraphics-1.0.0
folder.Modern-iGraphics-1.0.0
โโโ MINGW
โ โโโ bin
โ โโโ include
โ โโโ lib
โ โโโ ....
โ โโโ share
โโโ OpenGL
โโโ assets
โโโ bin
โโโ 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'
iExitMainLoop();
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
iWindowedMode(400, 400, "iGraphics");
iStartMainLoop();
// Execution will continue from here once iExitMainLoop() is called or window is closed.
return 0;
}
iGraphics.h
void iWindowedMode(int width=500, int height=500, char* title="iGraphics")
width
: Width of the window.height
: Height of the window.title
: Title of the window.iWindowedMode(300, 300, "iGraphics");
void iGameMode(const char *gameModeStr = W800_X_H600)
gameModeStr
: String representing the game mode.
W800_X_H600
: 800x600 resolution.W1024_X_H768
: 1024x768 resolution.W1280_X_H720
: 1280x720 resolution.W1920_X_H1080
: 1920x1080 resolution.iGameMode(W1280_X_H720);
void iStartMainLoop()
iExitMainLoop()
is called.iStartMainLoop();
void iExitMainLoop()
iStartMainLoop()
.void iKeyPress(unsigned char key)
{
switch (key)
{
case 'q':
iExitMainLoop();
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 iTextBold(double x, double y, char *str, void* font=GLUT_BITMAP_8_BY_13)
void iTextAdvanced(double x, double y, const char *str, float scale = 0.3, float weight = 1.0, void *font = GLUT_STROKE_ROMAN)
x
, y
: Coordinates of the first character.str
: The text to display.scale
: Scale factor for the text.weight
: Weight of the text (1.0 for normal, 2.0 for bold).font
: Font type (default is GLUT_STROKE_ROMAN
).iTextAdvanced(50, 60, "This is a text", 0.5, 2.0);
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 iWindowedMode();
...
iWindowedMode(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 iGetVisiblePixelsCount(Sprite* s1)
s1
: Pointer to the Sprite
structure.Sprite s1;
...
int visiblePixels = iGetVisiblePixelsCount(&s1);
FrameSet iCreateFrameSet(Image *frames, int count)
FrameSet
from an array of images.frames
: Pointer to an array of Image
structures.count
: Number of frames in the array.FrameSet
structure containing the frames.Example:
Image frames[4];
...
FrameSet frameSet = iCreateFrameSet(frames, 4); // Create a FrameSet from the array of images
Image singleImg;
...
FrameSet frameSet = iCreateFrameSet(&singleImg, 1); // Create a FrameSet from a single image
<!-- Collision Detection -->
### ๐ก๏ธ Collision Detection
#### `int iCheckImageCollision(int x1, int y1, Image *img1, int x2, int y2, Image *img2)`
- **Description:** Checks for pixel-level collision between two images.
- **Parameters:**
- `x1`, `y1`: Coordinates of the first image.
- `img1`: Pointer to the first `Image` structure.
- `x2`, `y2`: Coordinates of the second image.
- `img2`: Pointer to the second `Image` structure.
- **Returns:** Number of overlapping pixels. `>= 1` if collision is detected, `0` otherwise.
- **Note:** This function doesn't consider image rotation (Using `iRotate` and `iUnRotate`). Use `iCheckSpriteCollision` for such cases.
- **Example:**
```cpp
Image img1, img2;
iLoadImage(&img1, "image1.png");
iLoadImage(&img2, "image2.png");
....
// Check for collision between img1 at (100, 200) and img2 at (150, 250)
if (iCheckImageCollision(100, 200, &img1, 150, 250, &img2)) {
// Collision detected
}
int iCheckSpriteCollision(Sprite* s1, Sprite* s2)
Description: Checks for pixel-level collision between two sprites.
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 (iCheckSpriteCollision(&s1, &s2)) {
// Collision detected
}
int iCheckImageSpriteCollision(int x1, int y1, Image *img, Sprite *s)
x1
, y1
: Coordinates of the image.img
: Pointer to the Image
structure.s
: Pointer to the Sprite
structure.>= 1
if collision is detected, 0
otherwise.iRotate
and iUnRotate
). Use iCheckSpriteCollision
for such cases.Image img;
Sprite s;
iLoadImage(&img, "image.png");
....
if (iCheckImageSpriteCollision(100, 200, &img, &s)) {
// Collision detected between image and sprite
}
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.