OpenGL Learning Path (i)

Source: Internet
Author: User

1 intro

Although it is a computer trained, but from a small geometric aspects of the thing is not too cold, space imagination is also poor, so from undergraduate to graduate students, basically did not contact the computer graphics. Why did you say you didn't learn it? Because of curiosity (especially marvel at three-dimensional game realism, such as World of Warcraft, Need for Speed), in the graduate stage is also specialized in computer graphics, but also just listened to a few lessons, know that there is frame cache, homogeneous coordinates, such as the concept of fragmented, then read a paper and take the stage to report (not read). In short, just think computer graphics or three-dimensional rendering is very cow, even asked me what is rendering do not know, but also do not know how to display 3-dimensional geometry on the 2-dimensional screen. So I now want to think very ridiculous is that the 2D image is the plane, 3D image is three-dimensional.

Real exposure to 3-D drawing is done after work, because it is the development of software for image processing and visualization, so it is beginning to know that these 3D images are made by programming interfaces such as Opengl/direct3d. But the code for the company's invocation and drawing of the OpenGL interface is written by another group, and bloggers can't see their code at all. However, some knowledge was learned in the discussions with the relevant colleagues. So the blogger would consider learning OpenGL programming systematically.

The two best OpenGL books on the market should be-the OpenGL Programming Guide (Red Book) and the OpenGL programming book (Lan Baoshu). So, I chose the "OpenGL Programming Guide (Eighth edition)" As my introductory textbook, thus embarked on the learning path. This blog wants to record some new experiences in the learning process. The knowledge that is written down is his own. Gossip doesn't say much, let's embark on the OpenGL learning journey!

2 First example

Red Book at the beginning in what is the OpenGL section, briefly introduces the concept of OpenGL, the development process, the rendering process and other concepts. To tell the truth, the first reading of this text is to read, the concept of a variety of not understand. But it doesn't matter, bloggers think, most of the technical books in the first chapter is the case-a lot of concepts, and then write a simple small program, analysis of it, continue to enumerate more concepts, and then explain in the first few chapters of the section detailed introduction. So for me this beginner, read the first chapter completely do not know what to say is also very normal, do not hurry, slowly, a moment you understand-the so-called follow.

After that, Bam throws an example, this may be the programmer's style--first write a demo to see. In fact, just beginning to contempt for this example, too simple-and my mind on the big game interface is far from. However, in fact, this example contains a lot of things. First take a look at the effect of this program running.

is to draw two blue triangles in a window. Let's follow the steps to draw the graph.

First step: Build a Frame

For technical books, the first reading is to follow the book to hit the code, after the code to see the code there is no problem. This example is simple, but a lot of code. In fact, we can write a step-by-step, first write a main function, in which to fill out some initialization and create the window code, as follows:

1 #include <iostream> 2 #include "StdAfx.h" 3  4 void display () 5 {6} 7  8 int main (int argc, char **argv) 9 {     Glutinit (&ARGC, argv);     Glutinitdisplaymode (Glut_rgba);     glutinitwindowsize (512, 512); 13     glutinitcontextversion (3, 3);     glutinitcontextprofile (glut_core_profile);     Glutcreatewindow (argv [0]);     if (Glewinit ()) +           std::cerr << "Unable to initialize Glew ... Exiting "<< std::endl;20         std::exit (exit_failure);     }22     (display); 24     Glutmainloop (); 25}

In fact, it's just an API that involves OpenGL, and it just uses a third-party library. Some functions create a window to display the image. Just like when we started writing the console demo, we wrote the main function and then printed a "HelloWorld" to see if we could run. This short line of code above is capable of running. The result of the operation is a blank window of size 512x512. The code is simple, which is to initialize the related function. Here is a description:#include "StdAfx.h" is downloaded from the Red Book Web site vgl.h files, and configured the properties of the project (such as header file directory, Lib library directory) The other is this: the display function is the function that we want to invoke OpenGL to draw the image. The following is the fill function.

