Go from "translation" Nehe OpenGL tutorial
Objective
Statement, this Nehe OpenGL tutorial series of articles by 51 blog yarin Translation (2010-08-19), this blog for reprint and a little collation and modification. Thank you for compiling Nehe's OpenGL pipeline tutorial, as well as yarn translation finishing.
Nehe OpenGL Lesson 47th: CG Vertex script
CG Vertex Script
Nvidio's GPU-oriented C language, if you believe it to learn well, also here is just a primer. Remember, a similar language also has Microsoft's Hlsl,opengl Glsl,ati's shadermonker. Do not choose the wrong OH:)
The extra benefit of using vertex and fragment scripting to do rendering work is to give some of the CPU's work to GPU,CG to provide a means to write these powerful scripts.
This tutorial has many purposes, and the first shows you a very simple vertex script, and the second shows you how to use CG-written scripts in OpenGL.
This tutorial is based on the basic code of the newest NEHEGL, in order to get more information, you can visit Nvidia's official website (developer.nvidia.com), it will give you a complete answer.
Note: This tutorial does not tell you how to write a complete CG script, but instead teaches you to load and run the script in OpenGL.
Begin:
The first step is to download the CG compiler library from the Nvidia website, preferably by downloading the 1.1 version, because the Nvidia versions vary greatly, so it's best to do so in order to keep the program from having any problems, because we're using version 1.1.
Next, include the header and library files required for compilation.
I have helped you to copy them into the project folder.
CG Introduction
You must have the following concepts:
1. The vertex script acts on each vertex you enter, and if you want to work on some vertices, you must load the vertex script before the action and release the vertex script after the action.
2, the result of the vertex script output is fed into the fragment processor, you do not have to control how this is implemented.
Finally, remember that the vertex script is executed before the entity is assembled, and the fragment script is executed after rasterization.
OK, now let's create a blank file (save it as WAVE.CG), and then we'll create a data structure that is used by our script. The following code is added to the WAVE.CG file.
struct AppData {float4 position:position; float4 color:color0; float3 Wave:color1;};
The above results show that the vertices we enter contain a position coordinate, a color and the color of our custom wave
The following code defines the data for an output vertex, including a vertex and a color
struct vfconn{float4 hpos:position; float4 col0:color0;};
The following code is the main function of CG, and each vertex is executed by the following function:
Vfconn Main (AppData in, uniform float4x4 modelviewproj)
{
Vfconn out; Save data from our output vertices
Calculates the coordinates of Vertex y
IN.POSITION.Y = (sin (in.wave.x + (in.position.x/5.0)) + sin (in.wave.x + (in.position.z/4.0))) * 2.5f;
Save to output data
Out. Hpos = Mul (modelviewproj, in.position);
Does not change the color of the input
Out. COL0.XYZ = IN.color.xyz;
return out;
}
Complete the above code, remember to save it.
below we get to the program, first include the header files needed for CG, and the library file
#include <cg\cg.h> #include <cg\cggl.h>
#pragma comment (lib, "Cg.lib") #pragma Comment (lib, "Cggl.lib")
Below we define a number of global variables used to calculate our grids and control the CG program switches
#define size 64 // Define the size of the grid bool cg_enable = TRUE, sp; //switch CG program glfloat mesh[size][size][3]; //Save Our grid glfloat wave_movement = 0.0f; //recording movement of fluctuations
Let's define some CG-related global variables
Cgcontext Cgcontext; Used to save CG scripts
The first variable we need is Cgcontext, which is a container for multiple CG scripts, and generally you get the script you want to get from this container with a function
Next we define a Cgprogram variable, which is used to save our vertex script.
Cgprogram Cgprogram; We need the vertex script.
Next we need a variable to set how to compile this vertex script
Cgprofile Cgvertexprofile; Used by vertex scripts
Below we need some parameters to transfer the data used by the CG script from the program to the past.
Cgparameter position, color, modelviewmatrix, wave; Parameters required in the script
In the initialization phase we first create our grid data
Glpolygonmode (Gl_front_and_back, gl_line);
for (int x = 0; × < SIZE; x + +)
{
for (int z = 0; z < SIZE; z++)
{
Mesh[x][z][0] = (float) (SIZE/2)-X;
MESH[X][Z][1] = 0.0f;
MESH[X][Z][2] = (float) (SIZE/2)-Z;
}
}
We set the realistic mode of the polygon to wireframe, then traverse the no vertex to set its height.
Next, we initialize the CG program
Set CG Cgcontext = Cgcreatecontext (); Create a CG container
Test whether the creation was successful
if (Cgcontext = = NULL)
{
MessageBox (NULL, "Failed to Create Cg Context", "Error", MB_OK);
return FALSE;
}
We create a container for a CG program and check whether it was created successfully
Cgvertexprofile = Cgglgetlatestprofile (Cg_gl_vertex); Configure the use of vertex caching in OpenGL
Detect if the CG program was created successfully
if (Cgvertexprofile = = Cg_profile_unknown)
{
MessageBox (NULL, "Invalid profile type", "Error", MB_OK);
return FALSE;
}
Cgglsetoptimaloptions (Cgvertexprofile); Enable configuration file
If you want to use a fragment script, use the cg_gl_fragment variable. If the returned variable is cg_profile_unknow to indicate that no configuration file is available, you will not be able to compile the CG program you need.
Load CG program from File Cgprogram = Cgcreateprogramfromfile (Cgcontext, Cg_source, "CG/WAVE.CG", Cgvertexprofile, "main", 0);
Detection is successful
if (Cgprogram = = NULL)
{
Cgerror Error = Cggeterror ();
MessageBox (NULL, cggeterrorstring (Error), "error", MB_OK);
return FALSE;
}
We try to create a CG program from the source file and return the compiled results.
Load Script Cgglloadprogram (Cgprogram);
Here we load the vertex script into the video memory and are ready to help the GPU. All scripts must be loaded before they are used.
The data variable address is sent to the CG program position = Cggetnamedparameter (Cgprogram, "in.position"); color = Cggetnamedparameter (Cgprogram, "In.color"); Wave = Cggetnamedparameter (Cgprogram, "In.wave"); Modelviewmatrix = Cggetnamedparameter (Cgprogram, "modelviewproj");
return TRUE;
At the end of the initialization, we have to tell the CG script where to get the input data, we need to pass the pointer over the variable, and the following function completes the function.
At the end of the program, remember to release the content we created.
Cgdestroycontext (Cgcontext);
The following code uses spaces to toggle whether a CG program is used
if (G_keys->keydown ["] &&!sp) {sp=true; cg_enable=!cg_enable; }
if (!g_keys->keydown ["]) Sp=false;
Now that we have finished all the preparations, we have actually mapped out the grid, and as a rule we have to set our own viewport first.
Glulookat (0.0f, 25.0f, -45.0f, 0.0f, 0.0f, 0.0f, 0, 1, 0);
The current CG program's model change matrix is told to the current program Cgglsetstatematrixparameter (Modelviewmatrix, Cg_gl_modelview_projection_matrix, CG_GL_ matrix_identity);
What we have to do above is to tell the current program the model change matrix of the current CG program.
If you use a CG program, set the color of the vertex to green
//if using a CG program if (cg_enable) { //using a vertex script configuration file cgglenableprofile (cgvertexprofile); // Help to the current vertex script cgglbindprogram (cgprogram); //Set paint color cgglsetparameter4f (color, 0.5f , 1.0f, 0.5f, 1.0f); }
Let's draw our grid.
//start drawing our grid for (int x = 0; x < SIZE-1; + +) &NBSP;{&NBSP;&NB Sp;glbegin (Gl_triangle_strip); for (int z = 0; z < SIZE-1; z++) { //Set wave parameters cgglsetparameter3f (Wave, wave_movement, 1.0f, 1.0f) //set the input vertex glvertex3f (Mesh[x][z][0], mesh[x][z][1], mesh[x][z][2]); glvertex3f (Mesh[x+1] [Z] [0], mesh[x+1][z][1], mesh[x+1][z][2]); wave_movement + = 0.00001f; if (Wave_movement > Two_pi) wave_movement = 0.0f; } //is processed by CG program and is drawn glend ();
The above code completes the specific drawing operation, for each vertex, we dynamically pass in the volatility coefficients and input the original vertex data. Before the drawing begins, the vertex script accepts all the vertex data and processes it, then the raster operation.
Don't forget to close our enabled vertex script when drawing is done, or else you will get unwanted results when drawing other models.
if (cg_enable)
Cggldisableprofile (Cgvertexprofile); Disabling the vertex script configuration file
Original source code and version of the download:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=47
Nehe OpenGL Tutorial Lesson 47th: CG Vertex script