OpenGL deprecated functions and gluPerspective and Transform - opengl

I am new to OpenGL and I am still experimenting with basic shapes. I sometimes find many functions like glEnd and many more, that are not mentioned in the OpenGL 3+ documentation. Were they replaced by other functions? Or do I have to write them manually?
Is there a tutorial online that uses OpenGL 3+?
As for " gluPerspective" I have read that it isn't used in Opengl 3+. Isn't it supposed to be a separate function in GLUT? what does it has to do with OpenGL 3+? Last, what does Transform( Width, Height ); do? (I found it in some sample code I downloaded, and I can't find it in GLUT or OpenGL).
here is the code:
GLvoid Transform(GLfloat Width, GLfloat Height)
{
glViewport(00, 00, Width, Height); /* Set the viewport */
glMatrixMode(GL_PROJECTION); /* Select the projection matrix */
glLoadIdentity(); /* Reset The Projection Matrix */
gluPerspective(20.0,Width/Height,0.1,100.0); /* Calculate The Aspect Ratio Of The Window */
glMatrixMode(GL_MODELVIEW); /* Switch back to the modelview matrix */
}
/* A general OpenGL initialization function. Sets all of the initial parameters. */
GLvoid InitGL(GLfloat Width, GLfloat Height)
{
glClearColor(0.0, 0.0, 0.0, 0.0); /* This Will Clear The Background Color To Black */
glLineWidth(2.0); /* Add line width, ditto */
Transform( Width, Height ); /* Perform the transformation */
}
/* The function called when our window is resized */
GLvoid ReSizeGLScene(GLint Width, GLint Height)
{
if (Height==0) Height=1; /* Sanity checks */
if (Width==0) Width=1;
Transform( Width, Height ); /* Perform the transformation */
}

I sometimes find many functions like glEnd and many more, that are not mentioned in the OpenGL 3+ documentation. Were they replaced by other functions?
They have been completely removed, since their workings doesn't reflect well with how modern graphics systems work on both the hardware and the software side. glBegin(…) and glEnd() form the surroundings of the so called immediate mode: Every call causes an operation. This reflects how early graphics systems were built, some 20 years ago.
Today one prepares batches of data, transfers them to GPU memory and triggers batch drawings with a single drawing call. OpenGL does this through vertex arrays and vertex buffer objects (VBOs). Vertex arrays have been around since OpenGL-1.1 (1996), and the VBO API is founded on vertex arrays, so for any reasonable program VBO support was added easily.
Or do I have to write them manually? Is there a tutorial online that uses OpenGL 3+?
It depends on the function in question. For example the whole texture environment, combiners have been removed. Just like the matrix manipulation functions and the whole lighting interface.
What they did and configured is now done through shaders and uniforms. Since you're expected to supply shaders one might say, you're expected to implement this yourself. OTOH you'll quickly find out, that often writing a shader is easier and more concise, than fiddling with large numbers of OpenGL parameter setting calls. Also once you've progressed far enough you'll hardly miss the matrix manipulation functions. Every serious application dealing with 3D graphics maintains the transformation matrices itself; be it for enhanced flexibilty or simply because those matrices are required in other places, too, e.g. some physics simulation.
As for " gluPerspective" I have read that it isn't used in Opengl 3+. Isn't it supposed to be a separate function in GLUT? what does it has to do with OpenGL 3+? Last, what does Transform( Width, Height ); do? (I found it in some sample code I downloaded, and I can't find it in GLUT or OpenGL).
gluPerspective is part of GLU. GLU is a companion library of OpenGL Utility functions, that used to ship with OpenGL-1.1. However it is not part of the OpenGL specification and completely optional.
GLUT is something else again. It's a simplicistic framework for quick and dirty setup of a OpenGL window and context, offering some minimalistic input API. Also it's no longer actively maintained. Personally I recommend not using it. If you must use a GLUT API, use FreeGLUT. Or better yet, don't GLUT at all, use a toolkit like Qt, GTK or a framework like GLFW or SDL.

Were they replaced by other functions?
No.
Or do I have to write them manually?
For old-style immediate-mode geometry submission you'll have to make your own work-alike. The matrix stack has a replacement.
Is there a tutorial online that uses OpenGL 3+?
At least one.

Related

dll injection: drawing simple game overlay with opengl

I'm trying to draw a custom opengl overlay (steam does that for example) in a 3d desktop game.
This overlay should basically be able to show the status of some variables which the user
can affect by pressing some keys. Think about it like a game trainer.
The goal is in the first place to draw a few primitives at a specific point on the screen. Later I want to have a little nice looking "gui" component in the game window.
The game uses the "SwapBuffers" method from the GDI32.dll.
Currently I'm able to inject a custom DLL file into the game and hook the "SwapBuffers" method.
My first idea was to insert the drawing of the overlay into that function. This could be done by switching the 3d drawing mode from the game into 2d, then draw the 2d overlay on the screen and switch it back again, like this:
//SwapBuffers_HOOK (HDC)
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glOrtho(0.0, 640, 480, 0.0, 1.0, -1.0);
//"OVERLAY"
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2f(0, 0);
glVertex2f(0.5f, 0);
glVertex2f(0.5f, 0.5f);
glVertex2f(0.0f, 0.5f);
glEnd();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
SwapBuffers_OLD(HDC);
However, this does not have any effect on the game at all.
Is my approach correct and reasonable (also considering my 3d to 2d switching code)?
I would like to know what the best way is to design and display a custom overlay in the hooked function. (should I use something like windows forms or should I assemble my component with opengl functions - lines, quads
...?)
Is the SwapBuffers method the best place to draw my overlay?
Any hint, source code or tutorial to something similiar is appreciated too.
The game by the way is counterstrike 1.6 and I don't intend to cheat online.
Thanks.
EDIT:
I could manage to draw a simple rectangle into the game's window by using a new opengl context as proposed by 'derHass'. Here is what I did:
//1. At the beginning of the hooked gdiSwapBuffers(HDC hdc) method save the old context
GLboolean gdiSwapBuffersHOOKED(HDC hdc) {
HGLRC oldContext = wglGetCurrentContext();
//2. If the new context has not been already created - create it
//(we need the "hdc" parameter for the current window, so the initialition
//process is happening in this method - anyone has a better solution?)
//Then set the new context to the current one.
if (!contextCreated) {
thisContext = wglCreateContext(hdc);
wglMakeCurrent(hdc, thisContext);
initContext();
}
else {
wglMakeCurrent(hdc, thisContext);
}
//Draw the quad in the new context and switch back to the old one.
drawContext();
wglMakeCurrent(hdc, oldContext);
return gdiSwapBuffersOLD(hdc);
}
GLvoid drawContext() {
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();
}
GLvoid initContext() {
contextCreated = true;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 640, 480, 0.0, 1.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0, 0, 0, 1.0);
}
Here is the result:
cs overlay example
It is still very simple but I will try to add some more details, text etc. to it.
Thanks.
If the game is using OpenGL, then hooking into SwapBuffers is the way to go, in principle. In theory, there might be sevaral different drawables, and you might have to decide in your swap buffer function which one(s) are the right ones to modify.
There are a couple of issues with such kind of OpenGL interceptions, though:
OpenGL is a state machine. The application might have modified any GL state variable there is. The code you provided is far from complete to guarantee that something is draw. For example, if the application happens to have shaders enabled, all your matrix setup might be without effect, and what really would appear on the screen depends on the shaders.
If depth testing is on, your fragments might lie behind what already was drawn. If polygon culling is on, your primitive might be incorrectly winded for the currect culling mode. If the color masks are set to GL_FALSE or the draw buffer is not set to where you expect it, nothing will appear.
Also note that your attempt to "reset" the matrices is also wrong. You seem to assume that the current matrix mode is GL_MODELVIEW. But this doesn't have to be the case. It could as well be GL_PROJECTION or GL_TEXTURE. You also apply glOrtho to the current projection matrix without loading identity first, so this alone is a good reason for nothing to appear on the screen.
As OpenGL is a state machine, you also must restore all the state you touched. You already try this with the matrix stack push/pop. But you for example failed to restore the exact matrix mode. As you have seen in 1, a lot more state changes will be required, so restoring it will be more comples. Since you use legacy OpenGL, glPushAttrib() might come handy here.
SwapBuffers is not a GL function, but one of the operating system's API. It gets a drawable as parameter, and does only indirectly refer to any GL context. It might be called while another GL context is bound to the thread, or with none at all. If you want to play it safe, you'll also have to intercept the GL context creation function as well as MakeCurrent. In the worst (though very unlikely) case, the application has the GL context bound to another thread while it is calling the SwapBuffers, so there is no change for you in the hooked function to get to the context.
Putting this all together opens up another alternative: You can create your own GL context, bind it temporarily during the hooked SwapBuffers call and restore the original binding again. That way, you don't interfere with the GL state of the application at all. You still can augment the image content the application has rendered, since the framebuffer is part of the drawable, not the GL context. Doing so might have a negative impact on performance, but it might be so small that you never would even notice it.
Since you want to do this only for a single specific application, another approach would be to find out the minimal state changes which are necessary by observing what GL state the application actually set during the SwapBuffers call. A tool like apitrace can help you with that.

Porting C++ OpenGL from windows to mac. What to do with GLKMatrix4MakePerspective?

I am trying to port a c++ program that uses SFML and OpenGL I wrote from Windows to Mac OS X. I am using g++ to compile on both platforms.
Here is my current code for calculating the projection matrix:
void perspectiveCalculate (int width, int height) {
// Prevent A Divide By Zero
if (height<1) height=1;
if (width<1) width=1;
glViewport(0, 0, width, height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
//field of vision , width , height , near clipping , far clipping
//and calculate The Aspect Ratio Of The Window
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 1000.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
However, g++ is saying that gluPerspective is deprecated, and I should be using GLKMatrix4MakePerspective instead. I found the manual page on the function but I'm not sure how to integrate it with the rest of my code. What should I do?
All your matrix code there is deprecated in modern OpenGL. You can keep using it on the Mac (warnings and all) if you have a GL 2.x context, but if you want to use GL 3.2 or newer you only get a Core Profile context, and for that you need to move to modern OpenGL code. (Ditto if you want to use OpenGL ES 2.0 or newer on mobile platforms.)
In modern OpenGL, the matrix setup functions you're using are all gone. The fixed-function pipeline they go with is replaced by a programmable pipeline... instead of telling OpenGL what model, view, and projection matrices you want and having it do the transformations for you, you do the transformations yourself in a GLSL vertex shader. The good news is that you can now leverage programmable shaders to do all kinds of effects not possible with the fixed-function pipeline. The bad news is you have to do the basic stuff yourself.
Part of doing that basic stuff is finding (or writing) a math library to generate all the matrices you'll be handing off to the vertex shader for doing your transformations. GLKMatrix4 is part of Apple's library for such things. GLKMatrix4MakePerspective takes almost the same set of arguments as gluPerspective (vertical FOV in radians, aspect ratio, near clipping distance, far clipping distance), but instead of setting fixed-function matrix state it returns a GLKMatrix4 data structure.
You then pass this data structure to a vertex shader via a uniform variable. Or, if you're working with GLKit anyway, you can look into [GLKBaseEffect][2], which provides an Objective-C interface roughly analogous to the old fixed-function pipeline.
Dealing with the entire process of moving to modern OpenGL is beyond the scope of one SO answer. Here's a few resources:
http://www.opengl-tutorial.org — Good overall tutorial. They use GLM for matrix math, but you can use GLKit math just as well
Migrating to OpenGL Core Profile — Apple Developer video
"OpenGL Game" Xcode template — this is for OpenGL ES on iOS, but you can run it in the simulator, and it provides a nice simple example of how to use GLKit to generate matrices and either hand them off to shaders or pass them to GLKBaseEffect. The GL part of this is pretty much the same on both iOS and OS X.

OpenGL what do I have to do before drawing a triangle?

Most of the tutorials, guides and books that I've found out there are related to OpenGL, explains how to draw a triangle and initialize OpenGL. That's fine. But when they try to explain it they just list a bunch of functions and parameters like:
glClear()
glClearColor()
glBegin()
glEnd()
...
Since I'm not very good at learning things by memory, I always need an answer to "why are we doing this?" so that I'll write that bunch of functions because I remember that I have to set a certain things before doing somethings else and so on not because the tutorial told me so.
Could please someone explain to me what do I have to define to OpenGL (only pure OpenGL, I'm using SFML as background library but that really doesn't matter) before starting to draw something with glBegin() and glEnd()?
Sample answer:
You have to first tell OpenGL what color does it need to clear the
screen with. Because each frame needs to be cleared by the previous
before we start to draw the current one...
First you should know, that OpenGL is a state machine. That means, that apart from creating the OpenGL context (which is done by SFML) there's no such thing as initialization!
Since I'm not very good at learning things by memory,
This is good…
I always need an answer to "why are we doing this?"
This is excellent!
Could please someone explain to me what do I have to define to OpenGL (only pure OpenGL, I'm using SFML as background library but that really doesn't matter) before starting to draw something with glBegin() and glEnd()?
As I already told: OpenGL is a state machine. That basically means, that there are two kinds of calls you can do: Setting state and executing operations.
For example glClearColor sets a state variable, that of the clear color, which value is used for clearing the active framebuffer color to, when a call to glClear with the GL_COLOR_BUFFER_BIT flag set. There exists a similar function glClearDepth for the depth value (GL_DEPTH_BUFFER_BIT flag to glClear).
glBegin and glEnd belong to the immediate mode of OpenGL, which have been deprecated. So there's little reason in learning them. You should use Vertex Arrays instead, preferrably through Vertex Buffer Objects.
But here it goes: glBegin sets OpenGL in a state that it should now draw geometry, of the kind of primitive selected as parameter to glBegin. GL_TRIANGLES for example means, that OpenGL will now interpret every 3 calls to glVertex as forming a triangle. glEnd tells OpenGL that you've finished that batch of triangles. Within a glBegin…glEnd block certain state changes are disallowed. Among those everything that has to do with transforming the geometry and generating the picture, which matrices, shaders, textures, and some others.
One common misconception is, that OpenGL is initialized. This is due to badly written tutorials which have a initGL function or similar. It's a good practice to set all state from scratch when beginning to render a scene. But since a single frame may contain several scenes (think of a HUD or split screen gaming) this happens several times a scene.
Update:
So how do you draw a triangle? Well, it's simple enough. First you need the geometry data. For example this:
GLfloat triangle[] = {
-1, 0, 0,
+1, 0, 0,
0, 1, 0
};
In the render function we tell OpenGL that the next calls to glDrawArrays or glDrawElements shall fetch the data from there (for the sake of simplicity I'll use OpenGL-2 functions here):
glVertexPointer(3, /* there are three scalars per vertex element */
GL_FLOAT, /* element scalars are float */
0, /* elements are tightly packed (could as well be sizeof(GLfloat)*3 */
trignale /* and there you find the data */ );
/* Note that glVertexPointer does not make a copy of the data!
If using a VBO the data is copied when calling glBufferData. */
/* this switches OpenGL into a state that it will
actually access data at the place we pointed it
to with glVertexPointer */
glEnableClientState(GL_VERTEX_ARRAY);
/* glDrawArrays takes data from the supplied arrays and draws them
as if they were submitted sequentially in a for loop to immediate
mode functions. Has some valid applications. Better use index
based drawing for models with a lot of shared vertices. */
glDrawArrays(Gl_TRIANGLE, /* draw triangles */
0, /* start at index 0 */
3, /* process 3 elements (of 3 scalars each) */ );
What I didn't include yet is setting up the transformation and viewport mapping.
The viewport defines how the readily projected and normalized geometry is placed in the window. This state is set using glViewport(pos_left, pos_bottom, width, height).
Transformation today happens in a vertex shader, Essentially a vertex shader is a small program written in a special language (GLSL), that takes the vertex attributes and calculates the clip space position of the resulting vertex. The usual approach for this is emulating the fixed function pipeline, which is a two stage process: First transform the geometry into view space (some calculations, like illumination are easier in this space), then project it into clip space, which is kind of the lens of the renderer. In the fixed function pipeline there are two transformation matrices for this: Modelview and Projection. You set them to whatever is required for the desired outcome. In the case of just a triangle, we leave the modelview identity and use a ortho projection from -1 to 1 in either dimension.
glMatrixMode(GL_PROJECTION);
/* the following function multiplies onto what's already on the stack,
so reset it to identity */
glLoadIdentity();
/* our clip volume is defined by 6 orthogonal planes with normals X,Y,Z
and ditance 1 from origin into each direction */
glOrtho(-1, 1, -1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
/* now a identity matrix is loaded onto the modelview */
glLoadIdentity();
Having set up the transformation we can now draw the triangle as outlined above:
draw_triangle();
Finally we need to tell OpenGL we're done with sending commands and it should finish it's renderings.
if(singlebuffered)
glFinish();
However most of the time your window is double buffered, so you need to swap it to make things visime. Since swapping makes no sense without finishing the swap implies a finish
else
SwapBuffers();
You're using the API to set and change the OpenGL state machine.
You're not actually programming directly to the GPU, you're using a medium between your application and your GPU to do whatever you're trying to do.
The reason it is like this and doesn't work the same way as a CPU and memory, is because openGL was intended to run on os/system-independent hardware, so that your code can run on any OS and run on any hardware and not just the one your programming to.
Hence, because of this, you need to learn to use their preset code that makes sure that whatever you're trying to do it will be able to be run on all systems/OS/hardware within a reasonable range.
For example if you were to create your application on windows 8.1 with a certain graphics card(say amd's) you still want your application to be able to run on Andoird/iOS/Linux/other Windows systems/other hardware(gpus) such as Nvidia.
Hence why Khronos, when they created the API, they made it as system/hardware independent as possible so that it can run on everything and be a standard for everyone.
This is the price we have to pay for it, we have to learn their API instead of learning how to directly write to gpu memory and directly utilize the GPU to process information/data.
Although with the introduction of Vulkan things might be different when it is released(also from khronos)and we will find out how it will be working.

How to use OpenGL and GLSL to change color (C++)?

I am working on an OpenGL project in C++, and I want to learn how to use GLSL shaders. The problem is that, while I can complete my program without using my own shaders, I want to write my own (at this time there are no shaders that I load myself - not sure if OpenGL defaults any).
To draw a bunch of lines on the image (whose vertices are stored in a vector and color values are stored in another vector), I use the following code to run through and render them whenever the frame is updated - I use the GLUT display function for this.
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
vector<point2>::iterator it;
int c_index = 0;
for(it=points.begin(); it<points.end(); it++){
if(c_index % 2 == 0) //set color for every pair of points (each line)
glColor3f(colors[c_index/2][0], colors[c_index/2][1], colors[c_index/2][2]);
c_index++;
glVertex2f(it->x, it->y); //set vertex
}
glEnd();
glFlush();
Now, the problem is when I try to use shaders that I found in another example program, the color is all red (even though the shaders do not explicitly define any colors). It also makes glColor3f do nothing.
My question is, assuming I can use shaders to do this, what do the shaders have to look like, and how would I load them?
Apparently it cannot be done using glColor3f. Instead, I had to make a pre-determined OpenGL buffer, and send the buffer data to the shaders. It can't be done "on the fly" as I hoped.

2D Particle System - Performance

I have implemented a 2D Particle System based on the ideas and concepts outlined in "Bulding an Advanced Particle System" (John van der Burg, Game Developer Magazine, March 2000).
Now I am wondering what performance I should expect from this system. I am currently testing it within the context of my simple (unfinished) SDL/OpenGL platformer, where all particles are updated every frame. Drawing is done as follows
// Bind Texture
glBindTexture(GL_TEXTURE_2D, *texture);
// for all particles
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2f(x,y);
glTexCoord2d(1,0); glVertex2f(x+w,y);
glTexCoord2d(1,1); glVertex2f(x+w,y+h);
glTexCoord2d(0,1); glVertex2f(x,y+h);
glEnd();
where one texture is used for all particles.
It runs smoothly up to about 3000 particles. To be honest I was expecting a lot more, particularly since this is meant to be used with more than one system on screen. What number of particles should I expect to be displayed smoothly?
PS: I am relatively new to C++ and OpenGL likewise, so it might well be that I messed up somewhere!?
EDIT Using POINT_SPRITE
glEnable(GL_POINT_SPRITE);
glBindTexture(GL_TEXTURE_2D, *texture);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
// for all particles
glBegin(GL_POINTS);
glPointSize(size);
glVertex2f(x,y);
glEnd();
glDisable( GL_POINT_SPRITE );
Can't see any performance difference to using GL_QUADS at all!?
EDIT Using VERTEX_ARRAY
// Setup
glEnable (GL_POINT_SPRITE);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
glPointSize(20);
// A big array to hold all the points
const int NumPoints = 2000;
Vector2 ArrayOfPoints[NumPoints];
for (int i = 0; i < NumPoints; i++) {
ArrayOfPoints[i].x = 350 + rand()%201;
ArrayOfPoints[i].y = 350 + rand()%201;
}
// Rendering
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex arrays
glVertexPointer(2, GL_FLOAT, 0, ArrayOfPoints); // Specify data
glDrawArrays(GL_POINTS, 0, NumPoints); // ddraw with points, starting from the 0'th point in my array and draw exactly NumPoints
Using VAs made a performance difference to the above. I've then tried VBOs, but don't really see a performance difference there?
I can't say how much you can expect from that solution, but there are some ways to improve it.
Firstly, by using glBegin() and glEnd() you are using immediate mode, which is, as far as I know, the slowest way of doing things. Furthermore, it isn't even present in the current OpenGL standard anymore.
For OpenGL 2.1
Point Sprites:
You might want to use point sprites. I implemented a particle system using them and came up with a nice performance (for my knowledge back then, at least). Using point sprites you are doing less OpenGL calls per frame and you send less data to the graphic card (or even have the data stored at the graphic card, not sure about that). A short google search should even give you some implementations of that to look at.
Vertex Arrays:
If using point sprites doesn't help, you should consider using vertex arrays in combination with point sprites (to save a bit of memory). Basically, you have to store the vertex data of the particles in an array. You then enable vertex array support by calling glEnableClientState() with GL_VERTEX_ARRAY as parameter. After that, you call glVertexPointer() (the parameters are explained in the OpenGL documentation) and call glDrawArrays() to draw the particles. This will reduce your OpenGL calls to only a handfull instead of 3000 calls per frame.
For OpenGL 3.3 and above
Instancing:
If you are programming against OpenGL 3.3 or above, you can even consider using instancing to draw your particles, which should speed that up even further. Again, a short google search will let you look at some code about that.
In General:
Using SSE:
In addition, some time might be lost while updating your vertex positions. So, if you want to speed that up, you can take a look at using SSE for updating them. If done correctly, you will gain a lot of performance (at a large amount of particles at least)
Data Layout:
Finally, I recently found a link (divergentcoder.com/programming/aos-soa-explorations-part-1, thanks Ben) about structures of arrays (SoA) and arrays of structures (AoS). They were compared on how they affect the performance with an example of a particle system.
Consider using vertex arrays instead of immediate mode (glBegin/End): http://www.songho.ca/opengl/gl_vertexarray.html
If you are willing to get into shaders, you could also search for "vertex shader" and consider using that approach for your project.