Step Two: fill the frame

As with any program, the OpenGL program requires input and then passes through the rendering pipeline, a series of shaders (the shader runs through the book), and finally a two-dimensional image (the pixel matrix), see.

So before invoking the OpenGL API to draw the image, load the required data into the video memory so that OpenGL can handle it when it is drawn. The following code is populated:

1 #include <iostream> 2 #include "StdAfx.h" 34 Gluint buffer_id; 5 const int buffer_number = 1; 6 7 gluint vao_id; 8 Gluint vao_number = 1; 9 const int Vertic Es_number = 6;11 const int vposition = 0;12 13void Initialize ()---------------------Prepare data-------------------------------glfloat vertices[vertices _NUMBER][2] = 17 {18 {-0.90,-0.90},19 {0.85,-0.90},20 {-0.90, 0.85},21 22 { 0.90,-0.85},23 {0.90, 0.90},24 {-0.85, 0.90}25};26 27//Generate Cache object Glgenbuffers (BUFF Er_number, &buffer_id); 29 30//Bind cache object to Glbindbuffer (Gl_array_buffer, buffer_id); 32 33//fill in Data Glbu Fferdata (Gl_array_buffer, sizeof (vertices), vertices, gl_static_draw);//------------------- Set vertex data Properties------------------------------37//Generate vertex Array object Glgenvertexarrays (Vao_number, &vao_id); 39 40//Bundle TOP Points Group Object Glbindvertexarray (vao_id); 42 43//Set vertex properties Glvertexattribpointer (vposition, 2, Gl_float, Gl_false, 0, Buffer_offset (0)); Glenablevertexattribarray (vposition);$ void Display () 49 {glclear (gl_color_buffer_bit); Glbindvertexarray (vao_id); Gldrawarrays (gl_triangles, 0, Vertices_ number); Glflush ();}57 (int argc, char **argv) (+ glutinit (&AMP;ARGC, argv); Glutinitdisplaymode (Glut_rgba); 62     Glutinitwindowsize (Glutinitcontextversion) (3, 3); Glutinitcontextprofile (Glut_core_profile); 65 Glutcreatewindow (Argv[0]); glewexperimental = true;68 if (Glewinit ()). {Std::cerr << "Unable to initialize Glew ... Exiting "<< std::endl;71 std::exit (exit_failure);}73 () Initialize (); Glutdisplayfunc (di splay); Glutmainloop (); 77}

On top of that, add the code that loads the data section and draws the graphics section. The main points are two steps:

1. Data entry Steps

Any system has an input/output (I/O) system, such as an input device and an output device in a computer hardware system; Each programming language has its own input command (class) and Output command (class), and for an algorithm, it also has its inputs and outputs.

For our graphic drawing system, the input and output are naturally unavoidable. Since the input of the data only needs to be executed once, it is written in the Initialize function and is executed in the main function.

In this example, to draw two triangles, the input data is naturally the vertex data of the two triangles. Because the planar triangles are drawn, we can not specify the coordinate values (depth values) in the z-direction. The two-dimensional vertex arrays of the 16~25 rows are stored in memory, and the graphics are executed in the graphics card, so the data needs to be loaded into the video memory. Here comes the first important concept in OpenGL programming-the cache object (in buffer). As the name implies, this object is primarily used to store data, where we use caching to store vertex data. Let's take a look at how the cache object is used to load vertex data in the program.

Loading vertex data into memory uses 3 OpenGL APIs to load the data.

I: Use Glgenbuffer to declare a cached object ID. in a programming language, the data in memory is identified by a variable, and the operating system identifies the thread by identifying the process with various IDs, such as the process identifier PID to identify the processes, and the thread identifier TID. OpenGL also identifies various objects by ID. Since only one cache object is used here, it is only possible to generate a cache ID, but note that this instruction can generate multiple cache objects .

