Guide How to get started with OpenGL Hacks

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,065
78,998
2,370
Game Name
N/A
Tutorial Link
N/A
How long you been coding/hacking?
4 Years
85% of games do rendering with Direct3d thanks to MIcrosoft's monopoly, but some games you hack may use OpenGL. If you're doing an ESP or other drawing you want to use whatever rendering API is used by the game. Then you just hook it and draw. Alternatively you can do an OpenGL transparent overlay window and draw on top of it.

OpenGL is pretty cool but you should focus on Direct3D for hacking games, as that's what most use and it might be a waste of your time to learn multiple APIs. The APIs are quite similar, you're basically learning 3d game programming when doing this, the concepts are all the same it's just the implementation that's different.

MOST IMPORTANT CONTENT:

SwapBuffers Hook
In the case of OpenGL you will want to hook SwapBuffers. In rendering a game, there is a frame that is presented on the screen and then there is a backbuffer that is also being drawn to, when the frame is finished drawing you call SwapBuffers and it puts the back buffer onto the screen. So if you draw in a SwapBuffers hook, all the drawing is already done on the screen, so you're guaranteed to be drawing on top of the frame, and any OpenGL stuff you do will not affect the next frame.
swap buffers hook here

Using Trampoline Function Hook - Source Code - OpenGL SwapBuffers Hook Template
Using ASM detour Tutorial - OpenGL SwapBuffers Hooking (For Drawings and etc)

How to Draw 2D ESP & Menu in a 3d Game
The easiest way to draw 2D is to use an orthographic projection matrix, which you need to setup in your SwapBuffers hook before you draw, then after you draw you need to reset back to whatever the game was using before it was changed.
OpenGL is a state machine and throughout execution there are different states and state variables being modified. Every will call SwapBuffers with certain variables set or unset. Here are functions that setup a orthagraphic projection for you, set the right vars and then reset everything back to normal for Assault Cube. With a few minor changes it can work with other similar games like OpenArena. But every game is different and you have to figure it out.

C++:
void GL::SetupOrtho()
{
    GLint viewport[4];
    glGetIntegerv(GL_VIEWPORT, viewport);
    glViewport(0, 0, viewport[2], viewport[3]);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, viewport[2], viewport[3], 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glDisable(GL_DEPTH_TEST);
}

void GL::RestoreGL()
{
    glEnable(GL_DEPTH_TEST);
}
You can use glPopMatrix, glPushMatrix, glPushAttribute & glPopAttribute as well, there is definitly a more dynamic way to do this using those.

Need to find out exactly what modes/states to set? Try this: dtrebilco/glintercept

Want to use your own OpenGL Context so you don't have to modify the gl states? It's very easy: Video Tutorial - OpenGL Hooking, Drawing & Text Rendering Tutorial

OpenGL Drawing Methods
There are kind of 3 ways to draw in OpenGL, Immediate Mode, glDrawArrays, & VBO/VAOs. 99% of people will want to use immediate mode. Hooking and drawing with the other methods will be much more work.

Immediate Mode:
glBegin(GL_LINES);
glVertex2i(0, 0);
glVertex2i(5, 5);
glEnd();
If the game uses Immediate Mode, you should also use Immediate Mode because the game probably doesn't support the other methods without serious modification.

glDrawArrays:
int crossHair[8] =
{
    // horizontal line
    *windowWidth / 2 - 7, *windowHeight / 2,
    *windowWidth / 2 + 7, *windowHeight / 2,
     //vertical line
    *windowWidth / 2, *windowHeight / 2 + 7,
    *windowWidth / 2, *windowHeight / 2 - 7
};

// activate vertext array state and assign pointer to vertext array data
glEnableClientState(GL_VERTEX_ARRAY);

//2 = number of coordinates per vertex
//GL_INT = data type held in array
//crossHair = pointer to vertext data array
glVertexPointer(2, GL_INT, 0, crossHair);

//draw primitive GL_LINES starting at the first vertex, use 2 total vertices
glDrawArrays(GL_LINES, 0, 2); //draw horizontal line
//Same as above but start at second vertex
glDrawArrays(GL_LINES, 2, 2); //draw vertical line

// deactivate vertex array state after drawing
glDisableClientState(GL_VERTEX_ARRAY);
VAO VBO:
GLuint vboId;                              // ID of VBO
GLfloat* vertices = new GLfloat[vCount*3]; // create vertex array
...

// generate a new VBO and get the associated ID
glGenBuffers(1, &vboId);

// bind VBO in order to use
glBindBuffer(GL_ARRAY_BUFFER, vboId);

// upload data to VBO
glBufferData(GL_ARRAY_BUFFER, dataSize, vertices, GL_STATIC_DRAW);

// it is safe to delete after copying data to VBO
delete [] vertices;
...

// delete VBO when program terminated
glDeleteBuffers(1, &vboId);


// bind VBOs for vertex array and index array
glBindBuffer(GL_ARRAY_BUFFER, vboId1);            // for vertex attributes
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboId2);    // for indices

glEnableClientState(GL_VERTEX_ARRAY);             // activate vertex position array
glEnableClientState(GL_NORMAL_ARRAY);             // activate vertex normal array
glEnableClientState(GL_TEXTURE_COORD_ARRAY);      // activate texture coord array

