Cg and the GPU - Gammeter.com

Λογισμικό & κατασκευή λογ/κού

2 Δεκ 2013 (πριν από 4 χρόνια και 7 μήνες)

89 εμφανίσεις

Old
-
school,
General
Purpose Use
of the GPU
for
Everything,
But …

Originally, Customizable Shaders were
Written in Assembly or a Specialized Vector
Languages.

C for Graphics is a high
-
level GPU shader
language designed, developed and
implemented by NVIDIA.

Simple C Syntax compiles out to assembly,
GLSL or HLSL code, in various formats, for
many versions of DirectX and OpenGL.

Constructors, e.g. float4 v = float4(
a,b,c,d
);

Array Operator, e.g. v[0], v[1], v[2], or v[3]

Swizzle Operator Can Reorder Data:

e.g. v.xyz,
v.xxxz
, v.yyx,
v.yx
,
v.xyzw

Replaceable with
rgba

instead of
xyzw

Vectorized

Primitives: float2, float3, float4

16
-
bit Floating Point Constructs: half, half2, …

Fixed Precision Decimals: fixed, fixed2, …

Matrices are Compounded Vector Classes,
e.g. float4x4, and are Constructed with
multiple vectors

float4 v = float4(
a,b,c,d
);

float4x4 m = float4x4(
v,v,v,v
);

Samplers Texture Data Type

sampler1D, sampler2D,
samplerRECT
, sampler3D

samplerRECT
: Same as sampler2D but uses pixel
locations as texture coordinates instead of [0,1]

struct

C2E1v_Output

{

float4 position : POSITION;

float4 color : COLOR;

};

C2E1v_Output C2E1v_green(float2 position : POSITION)

{

C2E1v_Output OUT;

OUT.position

= float4(position, 0, 1);

OUT.color

= float4(0, 1, 0, 1); // RGBA green

return OUT;

}

struct

C2E2f_Output

{

float4 color : COLOR;

};

C2E2f_Output C2E2f_passthrough(float4 color : COLOR)

{

C2E2f_Output OUT;

OUT.color

= color;

return OUT;

}

CPU

GPU

CPU

GPU

void

shScene
::
GPU_CreateTextureDataForModel
(
shObject

*
oi

) {

// determine the texture dimensions

modelTexColumnCount

=
numDataFromModel
*
floatArraySize
;

//formalize the texture's
modelHeight

and
modelWidth

modelWidth

=
numDataFromModel
;
//number of data pieces to store wide

modelHeight

=
oi
-
>
NList.size
;
//number of nodes to store high

modelTexSize

=
modelWidth
*
modelHeight
*
floatArraySize
;

textureData

=
new

float
[
modelTexSize
];

//Copy all the data from the cloth to the texture

int

i

= 0;

float

* position =
new

float

[
floatArraySize
];

float

* velocity =
new

float

[
floatArraySize
];

for
( node *
currentNode

=
oi
-
>
NList.head
;
currentNode

!= NULL;

currentNode

=
currentNode
-
>next ) {

currentNode
-
>
getPosition
(position);

//Model Data: 0
-
pos, 1
-
force, 2
-
vel

for
(
int

j = 0; j <
floatArraySize
; j++ ) {

textureData
[
i+j
] = position[j];

textureData
[
i+j+floatArraySize
] = 0.0f;
//force

textureData
[i+j+2*
floatArraySize
] = 0.0f;

}

i
+=
modelTexColumnCount
;

}

free(position);

}

void

shScene
::
GPU_ExecuteGPGPU
(
CGprogram

fragmentProgram
,
GLuint

springData
,
int

springIndex

)

{

//Prepare Frame Buffer Object (FBO)

glBindFramebufferEXT
( GL_FRAMEBUFFER_EXT,
GPUFrameBuffer

);

if
(
texSwap

) {
// Bind output texture

glDrawBuffer
( GL_COLOR_ATTACHMENT1_EXT );

}
else {

// Bind output texture

glDrawBuffer
( GL_COLOR_ATTACHMENT0_EXT );

}

// get ready to run this specific fragment program

cgGLBindProgram
(
fragmentProgram
);

cgGLEnableProfile
(
cgFragmentProfile
);

// Create and enable the TEXTURE parameter for the fragment program

cgTexture0 =
cgGetNamedParameter
(
fragmentProgram
,
"
modelData
"
);

if
(
texSwap

){

cgGLSetTextureParameter
(cgTexture0,

m_imageLoader
-
>
m_itexNum
[GPU_Data_Texture_0]);

}
else {

cgGLSetTextureParameter
(cgTexture0,

m_imageLoader
-
>
m_itexNum
[GPU_Data_Texture_1]);

}

cgGLEnableTextureParameter
(cgTexture0);

[
continued below …
]

}

void

shScene
::
GPU_ExecuteGPGPU
(
CGprogram

fragmentProgram
,
GLuint

springData
,

int

springIndex

)

{

[
continued from above …
]

//enable additional custom options

if
(
fragmentProgram

==
cgCalculateSpringForcesOnGPU

) {

// Create and enable the STANDARD parameters for the fragment program

cgTextureSpringIndex

=
cgGetNamedParameter
(
fragmentProgram
,
"
springIndex
"
);

cgGLSetParameter1f(
cgTextureSpringIndex
,
springIndex
);

// Create and enable the TEXTURE parameter for the fragment program

cgTexture1 =
cgGetNamedParameter
(
fragmentProgram
,
"
springData
"
);

cgGLSetTextureParameter
(cgTexture1,
m_imageLoader
-
>
m_itexNum
[
springData
]);

cgGLEnableTextureParameter
(cgTexture1);

}
else

if
(
fragmentProgram

==
cgUpdateVelocityOnGPU

) {

// Create and enable the STANDARD parameters for the fragment program

cgEnforceFixedNode

=
cgGetNamedParameter
(
fragmentProgram
,
"
enforceFixed
"
);

//static for now, make this dynamic later

cgGLSetParameter1f(
cgEnforceFixedNode
, 1.0f);

}

// Render the Texture to the Buffer on a Simple Quad

GPU_WriteQuadAndTextureToBuffer
(
modelWidth
,
modelHeight
);

// Disable the Texture Parameter for this specific Fragment Program

cgGLDisableTextureParameter
(cgTexture0);

if
(
fragmentProgram

==
cgCalculateSpringForcesOnGPU

)

cgGLDisableTextureParameter
(cgTexture1);

cgGLDisableProfile
(
cgFragmentProfile
);

texSwap

= !
texSwap
;

}

//Fragment Program used to add gravity force to Y force vector

Fragment_Output

CalculateGravityForcesOnGPU
(

float2
textCoord

: TEXCOORD0, uniform
samplerRECT

modelData

)

{

//simply pass the data through if not force fragment

Fragment_Output

OUT;

OUT.color

=
texRECT
(
modelData
,
textCoord

);

//Model Data: 0
-
position, 1
-
force, 2
-
velocity

if
(
CorrectFragment
(
textCoord.x
, FORCE_5f ) )

{

//we are at the force position, index set by adding 2

OUT.color

+= MASS*
gravityVector
;
//F=MA

}

return

OUT;

}

void

shScene
::
GPU_RestoreDataFromTexture
(
shObject

*
oi

)

{

glBindFramebufferEXT
( GL_FRAMEBUFFER_EXT, 0 );

//Restore render buffer

float

* texture =
new

float
[
modelTexSize
];

if
( RESET_MODEL ) {
// Reset texture data on the graphics card with original text

glBindTexture
( GL_TEXTURE_RECTANGLE_NV,

m_imageLoader
-
>
m_itexNum
[
GPU_Data_Texture_RESET
] );

RESET_MODEL =
false
;
//our damage is done here

}
else

{

glBindTexture
( GL_TEXTURE_RECTANGLE_NV,

m_imageLoader
-
>
m_itexNum
[GPU_Data_Texture_1] );

}

glGetTexImage
( GL_TEXTURE_RECTANGLE_NV, 0, GL_RGB, GL_FLOAT, texture );

resize(
m_iwidth
,
m_iheight
);

// Change to PROJ

float

* position =
new

float

[
floatArraySize
];

for
( node *
currentNode

=
oi
-
>
NList.head
;
currentNode

!= NULL;

currentNode

=
currentNode
-
>next ) {

for
(
int

j = 0; j <
floatArraySize
; j++ ) {

position[j] = texture[
i+j
];

}

currentNode
-
>
setPosition
(position);

i
+=
modelTexColumnCount
;

}

glDisable
(GL_FRAGMENT_PROGRAM_NV);

//Disable our Custom GPU Rendering

glDisable
(GL_TEXTURE_RECTANGLE_NV);

}