II: Use Glbindbuffer to bind one of the caches. as already mentioned, there can be more than one cache object, so how does OpenGL know which cache object to operate on now? This requires the use of the Glbindbuffer command-the function of this command is to activate (Activate) One of the cached objects. The parameter is simple, which is the cache ID that was generated just now.

III: Use Glbufferdata to allocate memory and copy data to video memory. This step is our ultimate goal-to copy data from memory to video. This function is similar to the memory copy memcpy in the C language, and the function signature is:

void Glbufferdata (Glenum target, glsizeiptr size, const glvoid *data, glenum usage);

target--the cached object that was just bound (activated), which can be regarded as the destination address of memcpy;

size--This is the size of the data, which is the same as the size of the data in memcpy;

data--pointer to the source data, which is the same as the source data pointer in the memcpy;

usage--This parameter specifies the use of this data, mainly to optimize the memory management of OpenGL-based on the use of methods to determine the optimal memory allocation scheme.

By using the three OpenGL APIs above, we have completed the ability to load data from memory to the cache. So far, the story is not over, OpenGL does not know how the data in the cached object is parsed when it gets the vertex data, so you need to tell OpenGL what the format of the data you just uploaded is. This introduces the concept of the second object-the vertex array object and the vertex attribute. The vertex array object is an object that describes the vertex data features you just uploaded, and continues to parse the associated API with the vertex array object.

I: Use Glgenvertexarray to declare a top-point group object ID. this is the same as the cache object ID, which is designed to facilitate the organization and management of OpenGL;

II: Use Glbindvertexarray to activate one of the top-point group Objects , and the cache object is similar;

III: Use the Glvertexattribpointer interface to populate the currently bound vertex array object. the function is the same as the Glbindbuffer command of the cached object, but only for the cached object, as long as the data is copied, and the vertex attribute data needs to be populated (just like filling a struct). This function has many parameters, and its function signature is:

void Glvertexattribpointer (Gluint index, glsize size, glint size, glenum type, Glboolean normalized, Glsizei stribe, const Glvoid *pointer);

index--This is the attribute specified at the vertex in the shader.

size--This parameter specifies a number of components for each vertex, in this case the two-dimensional vertex is set to 2;

type--This parameter specifies the data type of the component in the vertex, where the coordinate component of the vertex is floating point data, so it is set to gl_float;

normalized--This parameter indicates whether a normalization is required before the vertex is stored;

stride--This parameter specifies the number of bytes for the interval between two vertex data, in this case, the vertex is continuously stored and is set to 0;

The pointer--vertex data is the starting address in the cached object, in this case the value is set to 0 because the cache object contains only a single vertex array.

IV: Use Glenablevertexattribarray to enable the vertex array associated with the index index. Although the vertex array property is set previously, the data cannot be obtained by OpenGL if it is not enabled.

2. Drawing steps

After the data and its formatting, the graph is drawn based on this data. This part of the code is written in the display function, and this function may be called multiple times. In this display function, one of the most important OpenGL APIs is the Gldrawarray function, which draws the basic graph with the following function signature:

void Gldrawarray (Glenum mode, glint first, glsizei count);

mode--specifies the type of entity you want to draw, such as the triangle is gl_triangles, the line is Gl_lines, the closed line is Gl_line_loop, and the vertex is gl_points. In this example, the triangle is drawn, so it is set to Gl_triangles.

first--Specifies the starting vertex when drawing the drawing, in this case starting from the No. 0 vertex;

count--the number of vertices to draw, in this case set to 6.

Setting different values for this function will result in different effects--you can use different vertices to draw different shapes.

The remaining, three interfaces:

Glclear (Glbitfield mask);

Empties the specified cache data. Each new drawing, of course, will need to erase some of the data from the last drawing process to prevent it from having an impact on the next draw. There are three kinds of cache data in OpenGL, namely, color cache, depth cache and template cache. Where deep caches are used only in three-dimensional scenarios. In this example, the color cache is emptied.

Glflush ();

