Thinking in Shader(5)

来源:互联网 发布:日本黑帮电影 知乎 编辑:程序博客网 时间:2024/06/05 08:18

Thinking in Shader(5)

 

开发环境

Window7

CgToolkit

VS2008

 

 

        羽化的第二十二篇博客,据说Unity3D官网注册超过了70万,是去年的3倍,再者网上的教程也慢慢变多,各种质量的教程也相继出现,但大多数都是英文版,貌似看过中文视频一个做坦克的,只可借鉴,制作方法实在不敢恭维。。。羽化认为Unity作为一款引擎来说还不算成熟,在开发过程中也许会遇到各种奇怪问题,而且稳定性无法保证,但作为像羽化这种新手来说,开发简单很适合用来学习,而且新版本也许会改进很多问题,希望Unity3D越做越好。最近腾讯在大力宣传一款叫做《艾尔之光》的游戏,在公司看到有人在玩,看了看貌似做得不错,3D横版卡通渲染漫画风格的游戏,有点看到《龙之谷》的感觉,可惜物是人非,提不起劲来- -这种游戏若没喜欢的朋友一起玩,也就3分钟热度,韩国很适合做这类休闲游戏,可能是因为没文化底蕴又不受文化约束。。。游戏在推动世界进步,推荐大家去看看“[道兰][NHK纪录片]世界游戏革命”,可以对比自己心中的游戏,感觉还差多远。

 

Parameter Shadowing参数映射

       当一个统一的参数通过一些OpenGL Cgruntime功能允许的时候,通常会被保存在内存,这样每次使用时就不需要重新设置,这种行为就叫做参数映射,缺点在于消耗内存大小,但依然值得使用,其允许所有参数设置在纹理状态阶段和纹理模式下。

 

OpenGL Cg Runtime

      这里介绍一些基本参数,一般有两个版本,一个是float操作的标为“f”,另一个是以double操作的,设为“d”。