// do same as vertex array except pointer
glVertexPointer(3, GL_FLOAT, stride, offset1);    // last param is offset, not ptr
glNormalPointer(GL_FLOAT, stride, offset2);
glTexCoordPointer(2, GL_FLOAT, stride, offset3);

// draw 6 faces using offset of index array
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, 0);

glDisableClientState(GL_VERTEX_ARRAY);            // deactivate vertex position array
glDisableClientState(GL_NORMAL_ARRAY);            // deactivate vertex normal array
glDisableClientState(GL_TEXTURE_COORD_ARRAY);     // deactivate vertex tex coord array

// bind with 0, so, switch back to normal pointer operation
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
OpenGL Vertex Buffer Object (VBO)
More work than necessary for basic ESP and menu

GLUT - GLEW - GLFW
These are all libraries that aid in making and drawing in OpenGL applications more easily. Most tutorials you see will use these frameworks. They are completely unnecessary and just an additional annoyance if you're just hooking and drawing 2d stuff on the screen. GLUT requires that the glut32.dll be placed in the same directory as the executable you're injecting into. But it's completely unnecessary, just don't use it. If you MUST use GLUT than at least statically link it Tutorial - How to Statically Link GLUT and best technique for GL text so they don't need glu32.dll in the same folder.

Drawing Text in OpenGL
The main reason to use GLUT is because of it's text rendering ability, but it's not needed. You can just use this text rendering class instead. Read the thread and understand you need to build the fonts in an OpenGL device context, which you can do in an OpenGL hook such as SwapBuffers.
Source Code - OpenGL Text Rendering Class

Drawing Rectangles, Lines Etc...
Release - OpenGL Drawing Class
Drawing In OpenGL
Source Code - [OpenGL] Draw a crosshair

OpenGL View Matrix & WorldToScreen Functions
Tutorial - So just what the fuck is a viewmatrix anyway and how does a W2S work????
Discuss - World2Screen function

Column Major vs Row Major Matrices
Matrices are defined as below, and the developer of the game gets to decide whether they want the 4 vec4s to be in rows or columns. Typically in OpenGL games, it is the opposite of Direct3D games, it's not a documented preference in OpenGL but for some reason it's common to see it like that. Note that the World2Screen function thread listed above, has functions for both.
C++:
float matrix[4][4];
OpenGL Chams / Model Loggers
If you want to make chams you need to use a model logger to get the stride and # of vertices etc...usually by hooking glDrawElements. glDrawElements is used to draw model textures. Model loggers hook this function and change the color based on number of vertices/stride and can log these values so you can tell your glDrawElements hook to change the color of the models drawn and disable the z buffer too so you can see them through walls.

Release - OpenGL ModelLogger (fast, simple, easy to use)
Release - OpenGL Model Logger v0.1 - source code

Best Resources:
OpenGL
3D Computer Graphics Using OpenGL - YouTube
Tutorials - Megabyte Softworks
OpenGL News Archives

Other good Resources:
Home
Learn OpenGL, extensive tutorial resource for learning Modern OpenGL
An intro to modern OpenGL. Chapter 1: The Graphics Pipeline
Calculating the gluPerspective matrix and other OpenGL matrix maths
Chapter 3 - OpenGL Programming Guide
Modern OpenGL - in2gpu
 
Last edited:

BDKPlayer

No hack no life
Dank Tier VIP
Dank Tier Donator
Oct 31, 2013
380
13,688
36
As Rake said the SetupOrtho() depends on the game. A more universal alternative is creating your own OpenGL context once and then use it whenever you want to render something and after you rendererd your stuff restore the original context. This method has worked for every game I've tested (including AssaultCube).

C++:
bool contextCreated = false;
HGLRC myContext;
HGLRC gameContext

//hooked SwapBuffers. This is x64 but it also works for x86
int64_t HkHwglSwapBuffers(HDC hdc)
{
    //Save the games context
    gameContext = wglGetCurrentContext();

    //Create our own context if it hasn't been created yet
    if (contextCreated == false)
    {
        //Create new context
        myContext = wglCreateContext(hdc);
     
        //Make thread use our context
        wglMakeCurrent(hdc, myContext);
     
        //Setup our context
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

       //Get resolution
       GLint m_viewport[4];
       glGetIntegerv( GL_VIEWPORT, m_viewport );

        glOrtho(0.0, m_viewport[2], m_viewport[3], 0.0, 1.0, -1.0);  //might want to make these your actual screen resolution
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glClearColor(0, 0, 0, 1.0);
    }
 
    //Make thread use our context
    wglMakeCurrent(hdc, myContext);
 
    //Draw something (a rectangle here)
    glColor3f(1.0f, 0, 0);
    glBegin(GL_QUADS);
    glVertex2f(0, 190.0f);
    glVertex2f(100.0f, 190.0f);
    glVertex2f(100.0f, 290.0f);
    glVertex2f(0, 290.0f);
    glEnd();

    //Make thread to use games context again
    wglMakeCurrent(hdc, oldContext);

    //return to orginal swapbuffers
    return oOpenGLReturn(hdc);
}
 
Last edited:
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods