CLASSIC TRIANGLE WITH OPENGL…

To begin any C++ (or even just C) program, we need to include the headers that contain the function and class definitions that we will use in our program. For our purposes, the bare minimum will be the following headers.
The GLTools.h header contains the bulk of the GLTools C-like stand-alone functions, while the GLTools C++ classes each have their own header file.
GLShaderManager.h brings in the GLTools shader manager class. You cannot render in OpenGL (core profile) without a shader.
The shader manager not only allows you to build and manage your own shaders, it comes with a set of “stock shaders” that perform a few rudimentary and basic rendering operations.

#include <GLTools.h>	// OpenGL toolkit
#include <GLShaderManager.h>

GLUT gets a different treatment depending on whether you are building on a Mac. On Windows and Linux, we use the static library version of freeglut and thus need the FREEGLUT_STATIC preprocessor macro defined ahead of it.

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

A simple GLTool wrapper class encapsulates our batch of triangles, and we declared an instance of this GLBatch class

GLBatch	triangleBatch;

Nothing can be rendered in the OpenGL core profile without a shader.As mentioned above.

GLShaderManager	shaderManager;
void ChangeSize(int w, int h);
void SetupRC();
void RenderScene(void);

Window has changed size, or has just been created. In either case, we need to use the window dimensions to set the viewport and the projection matrix.
The ChangeSize function receives the new width and height whenever the window size changes. We can use this information to modify the mapping of our desired coordinate system to real screen coordinates, with the help of the OpenGL function glViewport.

void ChangeSize(int w, int h)

The 1st and 2nd parameters specify the lower-left corner of the viewport within the window, and the width and height parameters specify these dimensions in pixels. Usually, x and y are both 0, but you can use viewports to render more than one drawing in different areas of a window. The viewport defines the area within the window in actual screen coordinates that OpenGL can use to draw in. The current clipping volume/coordinate system is then mapped to the new viewport. If you specify a viewport that is smaller than the window coordinates, the rendering is scaled smaller.

	glViewport(0, 0, w, h);

This function does any needed initialization on the rendering context.This is the first opportunity to do any OpenGL related tasks.This is where we do some one-time setup for our program.

void SetupRC()

This function sets the color used for clearing the window.The prototype for this function is

void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);

GLclampf is defined as a float under most implementations of OpenGL. Each parameter contains the weight of that color component in the final color desired. This function does not clear the background right away, but rather sets the color that will be used when the color buffer is cleared (possibly repeatedly) later.

	// Blue background
	glClearColor(0.0f, 0.0f, 1.0f, 1.0f );

The shader manager needs to compile and link its own shaders, though, so we must call the InitializeStockShaders method as part of our OpenGL initialization.

shaderManager.InitializeStockShaders();

This array, named vVerts, contains the x, y, and z pair of all three vertices in Cartesian coordinates. Note how we made the z coordinate zero for all three points.

	// Load up a triangle
	GLfloat vVerts[] = { -0.5f, 0.0f, 0.0f, 
		                0.5f, 0.0f, 0.0f,
				    0.0f, 0.5f, 0.0f };
    triangleBatch.Begin(GL_TRIANGLES, 3);
	triangleBatch.CopyVertexData3f(vVerts);
	triangleBatch.End();
}

GLUT by default updates the window by calling the RenderScene function when the window is created and when the window either changes size or is in need of being repainted. This happens anytime the window is minimized and restored, maximized,covered and redisplayed, and so on.

// Called to draw scene
void RenderScene(void)
	{

The glClear function clears a particular buffer or combination of buffers. A buffer is a storage area for image information. The red, green, blue, and alpha components of a drawing are usually collectively referred to as the color buffer or pixel buffer.
More than one kind of buffer (color, depth, and stencil) is available in OpenGL, we use the bitwise OR operator to simultaneously clear all three of these buffers.All you really need to understand is that the color buffer is the place where the displayed image is stored internally and that clearing the buffer with glClear removes the last drawing from the window. You will also see the term framebuffer, which refers to all these buffers collectively given that they work in tandem.

	// Clear the window with current clearing color
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

We set up an array of floating-point numbers to represent the color red (with an alpha of 1.0), and pass this to a stock shader.

GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f };
    	shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
	triangleBatch.Draw();

The GLBatch method Draw simply submits the geometry to the shader and ta-da!—red triangle…well, almost. There is one last detail. When we set up our OpenGL window, we specified that we wanted a double buffered rendering context. This means rendering occurs on a back buffer and then is swapped to the front when we are done. This prevents the viewer from seeing the scene being rendered, along with a likely flickering between animation frames. Buffer swaps are done in a platform-specific manner, but GLUT has a single function call that does this for you:

	// Perform the buffer swap to display back buffer
	glutSwapBuffers();

Calling glutPostRedisplay yourself is a way in which you can let GLUT know that something has changed and it’s time to rerender the scene.

      glutPostRedisplay();// Redraw
	}

Console-mode C and C++ programs always start execution with the function main. If you’re an experienced Windows nerd, you might wonder where WinMain is in this example. It’s not there because we start with a console-mode application, so we don’t have to start with window creation and a message loop. With Win32, you can create graphical windows from console applications, just as you can create console windows from GUI applications. These details are buried within the GLUT library. (Remember, the GLUT library is designed to hide just these kinds of platform details.)

int main(int argc, char* argv[])
	{

The GLTools function gltSetWorkingDirectory sets the current working directory. This is actually not necessary on Windows, as the working directory is by default the same direc- tory as the program executable. On Mac OS X, however, this function changes the current working folder to be the /Resources folder inside the application bundle. A GLUT prefer- ences setting does this automatically, but this method is safer and always works, even if that setting is changed by another program. This comes in handy later when we want to load texture files or model data.

gltSetWorkingDirectory(argv[0]);

Next, we do some standard GLUT-based setup. The first order of business is a call to glutInit, which simply passes along the command-line parameters and initializes the GLUT library.

glutInit(&argc, argv);

Next, we must tell the GLUT library what type of display mode to use when creating the window:
The flags here tell it to use a double-buffered window (GLUT_DOUBLE) and to use RGBA color mode (GLUT_RGBA). A double-buffered window means the drawing commands are actually executed on an off-screen buffer and then quickly swapped into view on the window later. This method is often used to produce animation effects. The GLUT_DEPTH bit flag allocates a depth buffer as part of our display so we can perform depth testing, and likewise GLUT_STENCIL makes sure we also have a stencil buffer available.

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);

Next, we tell GLUT how big to make the window and to go ahead and create the window, with a caption that reads, “Triangle”:

	glutInitWindowSize(800, 600);
	glutCreateWindow("Triangle");

Internally GLUT runs a system native message loop, intercepts the appropriate messages, and then calls callback functions you register for different events. This is somewhat limited compared to using a real system-specific framework, but it greatly simplifies getting a program up and running, and the minimal events are supported for a demo framework. Here, we must set a callback function for when the window changes size so that we can set up the viewport, and we register a function that will contain our OpenGL rendering code.

    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);

GLUT supports another callback function, called glutSpecialFunc. This function registers a function that is called whenever a special key is pressed. In GLUT parlance, this is one of the function keys or one of the directional keys (arrow keys, page up/down, and so on). The following line is added to our main function to register the SpecialKeys callback function for this purpose.

glutSpecialFunc(SpecialKeys);

Before we start the main message loop running, there are still two things we need to take care of. The first is to initialize the GLEW library. Recall the GLEW library initializes all the missing entry points in our OpenGL driver to make sure we have the full OpenGL API available to us. A call to glewInit does the trick, and we check to make sure nothing goes wrong with the driver initialization before we try and do any rendering.

GLenum err = glewInit();
	if (GLEW_OK != err) {
		fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
		return 1;
		}

The final piece of preparation is the call SetupRC. This function has nothing to do with GLUT actually but is a convenient place to do any OpenGL initialization we need performed before the actual rendering begins. The RC stands for rendering context, which is the logical handle to a running OpenGL state machine. A rendering context must be created before any OpenGL function will work, and GLUT sets this up for us when we first create the window.

SetupRC();

Finally, it’s time to start the main program loop and end the main function. The glutMainLoop function never returns after it is called until the main window is closed and needs to be called only once from an application. This function processes all the oper- ating system-specific messages, keystrokes, and so on until you terminate the program. It also makes sure those callback functions we registered earlier are called appropriately.

    glutMainLoop();
	return 0;
	}

Reklamlar

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Connecting to %s