//设置统一标量和统一向量参数,通过cgGLSetParameter功能:void cgGLSetParameter1f(CGparameter parameter, float x);void cgGLSetParameter1fv(CGparameter parameter, const float* array);void cgGLSetParameter1d(CGparameter parameter, double x);void cgGLSetParameter1dv(CGparameter parameter, const double* array);void cgGLSetParameter2f(CGparameter parameter, float x, float y);void cgGLSetParameter2fv(CGparameter parameter, const float* array);void cgGLSetParameter2d(CGparameter parameter, double x, double y);void cgGLSetParameter2dv(CGparameter parameter, const double* array);void cgGLSetParameter3f(CGparameter parameter, float x, float y, float z);void cgGLSetParameter3fv(CGparameter parameter, const float* array);void cgGLSetParameter3d(CGparameter parameter, double x, double y, double z);void cgGLSetParameter3dv(CGparameter parameter, const double* array);void cgGLSetParameter4f(CGparameter parameter, float x, float y, float z, float w);void cgGLSetParameter4fv(CGparameter parameter, const float* array);void cgGLSetParameter4d(CGparameter parameter, double x, double y, double z, double w);void cgGLSetParameter4dv(CGparameter parameter, const double* array);//相对应的检索功能cgGLGetParameter1f(CGparameter parameter, float* array);cgGLGetParameter1d(CGparameter parameter, double* array);cgGLGetParameter2f(CGparameter parameter, float* array);cgGLGetParameter2d(CGparameter parameter, double* array);cgGLGetParameter3f(CGparameter parameter, float* array);cgGLGetParameter3d(CGparameter parameter, double* array);cgGLGetParameter4f(CGparameter parameter, double* array);cgGLGetParameter4d(CGparameter parameter, type* array);//设置统一的矩阵参数void cgGLSetMatrixParameterfr(CGparameter parameter, const float* matrix);void cgGLSetMatrixParameterfc(CGparameter parameter, const float* matrix);void cgGLSetMatrixParameterdr(CGparameter parameter, const double* matrix);void cgGLSetMatrixParameterdc(CGparameter parameter, const double* matrix);//相应矩阵的检索功能void cgGLGetMatrixParameterfr(CGparameter parameter, float* matrix);void cgGLGetMatrixParameterfc(CGparameter parameter, float* matrix);void cgGLGetMatrixParameterdr(CGparameter parameter, double* matrix);void cgGLGetMatrixParameterdc(CGparameter parameter, double* matrix);//获得4X4的矩阵void cgGLSetStateMatrixParameter(CGparameter parameter, GLenum stateMatrixType, GLenum transform);//这里的stateMatrixType,可能为CG_GL_MODELVIEW_MATRIX、CG_GL_PROJECTION_MATRIX、CG_GL_TEXTURE_MATRIX、CG_GL_MODELVIEW_PROJECTION_MATRIX//后面的transform可能为CG_GL_MATRIX_IDENTITY、CG_GL_MATRIX_TRANSPOSE、CG_GL_MATRIX_INVERSE、CG_GL_MATRIX_INVERSE_TRANSPOSE//设置统一标量数组,向量,和矩阵参数void cgGLSetParameterArray1f(CGparameter parameter, long startIndex, long numberOfElements,const float* array);void cgGLSetParameterArray1d(CGparameter parameter, long startIndex, long numberOfElements, const double* array);void cgGLSetParameterArray2f(CGparameter parameter, long startIndex, long numberOfElements, const float* array);void cgGLSetParameterArray2d(CGparameter parameter, long startIndex, long numberOfElements, const double* array);void cgGLSetParameterArray3f(CGparameter parameter, long startIndex, long numberOfElements, const float* array);void cgGLSetParameterArray3d(CGparameter parameter, long startIndex, long numberOfElements, const double* array);void cgGLSetParameterArray4f(CGparameter parameter, long startIndex, long numberOfElements, const float* array);void cgGLSetParameterArray4d(CGparameter parameter, long startIndex, long numberOfElements, const double* array);//相应的检索void cgGLGetParameterArray1f(CGparameter parameter, long startIndex, long numberOfElements, float* array);void cgGLGetParameterArray1d(CGparameter parameter, long startIndex, long numberOfElements, double* array);void cgGLGetParameterArray2f(CGparameter parameter, long startIndex, long numberOfElements, float* array);void cgGLGetParameterArray2d(CGparameter parameter, long startIndex, long numberOfElements, double* array);void cgGLGetParameterArray3f(CGparameter parameter, long startIndex, long numberOfElements, float* array);void cgGLGetParameterArray3d(CGparameter parameter, long startIndex, long numberOfElements, double* array);void cgGLGetParameterArray4f(CGparameter parameter, long startIndex, long numberOfElements, float* array);void cgGLGetParameterArray4d(CGparameter parameter, long startIndex, long numberOfElements, double* array);//类似的功能设置矩阵数组void cgGLSetMatrixParameterArrayfr(CGparameter parameter, long startIndex, long numberOfElements, const float* array);void cgGLSetMatrixParameterArrayfc(CGparameter parameter, long startIndex, long numberOfElements, const float* array);void cgGLSetMatrixParameterArraydc(CGparameter parameter, long startIndex, long numberOfElements, const double* array);void cgGLSetMatrixParameterArraydc(CGparameter parameter, long startIndex, long numberOfElements, const double* array);//检索void cgGLGetMatrixParameterArrayfr(CGparameter parameter, long startIndex, long numberOfElements, float* array);void cgGLGetMatrixParameterArrayfc(CGparameter parameter, long startIndex, long numberOfElements, float* array);void cgGLGetMatrixParameterArraydc(CGparameter parameter, long startIndex, long numberOfElements, double* array);void cgGLGetMatrixParameterArraydc(CGparameter parameter, long startIndex, long numberOfElements, double* array);//这里的c和r后缀其实是行column和列row//设置不同的参数void cgGLSetParameterPointer(CGparameter parameter, GLint size, GLenum type, GLsizei stride, GLvoid* array);  //第一步void cgGLEnableClientState(CGparameter parameter); //第二步void cgGLDisableClientState(CGparameter parameter); //逆第二步。。。//设置单一参数void cgGLSetTextureParameter(CGparameter parameter, GLuint textureName);//第一步void cgGLSetManageTextureParameters(CGcontext context, CGbool enable); //第二步void cgGLEnableTextureParameter(CGparameter parameter);//第三步void cgGLDisableTextureParameter(CGparameter parameter);//逆第三步GLuint cgGLGetTextureParameter(CGparameter parameter);//检索物件GLenum cgGLGetTextureEnum(CGparameter parameter); //检索枚举器

OpenGL Profile Support配置文件支持

        一个方便的方法拿最有用的属性文件针对顶点或者片段程序:

CGprofile cgGLGetLatestProfile(CGGLenum profileType);void cgGLSetOptimalOptions(CGprofile profile);//优化编译

OpenGL Program Execution程序运行

       过程很简单如下:(*为可选项)

