Thinking in Shader(4)

开发环境

Window7

CgToolkit

VS2008


        羽化的第二十篇博客,没想到写到二十篇了,送上有点稍晚,Cg基础部分学得或多或少了,不出意外下周开始学写Cg代码了,到时候再慢慢更新在博客上,由于明哥的给力我们的地图终于支持到了6层,正在向无限层发起挑战,明哥钢霸得。。。这周翻了地牢围攻3,很精美的一款游戏,2代可以说是羽化玩过的仅次于暗黑的相同类型游戏,3代由于加入Square制作后,技术明显提升,各种Flare应用得淋漓尽致,但没了原来的朴实与多样性,彻头彻尾变成了另一个游戏。。。话说波仔被车撞了,也就是上周的事情,知道以后些许担心,但也有些许气愤,作为在上海唯一的老乡朋友,居然不告诉我。。。但幸好没事,依然和我们犀利dota- - 工作越来越忙,人手不足一直是个很头疼的问题,况且大家都没这方面经验,作为公司的第一个Unity游戏,居然做成MMORPG类型,其实羽化虽然信心满满,但总会遇到很多无法预料的问题,还是太弱了。。。

        发个牢骚(以下为个人意见):其实羽化一直搞不懂,为什么一个游戏公司养这么多策划,羽化认为策划应该是一个高层次的职业少而精,对应文艺或者设计方面的人才,能提供有价值的参考和规定制作的核心内容:游戏系统、场景、剧情、数值调整等复杂设定,但现在的公司里策划却能每天悠然自得,竟是些看漫画、看电影、打游戏、吃吃零食的空虚年轻人,策划需要丰富的阅历和灵感不错,但不是玩玩国内的垃圾游戏(国内也有很多好作品,但大多数是仿制的垃圾),看几部贺岁电影能培养出来的。。。做一个MMO就想仿照魔兽世界,又搞些多余的休闲方式和活动,这样根本无法超越它,这可能就是国内游戏缺少创新的主要原因,也和这个利益社会有关系吧。羽化认为国内很少有游戏制作人这种说法,制作人应该置于策划,高于策划,控制整个游戏的制作内容而不是规定游戏的制作方式,由于缺少一个与程序、美术、策划三方交流的核心,所以经常是一堆空虚的策划在一起商量一些大家都懂的常识问题,于是又一款山寨游戏就这此诞生了。总的一句话:策划这职业不是什么人都能当的,国内的策划伤不起- -


介绍 Cg Runtime

       Cg代码使用代码来描述材质,但是他们需要应用程序的支持来创建图像。在Cg的程序界面,你必须做两件事:

1.  为正确的配置编译程序,换句话说,就是我们要编译程序按照特点定的3D API的应用程序和底层硬件配置。

2.  连接程序在应用中,使其允许应用程序支持不同的和统一的数据接口给程序。  

        你有两种方式执行他们,一种是当应用程序编译在一个可执行文件中的时候,另一种是在运行的时候,应用程序在执行的时候。Cg Runtime是一个应用程序接口,允许Cg程序在运行时编译和链接。其优势在于未来的兼容性,没有依赖限制,输入参数管理三个方面。

 

Header Files 头文件

要引用Cg runtimeAPI在C或者C++中,头文件有以下几种:

核心:	#include <Cg/cg.h>
OpenGL:	#include <Cg/cgGL.h>
Direct3D 9:	#include <Cg/cgD3D9.h>
Direct3D 8:	#include <Cg/cgD3D8.h>

Creating a Context 创建关联

    一个Context是一个容器包含多个Cg程序,他保存Cg程序就像分享数据意义。下面是创建方法:

CGcontext context = cgCreateContext();

Compiling a Program 编译程序

         编译Cg程序通过添加一个Context通过 cgCreateProgram():

CGprogram program = cgCreateProgram(context,CG_SOURCE, myVertexProgramString,CG_PROFILE_ARBVP1, "main", args);

       CG_SOURCE表明myVertexProgramString,一个string类型参数,包含Cg起源代码,没有预先编译代码,甚至如果你想,Cg runtime允许你创建一个程序来预编译。

       CG_PROFILE_ARBVP1是一个表面的编译程序,“main”参数给这个功能命名作为入口当程序运行时,最后args是一个空字符串的空列表,可以传递一个参数来编译。

   

 Loading a Program 加载程序

//在Direct3D首先设置硬件
cgD3D9SetDevice(Device);
//下面读取Direct3D 9 Cg Runtime:
cgD3D9LoadProgram(program, CG_FALSE, 0);
//或者Direct3D 8 Cg Runtime:
cgD3D8LoadProgram(program, CG_FALSE, 0, 0, vertexDeclaration);

//在OpenGL则是
cgGLLoadProgram(program);

Modifying Program Parameters 参数修改

        想修改参数,第一步先获得句柄:

CGparameter myParameter = cgGetNamedParameter(program, "myParameter");

        myParameter是源文件中出现的参数。

        第二步是设定一个参数值,这个功能取决于参数类型,下面是个例子:

cgGLSetParameter4fv(myParameter, value);   //OpenGL
cgD3D9SetUniform(myParameter, value);		//Direct3D
cgSetParameterValuefr(myParameter, 4, value); //数值参数可以通过Cg Runtime获得,这是被假定为一个float4类型参数

Executing a Program 执行程序

         先设置配置文件,Direct3D中没有明确的配置。

cgGLEnableProfile(CG_PROFILE_ARBVP1);	//OpenGL
cgGLDisableProfile(CG_PROFILE_ARBVP1);	//相反

         下面是绑定程序:

cgGLBindProgram(program);	// OpenGL
cgD3D9BindProgram(program);		//Direct3D

Releasing Resources 释放资源

cgD3D9SetDevice(0);
cgDestroyProgram(program);
cgDestroyContext(context);	//破坏所有



Cg Runtime 核心

        顾名思义,应用中负责提供所有的Cg管理程序,主要负责3个主要概念:context,program,parameter,依次代表了CGcontext, CGprogram, 和CGparameter object 类型。




Cg Context 核心

       向Cg runtime提供创造,毁灭,查询,链接等功能。

CGcontext cgCreateContext();  //创造
void cgDestroyContext(CGcontext context); //毁灭所有链接,包括包含此链接的所有程序
CGbool cgIsContext(CGcontext context);  //查询有效性



Cg Program 核心

      提供创建,毁灭,迭代结束,和查询程序。

//程序直接包含源代码
CGprogram cgCreateProgram(CGcontext context,CGenum programType,
			const char* program,CGprofile profile,
			const char* entry,const char** args);     

//一个字符串包含文件名,里面是源代码
CGprogram cgCreateProgramFromFile(CGcontext context,CGenum programType,
				const char* program,CGprofile profile,
				const char* entry,const char** args); 

//移除程序
void cgDestroyProgram(CGprogram program);
        当一个程序问完成,他会自动卸载或者释放,为了方便下次使用,程序必须重编译再加载和回收。编译可执行手动执行或者自动:

cgCompileProgram(CGprogram program); //一般用于编译或者重编译

void cgSetAutoCompile(CGcontext ctx, CGenum flag);
//后面的flag一般为CG_COMPILE_MANUAL、CG_COMPILE_IMMEDIATE、CG_COMPILE_LAZY

CGbool cgIsProgramCompiled(CGprogram program);

         程序包含链接,这里提供了迭代,如果没用返回0:

CGprogram cgGetFirstProgram(CGcontext context);
CGprogram cgGetNextProgram(CGprogram program);

CGprogram program = cgGetFirstProgram(context);
while (program != 0)
{
	/* Here is the code that handles the program */
	program = cgGetNextProgram(program);
}

         查询方法很多:

CGbool cgIsProgram(CGprogram program); //有效性

const char* cgGetLastListing(CGcontext context); //编译结果 只针对cgCreateProgram