This interface is a synchronous interface--wait for the drawing to finish and then execute it down. What needs to be explained here is that OpenGL uses client-server mode-Our application is the client and the video card is the server. Each time the OpenGL API executes is equivalent to sending a command to the graphics card, these commands are normally executed asynchronously. This function needs to be called if our application needs to wait for the graphics card command to complete before executing.

The last one, the glbindvertexarray--binding operand, which Gldrawarray draws is the currently bound vertex array. In this case (only in this case) it is not possible to call because it has been called in the Initialize function, and there is no other binding in the display function.

At this point, we run the program and should be able to see two white triangles drawn.

Step Three: Add shaders

Let's take a look at the drawing pipeline in OpenGL, as shown in:

The so-called drawing pipeline, is OpenGL in the process of drawing the image of the operation steps, mainly include: the evaluation, vertex-wise operation, element assembly, texture mapping, rasterization, chip operation and so on. Such a drawing pipeline is called a fixed drawing pipeline, because once the drawing begins, the drawing process is artificially impossible to intervene.

The introduction of shaders transforms the drawing pipeline from a fixed pipeline into a programmable drawing pipeline. The so-called programmable, refers to the process of drawing a fixed drawing line, you can join our logic. What do you mean? Equivalent to OpenGL providing us with a programming framework (not just a set of APIs), we can customize some of these parts. In this way, you can control the drawing pipeline more flexibly and achieve better drawing effect. This gives you the following drawing pipeline:

As you can see, a vertex shader, a geometry shader, and a slice shader are added on top of the fixed pipeline, where the vertex shader and the element shader are the most important. Vertex shaders process input vertices, such as three-dimensional transformations of vertices, adding colors, and so on, and the slice shader is processed by the raster-like texture map, performing lighting calculations, and so on, which is the calculation of the rendering color (I think this is the most fundamental meaning of the shader!). )。 These shaders are written in the GLSL language, which is similar to the C language and defines some built-in variables and interface APIs that are easy for us to handle.

To change the white triangle to blue, we can add a slice shader to it, and the shader outputs the color of the slice. The code is simple, which is to output a color value, as follows:

1 #version core2 3 out VEC4 fcolor;4 5 void Main () 6 {7     Fcolor = VEC4 (0.0, 0.0, 1.0, 1.0); 8}

Very simple, line 1th is the version information of GLSL. The 3rd line indicates that the shader has an output-the computed color, in the main function, the output variable is assigned a 4-dimensional color vector, R channel value of 0.0,G channel value of 0.0,B channel value is 1.0,a channel value is 1.0 (transparency), so the final color is blue.

After writing this shader program, the video card does not know the existence of this shader, so it also requires some steps-compiling, linking, and loading the shader into the graphics card. This part of the content is very much, we directly use the code provided by this book, Loadshader function to load the shader program, is to add the following code at the end of the Initialize function:

1 Shaderinfo shaders[] = {2         {gl_fragment_shader, "Triangles.frag"},3         {gl_none, null}4     };5     gluint program = Loadshaders (Shaders), 6     Gluseprogram (program);

Finally, the book also gives a vertex shader, in fact, this vertex shader can not be used, is to set the input vertex coordinates to the built-in variable gl_position, there is no effect is the same, for completeness or paste it up!

1 #version core2 3 layout (location = 0) in VEC4 vposition;4 5 void Main () 6 {7     gl_position = vposition;8}

Of course, load it into the video card as well. At this point, a simple OpenGL program is finished, in fact, modify the vertex data or modify the shader program, we can draw some other effects. For example, you can draw a pentagram out, or draw a color figure out.

3 Summary

Finally, summarize: the main learning of the cache object and vertex array object creation, copy the array data to the cache object, set the vertex array object properties related interface. Finally, we learned about OpenGL rendering pipelines-Fixed rendering pipelines and programmable rendering pipelines, and added a slice shader and a collection shader to our program.

Label:OpenGL

OpenGL Learning Path (i)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.