void cgGLLoadProgram(CGprogram program); //所以程序先必须读取void cgGLEnableProfile(CGprofile profile); // 配置文件启用void cgGLDisableProfile(CGprofile profile);//配置文件不启用*void cgGLBindProgram(CGprogram program); //绑定配置文件CGbool cgGLIsProfileSupported(CGprofile profile);//判断配置文件是否支持*

OpenGL Program Examples程序实例

// VertexProgram.cg 顶点程序void VertexProgram(in float4 position : POSITION,  in float4 color : COLOR0,in float4 texCoord : TEXCOORD0,  out float4 positionO : POSITION,out float4 colorO : COLOR0, out float4 texCoordO : TEXCOORD0,const uniform float4x4 ModelViewMatrix ){positionO = mul(position, ModelViewMatrix);colorO = color;texCoordO = texCoord;}// FragmentProgram.cg 片段程序void FragmentProgram(in float4 color : COLOR0, in float4 texCoord : TEXCOORD0,out float4 colorO : COLOR0, const uniform sampler2D BaseTexture,const uniform float4 SomeColor){colorO = color * tex2D(BaseTexture, texCoord) + SomeColor;}// OpenGL Application OpenGL应用#include <cg/cg.h>#include <cg/cgGL.h>float* vertexPositions; // Initialized somewhere else别的地方初始化float* vertexColors; // Initialized somewhere elsefloat* vertexTexCoords; // Initialized somewhere elseGLuint texture; // Initialized somewhere elsefloat constantColor[]; // Initialized somewhere elseCGcontext context;CGprogram vertexProgram, fragmentProgram;CGprofile vertexProfile, fragmentProfile;CGparameter position, color, texCoord, baseTexture, someColor,modelViewMatrix;// Called at initialization初始化void CgGLInit(){// Create context 创建连接context = cgCreateContext();// Initialize profiles and compiler options初始化配置文件和编译器vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);cgGLSetOptimalOptions(vertexProfile);fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);cgGLSetOptimalOptions(fragmentProfile);// Create the vertex program创建顶点程序vertexProgram = cgCreateProgramFromFile(context, CG_SOURCE, "VertexProgram.cg", vertexProfile, "VertexProgram", 0);// Load the program读取程序cgGLLoadProgram(vertexProgram);// Create the fragment program创建片段程序fragmentProgram = cgCreateProgramFromFile(context, CG_SOURCE, "FragmentProgram.cg", fragmentProfile, "FragmentProgram", 0);// Load the program读取程序cgGLLoadProgram(fragmentProgram);// Grab some parameters.抓取一些参数position = cgGetNamedParameter(vertexProgram, "position");color = cgGetNamedParameter(vertexProgram, "color");texCoord = cgGetNamedParameter(vertexProgram, "texCoord");modelViewMatrix = cgGetNamedParameter(vertexProgram,"ModelViewMatrix");baseTexture = cgGetNamedParameter(fragmentProgram,"BaseTexture");someColor = cgGetNamedParameter(fragmentProgram, "SomeColor");// Set parameters that don't change:设置参数不再改变// They can be set only once because of parameter shadowing.设置映射cgGLSetTextureParameter(baseTexture, texture);cgGLSetParameter4fv(someColor, constantColor);}// Called to render the scene 打开渲染场景void Display(){// Set the varying parameters设置不同参数cgGLEnableClientState(position);cgGLSetParameterPointer(position, 3, GL_FLOAT, 0, vertexPositions);cgGLEnableClientState(color);cgGLSetParameterPointer(color, 1, GL_FLOAT, 0, vertexColors);cgGLEnableClientState(texCoord);cgGLSetParameterPointer(texCoord, 2, GL_FLOAT, 0, vertexTexCoords);// Set the uniform parameters that change every frame设置统一参数每帧变化cgGLSetStateMatrixParameter(modelViewMatrix,CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);// Enable the profiles打开配置文件cgGLEnableProfile(vertexProfile);cgGLEnableProfile(fragmentProfile);// Bind the programs绑定配置文件cgGLBindProgram(vertexProgram);cgGLBindProgram(fragmentProgram);// Enable texture纹理可用cgGLEnableTextureParameter(baseTexture);// Draw scene 画场景// ...// Disable texture纹理不可用cgGLDisableTextureParameter(baseTexture);// Disable the profiles关闭配置文件cgGLDisableProfile(vertexProfile);cgGLDisableProfile(fragmentProfile);// Set the varying parameters设置不同参数状态cgGLDisableClientState(position);cgGLDisableClientState(color);cgGLDisableClientState(texCoord);}// Called before application shuts down 当程序关闭时响应void CgShutdown(){// This frees any runtime resource.释放所有资源cgDestroyContext(context);}

OpenGL Error Reporting错误报告

         通过glGetError()方法得到错误报告,一般返回错误有:

         CG_PROGRAM_LOAD_ERROR

         CG_PROGRAM_BIND_ERROR

         CG_PROGRAM_NOT_LOADED_ERROR

         CG_UNSUPPORTED_GL_EXTENSION_ERROR



Direct3D Cg Runtime

         这个Direct3D Cgruntime包含两个接口:

         低配:此接口没有Direct3D自称,当你喜欢保持Direct3D代码在应用中。

         高配:此接口提供了所需的提高程序,参数管理,当你喜欢用Cg runtime 管理Direct3D着色器的时候。

         羽化个人认为高低配置比较适合这两个接口的区别。

 

Direct3D Minimal Interface低配接口

       提供一些方便的功能,把一些信息数据提供给核心运算,再把信息特征送到Direct3D。

Vertex Declaration 顶点声明

         在Direct3D中你必须提供一个顶点声明用来映射一张表在顶点着色器输入寄存器和应用程序数据流之间。

         一个数据流是一个基础的数组数据结构,每一个结构是一个特殊的类型称为顶点格式流,这里有一个顶点声明的例子,对应Direct3D 9:

//Direct3D 9const D3DVERTEXELEMENT9 declaration[] = {{ 0, 0 * sizeof(float),D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION, 0 }, // Position{ 0, 3 * sizeof(float),D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL, 0 }, // Normal{ 0, 8 * sizeof(float),D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD, 0 }, // Base texture{ 1, 0 * sizeof(float),D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD, 1 }, // TangentD3DD3CL_END()};

         两个声明都告诉Direct3Druntime去寻找:

(1)      顶点坐标在“流0”中,作为第一个3个浮点值的顶点格式。

(2)      法线座位下一个3个浮点值紧随“流0”的3个浮点值。

(3)      贴图坐标作为两个浮点数据用作偏移量相当于一个DWORD的两倍尺寸,在法线数据结尾,在“流0”中。

切线提供在“流1”中作为第二个贴图坐标,被作为第一个3个浮点值的顶点格式。

//Direct3D 9CGbool cgD3D9GetVertexDeclaration(CGprogram program,D3DVERTEXELEMENT9 declaration[MAXD3DDECLLENGTH]);//MAXD3DDECLLENGTH 是Direct3D 9的常量,给Direct3 0声明的最大长度,如果程序中没有得到声明,会返回一个CG_FALSE//返回值对于以下程序void main(in float4 position : POSITION,in float4 color : COLOR0,in float4 texCoord : TEXCOORD0,out float4 hpos : POSITION){ }//等同于 Direct3D 9 Cg runtimeconst D3DVERTEXELEMENT9 declaration[] = {{ 0, 0 * sizeof(float),D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION, 0 },{ 0, 4 * sizeof(float),D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR, 0 },{ 0, 8 * sizeof(float),D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD, 0 },D3DD3CL_END()};//测试是否兼容程序CGbool cgD3D9ValidateVertexDeclaration(CGprogram program,const D3DVERTEXELEMENT9* declaration);   //Direct 9 CGbool cgD3D8ValidateVertexDeclaration(CGprogram program,const DWORD* declaration);  //Direct 8 //有效声明例如:void main(float4 position : POSITION,float4 color : COLOR0,float4 texCoord : TEXCOORD0){ }//等同于 Derect3D 9const D3DVERTEXELEMENT9 declaration[] = {{ 0, 0 * sizeof(float),D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION, 0 },{ 0, 3 * sizeof(float),D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR, 0 },{ 1, 4 * sizeof(float),D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD, 0 },D3DD3CL_END()};//以上声明也可以写为const D3DVERTEXELEMENT9 declaration[] = {{ 0, 0 * sizeof(float),D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,cgD3D9ResourceToDeclUsage(CG_POSITION), 0 },{ 0, 3 * sizeof(float),D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,cgD3D9ResourceToDeclUsage(CG_COLOR0), 0 },{ 1, 4 * sizeof(float),D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,cgD3D9ResourceToDeclUsage(CG_TEXCOORD0), 0 },D3DD3CL_END()};//如果这么做的话 这个将一个CGresource枚举到一个输入缓存器中BYTE cgD3D9ResourceToDeclUsage(CGresource resource);//写顶点说明必须根据程序参数来,减少引用语义CGparameter position = cgGetNamedParameter(program, "position");CGparameter color = cgGetNamedParameter(program, "color");CGparameter texCoord = cgGetNamedParameter(program, "texCoord");const D3DVERTEXELEMENT9 declaration[] = {{ 0, 0 * sizeof(float),D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,cgD3D9ResourceToDeclUsage(cgGetParameterResource(position)),cgGetParameterResourceIndex(position) },{ 0, 3 * sizeof(float),D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,cgD3D9ResourceToDeclUsage(cgGetParameterResource(color)),cgGetParameterResourceIndex(color) },{ 1, 4 * sizeof(float),D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,cgD3D9ResourceToDeclUsage(cgGetParameterResource(texCoord)),cgGetParameterResourceIndex(texCoord) },D3DD3CL_END()};//检索DWORD cgD3D9TypeToSize(CGtype type);

Minimal Interface ProgramExamples 低端接口程序实例

//Vertex Program 顶点程序void VertexProgram(in float4 position : POSITION,in float4 color : COLOR0,in float4 texCoord : TEXCOORD0,out float4 positionO : POSITION,out float4 colorO : COLOR0,out float4 texCoordO : TEXCOORD0,const uniform float4x4 ModelViewMatrix){positionO = mul(position, ModelViewMatrix);colorO = color;texCoordO = texCoord;}//Fragment Program 片段程序void FragmentProgram(in float4 color : COLOR0,in float4 texCoord : TEXCOORD0,out float4 colorO : COLOR0,const uniform sampler2D BaseTexture,const uniform float4 SomeColor){colorO = color * tex2D(BaseTexture, texCoord) + SomeColor;}//Direct3D 9 Application DX9应用#include <cg/cg.h>#include <cg/cgD3D9.h>IDirect3DDevice9* device; // Initialized somewhere else 别处初始化IDirect3DTexture9* texture; // Initialized somewhere elseD3DXMATRIX matrix; // Initialized somewhere elseD3DXCOLOR constantColor; // Initialized somewhere elseCGcontext context;CGprogram vertexProgram, fragmentProgram;IDirect3DVertexDeclaration9* vertexDeclaration;IDirect3DVertexShader9* vertexShader;IDirect3DPixelShader9* pixelShader;CGparameter baseTexture, someColor, modelViewMatrix;// Called at application startup 应用启动void OnStartup(){// Create context 创建contextcontext = cgCreateContext();}// Called whenever the Direct3D device needs to be created 启动当Direct3D设备需要创建的时候void OnCreateDevice(){// Create the vertex shader 创建顶点着色器vertexProgram = cgCreateProgramFromFile(context, CG_SOURCE,"VertexProgram.cg", CG_PROFILE_VS_2_0, "VertexProgram", 0);CComPtr<ID3DXBuffer> byteCode;const char* progSrc = cgGetProgramString(vertexProgram, CG_COMPILED_PROGRAM);D3DXAssembleShader(progSrc, strlen(progSrc), 0, 0, 0, &byteCode, 0);// If your program uses explicit binding semantics (like this one), you can create a vertex declaration using those semantics.如果程序使用明确的约束语义,可以创建一个顶点声明来使用这些语义const D3DVERTEXELEMENT9 declaration[] = {{ 0, 0 * sizeof(float),D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION, 0 },{ 0, 3 * sizeof(float),D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR, 0 },{ 0, 4 * sizeof(float),D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD, 0 },D3DD3CL_END()};// Make sure the resulting declaration is compatible with the shader. This is really just a sanity check. 确保创建的声明是兼容的,这里是一个健全的检查assert(cgD3D9ValidateVertexDeclaration(vertexProgram, declaration));device->CreateVertexDeclaration(declaration, &vertexDeclaration);device->CreateVertexShader(byteCode->GetBufferPointer(), &vertexShader);// Create the pixel shader.创建像素着色器fragmentProgram = cgCreateProgramFromFile(context,CG_SOURCE, "FragmentProgram.cg",CG_PROFILE_PS_2_0, "FragmentProgram", 0);{CComPtr<ID3DXBuffer> byteCode;const char* progSrc = cgGetProgramString(fragmentProgram, CG_COMPILED_PROGRAM);D3DXAssembleShader(progSrc, strlen(progSrc), 0, 0, 0, &byteCode, 0);device->CreatePixelShader(byteCode->GetBufferPointer(), &pixelShader)}// Grab some parameters. 获取一些参数modelViewMatrix = cgGetNamedParameter(vertexProgram, "ModelViewMatrix");baseTexture = cgGetNamedParameter(fragmentProgram, "BaseTexture");someColor = cgGetNamedParameter(fragmentProgram, "SomeColor");// Sanity check that parameters have the expected size 检查参数的预期大小assert(cgD3D9TypeToSize(cgGetParameterType(modelViewMatrix)) == 16);assert(cgD3D9TypeToSize(cgGetParameterType(someColor)) == 4);}// Called to render the scene 渲染场景void OnRender(){// Get the Direct3D resource locations for parameters This can be done earlier and saved 早期获取Direct3D资源参数保存DWORD modelViewMatrixRegister = cgGetParameterResourceIndex(modelViewMatrix);DWORD baseTextureUnit = cgGetParameterResourceIndex(baseTexture);DWORD someColorRegister = cgGetParameterResourceIndex(someColor);// Set the Direct3D state.设置Direct3D状态device->SetVertexShaderConstantF(modelViewMatrixRegister, &matrix, 4);device->SetPixelShaderConstantF(someColorRegister, &constantColor, 1);device->SetVertexDeclaration(vertexDeclaration);device->SetTexture(baseTextureUnit, texture);device->SetVertexShader(vertexShader);device->SetPixelShader(pixelShader);// Draw scene.// ...}// Called before the device changes or is destroyed调用在设备改变或者终止之前void OnDestroyDevice() {vertexShader->Release();pixelShader->Release();vertexDeclaration->Release();}// Called before application shuts down调用在程序关闭之前void OnShutdown() {// This frees any core runtime resources. The minimal interface has no dynamic storage to free.释放所有资源,低配接口没用动态资源释放cgDestroyContext(context);}

 