//得到属性
CGcontext cgGetProgramContext(CGprogram program);
CGprofile cgGetProgramProfile(CGprogram program);
CGprofile cgGetProfile(const char* profileString);
const char* cgGetProfileString(CGprofile profile);
const char* cgGetProgramString(CGprogram program,
								CGenum stringType);
//这里的stringType一般对应CG_PROGRAM_SOURCE、CG_PROGRAM_ENTRY、 CG_PROGRAM_PROFILE、CG_COMPILED_PROGRAM



Cg Parameters 核心

         参数分为3类:程序参数、特效参数、共享参数。 分别联系着Cg programs,Cg Effects,Cg contexts。 Cg提供有提取,创建和查找程序参数。

CGparameter cgGetFirstStructParameter(CGparameter parameter);  //提供程序迭代,如果类型不为CG_STRUCT会返回0
         同时要提供数组元素可使用:

int cgGetArrayDimension(CGparameter parameter);
int cgGetArraySize(CGparameter parameter, int dimension);
CGparameter cgGetArrayParameter(CGparameter parameter,int index);  //如果类型不为CG_ARRAY会返回0
         下面是一个完整的使用实例:

void IterateProgramParameters(CGprogram program) 
{
	RecurseProgramParameters(cgGetFirstParameter(program, CG_PROGRAM));
}
void RecurseProgramParameters(CGparameter parameter) 
{
	if (parameter == 0)
	return;
	do 
	{
		switch(cgGetParameterType(parameter)) 
		{
		case CG_STRUCT:
			RecurseProgramParameters(
			cgGetFirstStructParameter(parameter));
		break;
		case CG_ARRAY:
			int arraySize = cgGetArraySize(parameter, 0);
			for (int i = 0; i < arraySize; ++i)
			RecurseProgramParameters(cgGetArrayParameter(parameter, i));
		break;
		default:
/* Here is the code that handles the parameter */
	break;
	}
	} while((parameter = cgGetNextParameter(parameter))!= 0);
}

         实际上,经常遍历所有参数用“leaf”:

CGparameter cgGetFirstLeafParameter(CGprogram program,CGenum namespace);
CGparameter cgGetNextLeafParameter(CGparameter parameter);

         所有程序参数可以直接寻回:

CGparameter cgGetNamedProgramParameter(CGprogram program,CGenum namespace,const char* name);

         Cg runtime提供的参数值管理方法:

int cgGetParameterValue{i,f,d}{r,c}(CGparameter param, int nvals, type *v);
const double* cgGetParameterValues(CGparameter parameter,CGenum valueType,int* numberOfValuesReturned);



Shared Parameters 共享参数

         Cgruntime支持创建任何类型的实例参数在一个Cg context中,一个参数可能连接多个拥有相同兼容的参数,包括任何程序或者环境参数在这个链接中。

         共享参数通过CGcontext连接,创建方式如下:

CGparameter cgCreateParameter(CGcontext ctx, CGtype type);
CGparameter cgCreateParameterArray(CGtype type, int length);
CGparameter cgCreateParameterMultiDimArray(CGtype type, int dim, int *lengths);
         删除方式:删除后所有连接取消
Void cgDeleteParameter(CGparameter param);

         连接参数:一个共享参数创建成功也许会连接很多程序,特效或者共享参数使用

void cgConnectParamteer(CGparameter source, CGparameter sink);
Void cgDisconnectParameter(param); //取消连接

         Cg中也经常使用模块或者是接口,这方面使用和普通高级语言类似。



Parameter Properties 参数属性

         参数属性包含很多内容,含有效性、关联、大小、以及其他属性。

interface MyInterface 
{
	float SomeMethod(float x);
};
struct MyStruct : MyInterface 
{
	float Scale;
	SomeMethod(float x)
	{
		return(Scale * x);
	}
};

         上面是一个例子,如果这个程序在开始时创建,那么MyInterface和MyStruct类型将会添加到输出结果中。下面是关联类型:

CGtype cgGetParameterNamedType(CGparameter param);
CGtype cgGetNamedUserType(CGhandle handle, const char *name); //handle可以使任意cg程序或者特效

