原文链接: http://hi.baidu.com/%CD%E6%CA%AF%CD%B7%B5%C4%D0%A1%BA%A2/blog/item/f7fff1ec091380deb31cb1d3.html
关于Cg(c for graphic)编程语言的信息
2002年6月13日,北京—图形处理解决方案领域的全球领袖NVIDIA公司(Nasdaq代码: NVDA)今日宣布推出面向新业界标准Cg图形编程语言的NVIDIA Cg编译器。同样也是今天宣布推出的Cg语言(C for Graphics)是一种高级图形编程语言,可为内容开发商提供一个全面的编程环境,使其更轻松、快捷地创建特殊效果和实时电影效果。NVIDIA Cg编译器是一种突破性的技术,可生成用于创建引人注目的实时视觉效果的优化图形汇编程序。
“我们正在进入一个图形软件开发的新世界,”In-Stat MDR公司《Microprocessor Report》主编Peter Glaskowsky说道,“Cg的发布标志着计算机图形业的一次革命—这是多年来第一次我们可以毫不夸张地这样说。”
NVIDIA Cg编译器是NVIDIA Cg编程环境的核心。面向标准DirectX8或DirectX 9兼容图形芯片(GPU)编写的程序可进行编译并可运行在任何兼容硬件上。所形成的程序是一种高效的顶点或象素渲染引擎,其性能水平相当于或优于手工编码 图形程序。NVIDIA的Cg编译器的设计目的是为了充分利用NVIDIA GPU的功能和通道,确保最优性能和视觉质量。此外,NVIDIA的Cg编译器还可独具特色地支持OpenGL。面向OpenGL平台编写的Cg渲染引 擎被编译和优化,以充分利用NVIDIA GPU里的扩展图形功能。NVIDIA的Cg编译器还是一种交叉平台,可支持面向Windows、OS X、Linux、Mac和Xbox编写的程序。
NVIDIA的Cg编译器的最强大功能是其前向和后向兼容性。NVIDIA Cg编译器借用NVIDIA著名的统一驱动架构(UDA),并最终采用了统一编译架构(UCA)。程序一旦编写完毕,将可运行在老一代或新一代Cg兼容 GPU上,并可在系统GPU运行时间里进行自动优化。这种独特的功能可使开发商无须承担GPU优化的重担。
“通过承担为当今GPU优化特殊效果的艰苦工作,Cg将使开发人员的生活变得更为轻松,”NVIDIA营销部副总裁Dan Vivoli说道,“因为我们利用Cg编译器进行许多工作,因此开发人员可将更多的时间放在游戏开发创意上。这开始了一个新的演绎传奇的时代。”
NVIDIA Cg工具套件Beta 1.0版将包括:
NVIDIA Cg编译器Beta 1.0—对GPU上渲染引擎进行编程的类C语言
NVIDIA Cg浏览器—带有大型Cg渲染引擎库的原型设计/可视化环境
Cg标准库—一套专门帮助熟悉一般计算机应用的编程人员的内嵌功能
Cg渲染引擎—供使用和学习的一套预编写范例
如欲了解更多有关NVIDIA Cg解决方案的信息,请访问NVIDIA网站:www.nvidia.com/view.asp?IO=cg。有兴趣了解NVIDIA Cg编译器更多信息的开发商可访问:http://developer.nvidia.com/org。如欲了解有关Cg和渲染的团体观点,请访问 www.cgshader.org。如欲了解开发商和其他人针对Cg的评论,请访问www.nvidia.com/view.asp?IO-cg testimonials。
------------------------------------------------------
Cg编程入门编(OpenGL)(1)
类型:转贴 | 来源:整理| 时间: 2006-07-07
Cg ,你好!
------Cg编程入门编(OpenGL)
原注:B Alex D'Angelo ([email protected])
译: 川流不息 ([email protected])未经本人同意,不能用于商业用途。
本文将介绍如何在你现有的图形程序中加入对顶点和片段的高级着色。采用CG着色语言,将会另你的工作更加容易实现。在编程过程中,你可以通过调用一些已有 的CG函数来完成你的工作。当然,当你学得足够深入后,你也可以自已编写一些着色器。最具有参考价值的资料,当然要数Fernando 和 Kilgard 编写的“The Cg Tutorial”了。在Nvidia公司的网页中可以下载到。
一、概述
本文的程序中,结合OpenGL和GLUT在屏幂中画了一个立方体,程序中加入了CG着色程序代码。Listing1中包含了完整的原程序代码,其中CG部分用粗体字标识出来,本程序贯穿全文。Listing2是一个CG顶点着色的代码。
二、建立Cg编程环境
在进行CG编程之前,首先要下载CG工具包“Cg Toolkit”,在以下网址可以找到:
http://developer.nvidia.com/CG ,请注意看一下你的显卡是否支持顶点着色编程。
安装CG工具包,为了能让它在Visual C++ 中工作,你可用以下两种方法之一。第一种:把CG头文件和库文件中的内容,分别拷贝到Visual C++的头文件和库文件的文件夹中。
From: C:\Program Files\NVIDIA Corporation\Cg\lib
To: C:\Program Files\Microsoft Visual Studio\VC98\Lib
From: C:\Program Files\NVIDIA Corporation\Cg\include
To: C:\Program Files\Microsoft Visual Studio\VC98\Include
第二种方法就是在VC编译器中增加一个搜索路径:Tools ->Options -> projects ->"directiress"
我们的程序中虽要连接“cg.lib”“cgGL.lib”这两个库文件,你可以把它写到连接路径中去:“properties ->Linker -> Input”,式者在程序开头加入以下代码:
#ifdef _MSC_VER
#pragma comment( lib, "cg.lib" )
#pragma comment( lib, "cgGL.lib" )
#endif
三、Cg编程细节
为了使用CG着色器,我们必须在程序中建立一个着色上下文(CGcontext),一个程序,只需一个着色上下文就可以了。
要为每个着色器建立一个CGprogram,而每个着色器你都可以为它指定一个单独的显卡适配参(CGprofile),CGprofile是用来告诉CG如何选择最适合你显卡的方式来对顶点或片段着色。
着色器可以在任何你虽要用到的地方被载入,载入的时候只需要给程序传递一个着色器函数入口名,或是着色器文件名。本文例子中,着色器在绘图循环前被载入,并且,为了适应各种显卡的在求,我们为着色器指定了一个基础profile
1、设定着色器要用到的变量。
首先,把CG头文件包含到你的程序中:
#include
#include
接着,增加一些用来保存着色器入口地址的变量:
static CGcontext Context = NULL;
static CGprogram VertexProgram = NULL;
以及一些着色参数的地址变量,在初始化着色器之后,这些地址变量将通过使用“CGparameters”与具体参数绑定在一起。
static CGparameter KdParam = NULL;
static CGparameter ModelViewProjParam = NULL;
static CGparameter VertexColorParam = NULL;
最后指定顶点着色用到的profile:
static CGprofile VertexProfile = CG_PROFILE_VP20;
2、初始化CG
程序中,初始化OpenGL这后,接着要对CG进行初始化。
首先,要创建一个着色上下文,一个程序中有一个着色上下文(context)就可以了,所有要用到的着色器都将会共享这一个上下文。
Context = cgCreateContext();
其次,通过给上下文指定着色器文件名以及着色器类型(这里是顶点着色),把一个顶点着色器加到着色上下文中去。
VertexProgram = cgCreateProgramFromFile(Context,
CG_SOURCE, "vertexShader.cg",
VertexProfile,
NULL, NULL);
只有在顶点着色器被成功创建之后,着色器的代码才被真正地载入到程序中来,与此同时,各种着色参数地址也最终与着色器中的参数绑定在一起。在这之后的程 序中,你便可以自由地使用和改变这些参数的内容了。如例子中所示的:反射光颜色(kdParam),顶点颜色(vertexColorParam)和模型 透视矩阵(modelViewProj),些变量都是可以改变的。
在绘图主循环结束之后,所有着色器占用的资源都要及时释放,在CG中,提供了两个函数:
cgDestroyProgram();和cgDestroyContext(); 让我们完成这一工作变得更简单。
3、绘图循环
进入绘图循环之后,着色器必虽在实际绘图这前调用,绘图结束这后就应该被禁用。这个概念和glBegin(); 及 glEnd(); 的意思是相似的,实际上CG是不能在 glBegin(); 和 glEnd(); 之间被调用的。
在所有绘图工作开妈之前,我们通过调用函数 cgGLBindProgram(); 把着色代码与OpenGL绘图代码关联起来,紧接着调用cgGLEnableProfile(); 函数来指定CG程序到底是进行顶点着色,还是片段着色。之后我们就可以利用cgGLSetParamter*();函数来传递或使用着色器中的参数了。
在所有绘图工作完成之后,我们应该马上调用cgGLDisableProfile(); 来停止着色器的使用。
着色器的参数是可以随时改变的,例如:立方体的顶点颜色可以通过函数cgGLSetParameter3f(vertexColorParam,0.0,1.0,0.00);来设定。
既然我们知道了如何在绘图循环中使用一个着色器,那么扩展到在一个绘图循环中使用多个着色器的情况,那也是很容易实现的,简单地把着色绑定包在绘图代码的外层就可以了。
例如:
void draw()
{
cgGLBindProgram(program);
cgGLEnableProfile(profile);
drawing_code()
cgGLDisableProfile(profile);
cgGLBindProgram(program2);
cgGLEnableProfile(profile2);
drawing_code2()
cgGLDisableProfile(profile2);
}
四、结论
现在我们已经学会了如何把着色代码加入到我们现有的程序中。在http://developer.nvidia.com/CG和别的一些相关网站中,有许多着色代码提供给我们使用,同时也可我和他们一起分享你的经验。
Listing 1 : HelloCg.c
Using Cg with your programs. Cg specific calls are in bold. Heavily based on the runtime_ogl
project in the Cg toolkit.
/* Minimalist program for using shaders, with no error checking */
#ifdef _MSC_VER
#pragma comment( lib, "cg.lib" )
#pragma comment( lib, "cgGL.lib" )
#endif
#include
#include
#include
#ifdef __APPLE__
#include
#else
#include
#endif
#include
#include
/******************************************************************************/
/*** Static Data ***/
/******************************************************************************/
/* New Cg global variables */
static CGcontext Context = NULL;
static CGprogram VertexProgram = NULL;
static CGparameter KdParam = NULL;
static CGparameter ModelViewProjParam = NULL;
static CGparameter VertexColorParam = NULL;
#ifdef __APPLE__
static CGprofile VertexProfile = CG_PROFILE_ARBVP1;
#else
static CGprofile VertexProfile = CG_PROFILE_VP20;
#endif
/* End new Cg global variables */
GLfloat CubeNormals[6][3] =
{
{-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
{0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0}
};
GLint CubeFaces[6][4] =
{
{0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
{4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3}
};
GLfloat CubeVertices[8][3];
/******************************************************************************/
static void DrawCube(void)
{
int i;
cgGLBindProgram(VertexProgram);
/*
* Set various uniform parameters including the ModelViewProjection
* matrix for transforming the incoming position into HPOS.
*/
if(KdParam != NULL)
cgGLSetParameter4f(KdParam, 1.0, 1.0, 0.0, 1.0);
/* Set the concatenate modelview and projection matrices */
if(ModelViewProjParam != NULL)
cgGLSetStateMatrixParameter(ModelViewProjParam,
CG_GL_MODELVIEW_PROJECTION_MATRIX,
CG_GL_MATRIX_IDENTITY);
cgGLEnableProfile(VertexProfile);
/*
* Create cube with per-vertex varying attributes
*/
for(i = 0; i < 6; i++)
{
glBegin(GL_QUADS);
{
glNormal3fv(&CubeNormals[i][0]);
cgGLSetParameter3f(VertexColorParam, 1.0, 0.0, 0.0);
glVertex3fv(&CubeVertices[CubeFaces[i][0]][0]);
cgGLSetParameter3f(VertexColorParam, 0.0, 1.0, 0.0);
glVertex3fv(&CubeVertices[CubeFaces[i][1]][0]);
cgGLSetParameter3f(VertexColorParam, 0.0, 0.0, 1.0);
glVertex3fv(&CubeVertices[CubeFaces[i][2]][0]);
cgGLSetParameter3f(VertexColorParam, 1.0, 1.0, 1.0);
glVertex3fv(&CubeVertices[CubeFaces[i][3]][0]);
}
glEnd();
}
cgGLDisableProfile(VertexProfile);
}
static void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DrawCube();
glutSwapBuffers();
}
static void InitializeCube(GLfloat v[8][3])
{
/* Setup cube vertex data. */
v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;
v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1;
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;
v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1;
v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
}
static void InitializeGlut(int *argc, char *argv[])
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow(argv[0]);
glutDisplayFunc(Display);
InitializeCube(CubeVertices);
/* Use depth buffering for hidden surface elimination. */
glEnable(GL_DEPTH_TEST);
/* Setup the view of the cube. */
glMatrixMode(GL_PROJECTION);
gluPerspective( /* field of view in degree */ 40.0,
/* aspect ratio */ 1.0,
/* Z near */ 1.0, /* Z far */ 10.0);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */
0.0, 0.0, 0.0, /* center is at (0,0,0) */
0.0, 1.0, 0.); /* up is in positive Y direction */
/* Adjust cube position to be asthetic angle. */
glTranslatef(0.0, 0.0, -1.0);
#if 1
glRotatef(60, 1.0, 0.0, 0.0);
glRotatef(-20, 0.0, 0.0, 1.0);
#endif
}
int main(int argc, char *argv[])
{
InitializeGlut(&argc, argv);
/* Create one context which all shaders will use */
Context = cgCreateContext();
/* Adds shader to the context */
VertexProgram = cgCreateProgramFromFile(Context,
CG_SOURCE, "vertexShader.cg",
VertexProfile,
NULL, NULL);
if(VertexProgram != NULL)
{
/* Vertex shader only needs to be loaded once */
cgGLLoadProgram(VertexProgram);
/* Bind parameters to give access to variables in the shader */
KdParam = cgGetNamedParameter(VertexProgram, "Kd");
ModelViewProjParam = cgGetNamedParameter(VertexProgram, "ModelViewProj");
VertexColorParam = cgGetNamedParameter(VertexProgram, "IN.VertexColor");
}
glutMainLoop();
cgDestroyProgram(VertexProgram);
cgDestroyContext(Context);
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Listing 2 : vertexShader.cg
Cg vertex shader code written. Heavily based on the runtime_ogl project in the Cg toolkit.
struct appdata
{
float4 position : POSITION;
float3 normal : NORMAL;
float3 color : DIFFUSE;
float3 VertexColor : SPECULAR;
};
struct vfconn
{
float4 HPOS : POSITION;
float4 COL0 : COLOR0;
};
vfconn main(appdata IN,
uniform float4 Kd,
uniform float4x4 ModelViewProj)
{
vfconn OUT;
OUT.HPOS = mul(ModelViewProj, IN.position);
OUT.COL0.xyz = Kd.xyz * IN.VertexColor.xyz;
OUT.COL0.w = 1.0;
return OUT;
} // main
-------------------------------------------------
Cg入门介绍1——VS工程设置
1. 介绍
Cg是由NVIDIA公司和MS公司联合设计的一个针对图形卡硬件编程的高级语言。Cg的编译器可以将Cg转化为汇编语言,然后交由图形卡处理器执行。本篇文章主要介绍一下在VS.NET2003下开发OpenGL程序时,引入Cg所需要进行的各项设置。
2.Cg工具包的下载及安装
Cg 下载 http://developer.nvidia.com/object/cg_toolkit.html ;当前版本为1.4.0,下载后直接双击exe文件安装即可,安装程序会自动设置环境变量,安装完了以后,在cmd模式下敲入cgc -help, 会列出cgc命令的使用参数,证明cg编译器安装成功。
3.工程设置
每次建立一个新工程的时候都需要重复此步骤,先介绍一个顶点程序(vertex program)的配置,片断程序(fragment program)道理是一样的。
创建一个win32工程在这里就不再多说了。对于cg文件,我们可以把它们放在同一个文件夹里统一管理(当然也可以不这样),新建一个文件夹,自己取个名字。在该文件夹上右键属性,Filter可以设置该文件夹所支持的文件后缀名。
添加一个cg文件,右键属性里面可以自定义一个编译规则:
Command Line:cgc $(InputPath) -o $(InputName).vp -profile CG_PROFILE_ARBVP1
Outputs:$(InputName).vp
其中-profile 后面紧跟的就是cgc编译时所需要的,你显卡可以支持的配置文件。这个编译器使cg程序编译成OpenGL ARB vertex 程序,是一个后缀名为vp的汇编代码文件,可以通过修改profile来得到不同的汇编程序。应用程序在调用cg语言时有两种方法,一种是直接调用cg, 另外一种是调用由cgc编译生成的vp文件,因此这一步可以不做。
4 高亮显示
这一步主要是可以使得在vs中写cg程序时,能够识别并高亮显示cg的关键字。
a>. 找到cg的安装目录,拷贝 usertype.dat 到Visual Studio 目录(C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE
b>找到cg的安装目录,msdev_syntax_highlighting目录下面有个install_highlighting_vs7.reg文件,直接双击加入注册表即可。记得重启vs.net
下次介绍如何写一个简单的cg程序,并添加到一个OpgenGL应用程序中。