Direct3D Expanded Interface 高配接口

       如果你想使用高配接口,尽量避免那些意外的错误,明确按照高配接口的相关着色器操作来执行,如着色器设定,着色器活化和参数设定包括设置纹理状态。

//设置Direct3D设备HRESULT cgD3D9SetDevice(IDirect3DDevice9* device);//获得当前设备关联IDirect3DDevice9* cgD3D9GetDevice();//丢失设备时IDirect3DDevice9* device; // Initialized elsewhereIDirect3DTexture9* myDefaultPoolTexture;CGprogram program;void OneTimeLoadScene(){// Load the program with cgD3D9LoadProgram and enable parameter shadowing读取程序和启动映射/* ... */cgD3D9LoadProgram(program, TRUE, 0, 0, 0);/* ... */// Bind sampler parameter 绑定采样参数GCparameter parameter;parameter = cgGetParameterByName(program, "MySampler");cgD3D9SetTexture(parameter, myDefaultPoolTexture);}void OnLostDevice(){// First release all necessary resources 第一释放所有所需资源PrepareForReset();// Next actually reset the Direct3D device下一步重新设置设备device->Reset( /* ... */ );// Finally recreate all those resource最后重建资源OnReset();}void PrepareForReset(){/* ... */// Release expanded interface reference释放高配接口关联cgD3D9SetTexture(mySampler, 0);// Release local reference and any other references to the texture释放本地关联和其他任何与纹理有关的关联myDefaultPoolTexture->Release();/* ... */}void OnReset(){// Recreate myDefaultPoolTexture in D3DPOOL_DEFAULT重建纹理池/* ... */// Since the texture was just recreated,it must be re-bound to the parameter再现纹理必须重新绑定参数GCparameter parameter;parameter = cgGetParameterByName(prog, "MySampler");cgD3D9SetTexture(mySampler, myDefaultPoolTexture);/* ... */}//提供参数类型HRESULT cgD3D9SetUniform(CGparameter parameter, const void* value);D3DXVECTOR3 vectorData(1,2,3);float matrixData[2][3] = {{1, 2, 3}, {4, 5, 6}};float arrayData[3][2][2] ={{{1, 2}, {3, 4}},{{5, 6},{7,8}}, {{9, 10}, {11, 12}}};cgD3D9SetUniform(vectorParam, &vectorData);cgD3D9SetUniform(matrixParam, matrixData);cgD3D9SetUniform(arrayParam, arrayData);HRESULT cgD3D9SetUniformMatrix(CGparameter parameter, const D3DMATRIX* matrix);D3DXMATRIX matrix(1, 1, 1, 0,1, 1, 1, 0,0, 0, 0, 0,0, 0, 0, 0,);cgD3D9SetUniformMatrix(matrixParam, &matrix);//设置标量,向量矩阵参数统一数值HRESULT cgD3D9SetUniformArray(CGparameter parameter, DWORD startIndex, DWORD numberOfElements,const void* array);HRESULT cgD3D9SetUniformMatrixArray(CGparameter parameter, DWORD startIndex, DWORD numberOfElements, const D3DMATRIX* matrices);//采样参数设置HRESULT cgD3D9SetTexture(CGparameter parameter, IDirect3DBaseTexture9* texture);HRESULT cgD3D9SetSamplerState(CGparameter parameter, D3DSAMPLERSTATETYPE type, DWORD value);cgD3D9SetSamplerState(parameter, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);//纹理包设置HRESULT cgD3D9SetTextureWrapMode(CGparameter parameter, DWORD value);cgD3D9SetTextureWrapMode(parameter, D3DWRAP_U | D3DWRAP_V);//参数映射HRESULT cgD3D9EnableParameterShadowing(CGprogram program, CGbool enable);//是否启用映射CGbool cgD3D9IsParameterShadowingEnabled(CGprogam program);//高配接口程序执行HRESULT cgD3D9LoadProgram(CGprogram program, CG_BOOL parameterShadowingEnabled,DWORD assembleFlags);HRESULT hresult = cgD3D9LoadProgram(vertexProgram, TRUE, D3DXASM_DEBUG);HRESULT hresult = cgD3D9LoadProgram(fragmentProgram, TRUE, 0);//释放程序HRESULT cgD3D9UnloadProgam(CGprogram program);//绑定程序HRESULT cgD3D9BindProgram(CGprogram program);//高配接口配置文件CGprofile cgD3D9GetLatestVertexProfile();CGprofile cgD3D9GetLatestPixelProfile();//返回最佳的编译选项给一个配置文件char const* cgD3D9GetOptimalOptions(CGprofile profile);//高配接口程序实例//VertexProgram.cgvoid VertexProgram(in float4 position : POSITION,in float4 color : COLOR0,in float4 texCoord : TEXCOORD0,out float4 positionO : POSITION,out float4 colorO : COLOR0,out float4 texCoordO : TEXCOORD0,const uniform float4x4 ModelViewMatrix){positionO = mul(position, ModelViewMatrix);colorO = color;texCoordO = texCoord; }//FragmentProgram.cgvoid FragmentProgram(in float4 color : COLOR0,in float4 texCoord : TEXCOORD0,out float4 colorO : COLOR0,const uniform sampler2D BaseTexture,const uniform float4 SomeColor){colorO = color * tex2D(BaseTexture, texCoord) + SomeColor;}//Direct3D 9 应用程序#include <cg/cg.h>#include <cg/cgD3D9.h>IDirect3DDevice9* device; // Initialized somewhere else 别处初始化IDirect3DTexture9* texture; // Initialized somewhere elseD3DXCOLOR constantColor; // Initialized somewhere elseCGcontext context;IDirect3DVertexDeclaration9* vertexDeclaration;CGprogram vertexProgram, fragmentProgram;CGparameter baseTexture, someColor, modelViewMatrix;// Called at application startup 应用打开时调用void OnStartup(){// Create context 创建连接context = cgCreateContext();}// Called whenever the Direct3D device needs to be created设备连接时调用void OnCreateDevice(){// Pass the Direct3D device to the expanded interface.把高配接口传给设备cgD3D9SetDevice(device);// Determine the best profiles to use确定最佳配置文件CGprofile vertexProfile = cgD3D9GetLatestVertexProfile();CGprofile pixelProfile = cgD3D9GetLatestPixelProfile();// Grab the optimal options for each profile.获取配置文件的最佳选择const char* vertexOptions[] = {cgD3D9GetOptimalOptions(vertexProfile), 0 };const char* pixelOptions[] = { cgD3D9GetOptimalOptions(pixelProfile), 0 };// Create the vertex shader.创建顶点着色器vertexProgram = cgCreateProgramFromFile(context, CG_SOURCE, "VertexProgram.cg",vertexProfile, "VertexProgram", vertexOptions);// If your program uses explicit binding semantics, you can create a vertex declaration using those semantics.如果你的程序使用明确的约束语义,可以创建一个顶点声明使用这些语义const D3DVERTEXELEMENT9 declaration[] = {{ 0, 0 * sizeof(float),D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION, 0 },{ 0, 3 * sizeof(float),D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR, 0 },{ 0, 4 * sizeof(float),D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD, 0 },D3DD3CL_END()};// Ensure the resulting declaration is compatible with the shader. This is really just a sanity check. 确保结果声明通过着色器完成,已经通过完全检查assert(cgD3D9ValidateVertexDeclaration(vertexProgram, declaration));device->CreateVertexDeclaration(declaration, &vertexDeclaration);// Load the program with the expanded interface. Parameter shadowing is enabled (second parameter = TRUE).从高配接口读取程序,参数映射启用。cgD3D9LoadProgram(vertexProgram, TRUE, 0);// Create the pixel shader.创建像素着色器fragmentProgram = cgCreateProgramFromFile( context, CG_SOURCE, "FragmentProgram.cg", pixelProfile, "FragmentProgram", pixelOptions);// Load the program with the expanded interface. Parameter shadowing is enabled (second parameter = TRUE). Ignore vertex shader specifc flags, such as declaration usage. .从高配接口读取程序,参数映射启用,忽略顶点着色器特殊标志,就像使用声明。cgD3D9LoadProgram(fragmentProgram, TRUE, 0);// Grab some parameters.获取参数modelViewMatrix = cgGetNamedParameter(vertexProgram, "ModelViewMatrix");baseTexture = cgGetNamedParameter(fragmentProgram,"BaseTexture");someColor = cgGetNamedParameter(fragmentProgram, "SomeColor");// Sanity check that parameters have the expected size明确检查参数的预期大小assert(cgD3D9TypeToSize(cgGetParameterType(modelViewMatrix)) == 16);assert(cgD3D9TypeToSize(cgGetParameterType(someColor))== 4);// Set parameters that don't change. They can be set only once since parameter shadowing is enabled 设置参数不能改变,他们设置只能参数绑定启用时cgD3D9SetTexture(baseTexture, texture);cgD3D9SetUniform(someColor, &constantColor);}// Called to render the scene渲染场景时调用void OnRender(){// Load model-view matrix.读取可视模型矩阵D3DXMATRIX modelViewMatrix;// ...// Set the parameters that change every frame This must be done before binding the programs 设定每帧参数修改,在绑定程序之前cgD3D9SetUniformMatrix(modelViewMatrix, &modelViewMatrix);// Set the vertex declaration设置顶顶声明device->SetVertexDeclaration(vertexDeclaration);// Bind the programs. This downloads any parameter values that have been previously set.绑定程序,下载先前设定的参数cgD3D9BindProgram(vertexProgram);cgD3D9BindProgram(fragmentProgram);// Draw scene.绘制场景// ...}// Called before the device changes or is destroyed 设备改变或终止时调用void OnDestroyDevice(){// Calling this function tells the expanded interface to release its internal reference to the Direct3D device and free its Direct3D resources. 释放高配接口的内部关联对Direct3D设备和资源。cgD3D9SetDevice(0);}// Called before application shuts down 应用关闭时调用void OnShutdown(){// This frees any core runtime resource.释放核心资源cgDestroyContext(context);}

 