//父类可以获得所有入口点
int cgGetNumParentTypes(CGtype type);
CGtype cgGetParentType(CGtype type, int index);
//单一类型获取入口点
int cgGetNumUserTypes(CGprogram program);
CGtype cgGetUserType(CGprogram program, int index);
//针对老应用获取入口
CGtype cgGetParameterType(CGparameter parameter);

//可应用于查询
const char* cgGetTypeString(CGtype type);
//也可能是一般类型参数
CGparameterclass cgGetParameterClass(CGparameter param);

        同样可以查看有效性和关联性:

CGbool cgIsParameter(CGparameter parameter);
CGbool cgIsParameterReferenced(CGparameter parameter);

         查看大小:

int cgGetParameterRows(CGparameter param);
int cgGetParameterColumns(CGparameter param);

int cgGetArrayDimension(CGparameter param);   //维度
int cgGetArraySize(CGparameter param, int dimension);   //特定尺寸
int cgGetArrayTotalSize(CGparameter param);  //总共大小

CGtype cgGetArrayType(CGparameter param); //规定类型可以在以后查询使用

//一样可以用不固定类型数组
void cgSetArraySize(CGparameter param, int size);
void cgSetMultiDimArraySize(CGparameter param, int *sizes); //多维

         查看属性

CGparameterclass cgGetParameterClass(CGparameter param); //常规类查询
/*
CG_PARAMETERCLASS_SCALAR
CG_PARAMETERCLASS_VECTOR
CG_PARAMETERCLASS_MATRIX
CG_PARAMETERCLASS_STRUCT
CG_PARAMETERCLASS_SAMPLER
CG_PARAMETERCLASS_OBJECT
*/

//程序查询
CGprogram cgGetParameterProgram(CGparameter parameter);

//可变性查询
CGenum cgGetParameterVariability(CGparameter parameter);
//设置可变性,这里的vary可能为CG_UNIFORM,CG_LITERAL,CG_DEFAULT
void cgSetParameterVariability(CGparameter parameter, CGenum vary);
//获取参数方向
CGenum cgGetParameterDirection(CGparameter parameter);

//检索参数名
const char* cgGetParameterName(CGparameter parameter); 
//取回语义字符串
const char* cgGetParameterSemantic(CGparameter parameter);

//资源分配参数,若没任何关联返回CG_UNDEFINED
CGresource cgGetParameterResource(CGparameter parameter);
//确定一个资源点和对应字符串
CGresource cgGetResource(const char* resourceString);
const char* cgGetResourceString(CGresource resource);
//允许恢复原本资源
CGresource cgGetParameterBaseResource(CGparameter parameter);
//检索数值部分资源
unsigned long cgGetParameterResourceIndex(CGparameter parameter);
//得到默认或者统一数值
const double* cgGetParameterValues(CGparameter parameter,CGenum valueType, int* numberOfValuesReturned);


Cg核心错误报告

         应用程序会缓冲查询错误代码,如下方法:

CGerror error = cgGetError();
CGerror error = cgGetFirstEror();
const char* errorString = cgGetErrorString(error);

//登记错误处理器
typedef void (*CGerrorHandlerFunc)(CGcontext ctx, CGerror err, void *appdata);
void cgSetErrorHandler(CGerrorHandlerFunc func, void *data);

         一般使用如下:

void HandleCgError(CGcontext ctx, CGerror err, void *appdata)
{
	fprintf(stderr, "Cg error: %s\n", cgGetErrorString(err));
	const char *listing = cgGetLastListing(ctx);
	if (listing != NULL)
		fprintf(stderr, " last listing: %s\n", listing);
}

        很多网友询问羽化如何使用Unity显示广告,看过源代码由于不难,用的是羽化写过的Android调用方法,没有深入研究,只是看到明哥实现过,所以先去明哥那取下经,在做研究- -


下期预告:

Unity Android平台AdMob应用

评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符 “速评一下”
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页