Direct3D Debugging Mode 调试模式

         使用Debug DLL:

1.      连接应用程序到cgD3D9d.lib代替cgD3D9.lib。

2.      确定应用能找到cgD3D9d.dll。

3.      打开或者关闭跟踪代码

void cgD3D9EnableDebugTracing(CGbool enable);

         这里有一个例子

cgD3D9EnableDebugTracing(CG_TRUE);// ...// Application code that is traced// ...cgD3D9EnableDebugTracing(CG_FALSE);

        

         常见错误类型:

         CGerror:

                  cgD3D9Failed

             cgD3D9DebugTrace

          HRESULT:

             CGD3D9ERR_INVALIDPARAM

             CGD3D9ERR_INVALIDPROFILE

             CGD3D9ERR_INVALIDSAMPLERSTATE

             CGD3D9ERR_INVALIDVEREXDECL

             CGD3D9ERR_NODEVICE

             CGD3D9ERR_NOTMATRIX

             CGD3D9ERR_NOTLOADED

             CGD3D9ERR_NOTSAMPLER

             CGD3D9ERR_NOTUNIFORM

             CGD3D9ERR_NULLVALUE

             CGD3D9ERR_OUTOFRANGE

             CGD3D9_INVALID_REG

 

    测试错误

HRESULT cgD3D9GetLastError();const char* cgD3D9TranslateHRESULT(HRESULT hr);//转换成字符串

   

    错误回调

void MyErrorCallback() {CGerror error = cgGetError();if (error == cgD3D9DebugTrace) {// This is a debug trace output.// A breakpoint could be set here to step from one// debug output to the other.return;}char buffer[1024];if (error == cgD3D9Failed)sprintf(buffer, "A Direct3D error occurred: %s'\n",cgD3D9TranslateHRESULT(cgD3D9GetLastError()));elsesprintf(buffer, "A Cg error occurred: '%s'\n",cgD3D9TranslateCGerror(error));OutputDebugString(buffer);}cgSetErrorCallback(MyErrorCallback);


下期预告:

         Thinking in Shader(6)


原创粉丝点击