C++ AMP图形

C++ AMP在可用于访问纹理在GPUs支持的  Concurrency::graphics 命名空间包含一些API。  一些常见的情况有:

  • 可以使用  纹理 选件类作为数据容器执行计算和利用GPU硬件纹理缓存和布局  空间的位置。  空格的位置是数据元素属性实际上是关闭相互。

  • 运行时提供有效的互操作性具有非计算着色器。  像素、顶点、tesselation和船身着色器经常使用或生成您的C++ AMP计算中使用的纹理。

  • 在C++ AMP的图像API提供替代方法来访问子Word打包的缓冲区。  具有格式由8位或16位标量组成 的texels 的纹理(纹理元素)允许对此类压缩数据存储的访问。

说明 说明

C++ AMP API不提供纹理采样和筛选功能。  在DirectCompute和HLSL必须使用C++ AMP然后编写互操作性功能代码。

norm 和  unorm 类型是限制  float 一系列值的数据类型;这称为"  夹紧。  这些类型可从其他数据类型显式构造。 在强制转换,该值首先转换为 float 然后将夹紧到由准则的单个区域[- 1.0 1.0]或… unorm允许… [0.0 1.0]。 将+/-无限返回+/- 1。 将Nan是未定义的。 准则可以从unorm隐式构造,而不是数据丢失。 浮动隐式转换运算符在这些类型定义。 二元运算符定义在这些类型和其他内置数据类型(如 float 和 int:+、-、*、/、==、!=、>、<、>=、<=。 复合赋值运算符还支持:+=、-=、*=、/=。 一元求反运算(-)为准则类型定义。

短的向量库提供一些在  向量类型 HLSL中定义且通常用于定义texels的功能。  短矢量采用表示相同类型的一到四个值的数据结构。 支持的类型是 doublefloatintnormuint和 unorm 该类型名称如下表所示。 对于不具有该名称的一个下划线的每个类型,还具有相应的 typedef 具有下划线的类型在 Concurrency::graphics 命名空间 没有下划线的类型在 Concurrency::graphics::direct3d 命名空间,以便从类似的命名基础类型明显分开例如 __int8 和 __int16

长度为2

长度为3

长度为4

double

double_2

double2

double_3

double3

double_4

double4

float

float_2

float2

float_3

float3

float_4

float4

int

int_2

int2

int_3

int3

int_4

int4

准则

norm_2

norm2

norm_3

norm3

norm_4

norm4

uint

uint_2

uint2

uint_3

uint3

uint_4

uint4

unorm

unorm_2

unorm2

unorm_3

unorm3

unorm_4

unorm4

Hh913015.collapse_all(zh-cn,VS.110).gif运算符

如果运算符已被定义两个简短的向量之间,则它还定义在短矢量图像和标量之间。  此外,其中一个必须满足的:

  • 标量的类型必须与短的向量的元素类型。

  • 通过使用用户定义的转换,标量的类型只能隐式转换为矢量的元素类型。

操作是的一个组件短矢量的每个元素和一个标量之间。  这是有效的运算符:

运算符类型

有效类型

二元运算符

有效在所有类型:+,),*,/,

有效在整数类型:%,^,|,&,<<,>>

两个矢量必须具有相同的大小,结果是相同大小的矢量。

关系运算符

有效在所有类型:==和! =

复合赋值运算符

有效在所有类型:+=,- =,*=,/=

有效在整数类型:%=,^=,|=,&=,<<=,>>=

增量和减量运算符

有效在所有类型:++,--

标题和后缀有效。

按位"取非"运算符(|)

有效在integer类型。

一元)运算符

有效在所有类型中除 unorm 和 uint

Hh913015.collapse_all(zh-cn,VS.110).gifSwizzling表达式

短的向量库支持  vector_type.identifier 访问器构造访问短矢量的元素。  identifier ,即一个 swizzling的表达式,该值指定矢量的元素。 该表达式可以是左值或r值。 在该标识符的各个字符可能是:x,y、z和w;、、、g、b和". “ x”和“r”表示零Th元素,“y”和“g”表示第一个元素,依此类推。 (“x”和“r”不能在同一标识符。)的通知因此,“rgba”和“xyzw”返回相同的结果。 单元素访问器例如“x”和“y”是标量值类型。 多格式说明符的访问器较短的向量类型。 例如,因此,如果构造名为 fourInts 并具有值2,4,6和8的 int_4 向量,然后 fourInts.y返回该整数4,并 fourInts.rg 返回具有值2和4.的 int_2 对象。

许多GPUs已优化获取像素和texels和呈现图形和纹理的硬件和缓存。  纹理<T,N> 选件类,它是texel对象的容器选件类,显示纹理功能这些GPUs。 texel可以是:

  • int 、uintfloatdoublenorm或 unorm 标量。

  • 有两个或四个元素的较短的矢量。  唯一的例外是 double_4,这是不允许的。

texture 对象可能有级别1、2或3,。  texture 对象调用lambda只能获取对 parallel_for_each 纹理在GPU存储为Direct3D纹理对象。 有关纹理和texels的更多信息。Direct3d,请 纹理介绍在Direct3D 11参见。

您使用的texel类型可能是用于图形编程多纹理格式之一。  例如,RGBA格式可以为R "、" G A、B和标量,使用32位和8位中的每个元素。 图形卡的纹理硬件可以各个元素按照以下格式的访问。 例如,如果您使用的是,RGBA格式,纹理硬件可以提取每个8位组件为32位窗体。 在C++ AMP,可以将此位设置每个您的texel的标量元素,以便您可以自动访问代码中的单个标量元素,而不必使用位转换。

Hh913015.collapse_all(zh-cn,VS.110).gif实例化的纹理Objects

可以声明纹理对象,而不会初始化。  下面的代码示例声明了纹理对象。

C++
#include <amp.h>
#include <amp_graphics.h>
using namespace concurrency;
using namespace concurrency::graphics;

void declareTextures() {

    // Create a 16-texel texture of int. 
    texture<int, 1> intTexture1(16);  
    texture<int, 1> intTexture2(extent<1>(16)); 

    // Create a 16 x 32 texture of float_2.  
    texture<float_2, 2> floatTexture1(16, 32);  
    texture<float_2, 2> floatTexture2(extent<2>(16, 32));   

    // Create a 2 x 4 x 8 texture of uint_4. 
    texture<uint_4, 3> uintTexture1(2, 4, 8);  
    texture<uint_4, 3> uintTexture2(extent<3>(2, 4, 8));
}

还可以使用构造函数声明和初始化 texture 对象。 下面的代码示例实例化 float_4 对象矢量的一 texture 对象。 位每个标量元素设置为默认值。 因为它们没有默认位每个标量元素,不能对 normunorm或 norm 和 unorm短矢量的此构造函数。

C++
#include <amp.h>
#include <amp_graphics.h>
#include <vector>
using namespace concurrency;
using namespace concurrency::graphics;

void initializeTexture() {

    std::vector<int_4> texels;
    for (int i = 0; i < 768 * 1024; i++) {
        int_4 i4(i, i, i, i);
        texels.push_back(i4);
    }
    
texture<int_4, 2> aTexture(768, 1024, texels.begin(), texels.end());
}

还可以声明和初始化 texture 对象通过在字节采用指向源数据、源数据的大小和位每个标量组件的构造函数重载。

C++
void createTextureWithBPC() {
    // Create the source data.
    float source[1024 * 2]; 
    for (int i = 0; i < 1024 * 2; i++) {
        source[i] = (float)i;
    }

    // Initialize the texture by using the size of source in bytes
    // and bits per scalar element.
    texture<float_2, 1> floatTexture(1024, source, (unsigned int)sizeof(source), 32U); 
}

在这些示例中的纹理在默认快捷键的默认视图创建。 如果要指定 accelerator_view 对象,可以使用构造函数的其他重载。 不能创建CPU快捷键的纹理对象。

如下表所示,在 texture 对象的每个维度的大小限制,。 如果超出限制,则会发生运行时错误。

纹理

范围限制

纹理<T,1>

16384

纹理<T,2>

16384

纹理<T,2>

2048

Hh913015.collapse_all(zh-cn,VS.110).gif读取纹理Objects

使用  texture::operator[] 运算符texture::operator() 运算符或  texture::get 方法,可以从  texture 对象读取。  texture::operator[] 运算符 和 texture::operator() 运算符 返回值,而不是引用。 因此,可以使用 texture::operator[] 运算符,您不能写入 texture 对象。

C++
void readTexture() {
    std::vector<int_2> src;    
    for (int i = 0; i < 16 *32; i++) {
        int_2 i2(i, i);
        src.push_back(i2);
    }

    std::vector<int_2> dst(16 * 32);  
    array_view<int_2, 2> arr(16, 32, dst);  
    arr.discard_data(); 

    const texture<int_2, 2> tex9(16, 32, src.begin(), src.end());  
    parallel_for_each(tex9.extent, [=, &tex9] (index<2> idx) restrict(amp) {          
        // Use the subscript operator.      
        arr[idx].x += tex9[idx].x; 
        // Use the function () operator.      
        arr[idx].x += tex9(idx).x; 
        // Use the get method.
        arr[idx].y += tex9.get(idx).y; 
        // Use the function () operator.  
        arr[idx].y += tex9(idx[0], idx[1]).y; 
    });  

    arr.synchronize();
}

下面的代码示例在短向量演示如何存储纹理通道,然后访问各个标量元素作为短矢量的属性。

C++
void UseBitsPerScalarElement() {
    // Create the image data. 
    // Each unsigned int (32-bit) represents four 8-bit scalar elements(r,g,b,a values).
    const int image_height = 16;
    const int image_width = 16;
    std::vector<unsigned int> image(image_height * image_width);

    extent<2> image_extent(image_height, image_width);

    // By using uint_4 and 8 bits per channel, each 8-bit channel in the data source is 
    // stored in one 32-bit component of a uint_4.
    texture<uint_4, 2> image_texture(image_extent, image.data(), image_extent.size() * 4U,  8U);

    // Use can access the RGBA values of the source data by using swizzling expressions of the uint_4.
    parallel_for_each(image_extent,  
         [&image_texture](index<2> idx) restrict(amp) 
    { 
        // 4 bytes are automatically extracted when reading.
        uint_4 color = image_texture[idx]; 
        unsigned int r = color.r; 
        unsigned int g = color.g; 
        unsigned int b = color.b; 
        unsigned int a = color.a; 
    });
}

下表列出了有效的位每个中的每一个通道排序向量类型。

纹理数据类型

有效的位每个标量元素

int,int_2,int_4

uint,uint_2,uint_4

8, 16, 32

浮点数,float_2,float_4

16, 32

二进制文件,double_2

64

准则,norm_2,norm_4

unorm,unorm_2,unorm,4

8, 16

Hh913015.collapse_all(zh-cn,VS.110).gif写入纹理Objects

使用  texture::set 方法写入  texture 对象。  纹理对象可以是只读还是可读/写的。 为纹理的对象可以读取和可写,必须满足以下条件:

  • T只有一个标量元素。  (短矢量不允许。)

  • T不是 doublenorm或 unorm

  • texture::bits_per_scalar_element 属性为32。

如果所有三个不为true,则  texture 对象只读。  前两个条件是在编译过程中检查。 生成错误,如果您尝试写入 readonly 纹理对象的代码。 texture::bits_per_scalar_element 的条件检测在运行时,因此,运行时生成 unsupported_feature 异常,如果尝试写入只读的texture 对象。

为纹理对象的下面的代码示例写入值。

C++
void writeTexture() {
    texture<int, 1> tex1(16); 
    parallel_for_each(tex1.extent, [&tex1] (index<1> idx) restrict(amp) {    
        tex1.set(idx, 0); 
    });

}

Hh913015.collapse_all(zh-cn,VS.110).gif使用writeonly_texture_view对象

writeonly_texture_view 选件类提供纹理对象的一个writeonly视图。  必须由lambda表达式的值获取 writeonly_texture_view 对象。 下面的代码示例使用编写的一 writeonly_texture_view 对象有两个元素的 texture 对象(int_2)。

C++
void write2ComponentTexture() {
    texture<int_2, 1> tex4(16); 
    writeonly_texture_view<int_2, 1> wo_tv4(tex4); 
    parallel_for_each(extent<1>(16), [=] (index<1> idx) restrict(amp) {   
        wo_tv4.set(idx, int_2(1, 1)); 
    });
}

Hh913015.collapse_all(zh-cn,VS.110).gif复制的纹理Objects

使用 复制 函数或 copy_async 功能,如下面的代码示例所示,使用能将在纹理对象之间,。

C++
void copyHostArrayToTexture() {
    // Copy from source array to texture object by using the copy function.
    float floatSource[1024 * 2]; 
    for (int i = 0; i < 1024 * 2; i++) {
        floatSource[i] = (float)i;
}
    texture<float_2, 1> floatTexture(1024);
    copy(floatSource, (unsigned int)sizeof(floatSource), floatTexture); 

    // Copy from source array to texture object by using the copy function.
    char charSource[16 * 16]; 
    for (int i = 0; i < 16 * 16; i++) {
        charSource[i] = (char)i;
    }
    texture<int, 2> charTexture(16, 16, 8U);
    copy(charSource, (unsigned int)sizeof(charSource), charTexture); 
    // Copy from texture object to source array by using the copy function.
    copy(charTexture, charSource, (unsigned int)sizeof(charSource)); 
}


使用 texture::copy_to 方法,可以从用纹理同时复制到另一个。 两纹理可以在不同的accelerator_views。 当您复制到 writeonly_texture_view 对象时,数据复制到基础 texture 对象。 位每个标量元素和该区域必须在源和目标 texture 对象上相同。 如果要求不匹配,运行时将引发异常。

C++ AMP运行时支持互操作性  texture<T,1> 之间  ID3D11Texture1D接口的集成, texture<T,2> 和  ID3D11Texture2D接口之间和  texture<T,3> 和  ID3D11Texture3D接口之间。  get_texture 方法采用 texture 对象并返回 IUnknown 接口。 make_texture 方法采用IUnknown 接口和 accelerator_view 对象并返回 texture 对象。

http://msdn.microsoft.com/zh-cn/library/hh913015

#include "graphics.h" #include "stdio.h" #include "dos.h" #include "conio.h" #include "bios.h" #include "stdlib.h" #include "math.h" #ifdef __cplusplus #define __CPPARGS ... #else #define __CPPARGS #endif #define VK_LEFT 0x4b00 #define VK_RIGHT 0x4d00 #define VK_DOWN 0x5000 #define VK_UP 0x4800 #define VK_HOME 0x4700 #define VK_END 0x4f00 #define VK_SPACE 0x3920 #define VK_ESC 0x011b #define VK_ENTER 0x1c0d #define VK_PGUP 0x4900 #define VK_PGDOWN 0x5100 #define TIMER 0x1c void drawblock(int,int,int); void nedr(void); void fk(int,int,int,int); void rewr(int,int,int,int); void rrwf(int,int); int is_bd(int,int,int); int is_line(void); void interrupt ( *oldhandler)(__CPPARGS); void KillTimer(void); void SetTimer(void interrupt (*IntProc)(__CPPARGS)); void rscore(int); int fkt[]={0,4,8,12,14,16,18}; int cj[]={0,100,300,900,1500}; long grc[]={0,3000,60000,90000,120000,150000,180000,210000,240000,270000}; int cjb[]={0,0,0,0,0,0,0,0,0,0}; char cjc[]="score: 0"; char grad[]="grade:0"; struct shape { short xy[8]; short color; short next; }; struct shape shapes[19]= { /* {x1,y1,x2,y3,x3,y3,x4,y4,color,next} */ {1,1,2,1,3,1,3,2,LIGHTBLUE,1}, /* □□□□ */ {2,2,3,0,3,1,3,2,LIGHTBLUE,1}, /* □■□□ */ {1,1,1,2,2,2,3,2,LIGHTBLUE,1}, /* □■□□ */ {2,0,2,1,2,2,3,0,LIGHTBLUE,-3}, /* □■■□ */ {1,1,1,2,2,1,3,1,LIGHTCYAN,1}, /* □□□□ */ {2,0,3,0,3,1,3,2,LIGHTCYAN,1}, /* □■■□ */ {1,2,2,2,3,1,3,2,LIGHTCYAN,1}, /* □■□□ */ {2,0,2,1,2,2,3,2,LIGHTCYAN,-3}, /* □■□□ */ {2,1,3,0,3,1,3,2,LIGHTRED,1}, /* □□□□ */ {1,2,2,1,2,2,3,2,LIGHTRED,1}, /* □□□□ */ {1,0,1,1,1,2,2,1,LIGHTRED,1}, /* □■□□ */ {1,0,2,0,2,1,3,0,LIGHTRED,-3}, /* ■■■□ */ {2,1,2,2,3,0,3,1,DARKGRAY,1}, /* □□□□ */ {1,0,2,0,2,1,3,1,DARKGRAY,-1}, /* □□□□ */ /* □■■□ */ /* ■■□□ */ {2,0,2,1,3,1,3,2,MAGENTA,1}, /* □□□□ */ {1,2,2,1,2,2,3,1,MAGENTA,-1}, /* □□□□ */ /* ■■□□ */ /* □■■□ */ {0,1,1,1,2,1,3,1,BROWN,1}, /* □■□□ */ {1,0,1,1,1,2,1,3,BROWN,-1}, /* □■□□ */ /* □■□□ */ /* □■□□ */ {2,1,2,2,3,1,3,2,YELLOW,0}, /* □□□□ */ /* □□□□ */ /* □■■□ */ /* □■■□ */ }; int stx=5,sty=8,sdx=24,sdy=18,shx=7,shy=22,adx=4,ady=1,nexti,TimerCounter=0,grade=0,end=0; unsigned long score=0; short board[25][12]= /* 方块空间表示,1表示有方块 */ { {1,1,1,1,1,1,1,1,1,1,1,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, /* 0 */ {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, /* 5 */ {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, /* 10 */ {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, 赞 0 2005-5-12 15:50 回复 218.85.57.* 2楼 {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, /* 15 */ {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, /* 20 */ }; short colable[25][12]= /* 方块空间颜色,1表示背景色蓝色*/ { {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, /* 0 */ {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, /* 5 */ {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, /* 10 */ {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, /* 15 */ {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, /* 20 */ }; void interrupt newhandler(__CPPARGS) /* 新的时钟中断处理函数 */ { TimerCounter++; oldhandler(); } void SetTimer(void interrupt (*IntProc)(__CPPARGS)) /* 设置新的时钟中断 */ { oldhandler=getvect(TIMER); disable(); setvect(TIMER,IntProc); enable(); } void KillTimer() /* 恢复原有的时钟中断处理过程 */ { disable(); setvect(TIMER,oldhandler); enable(); } void rscore(int line) /* 成绩更新函数 */ { int i,j,k=1; unsigned long s,f; score+=cj[line]; setfillstyle(1,GREEN); bar(0,5,150,30); s=score; if(s>=grc[grade]) { grade++; grad[6]=grade+48; bar(180,5,300,30); moveto(200,20); outtext(grad); } for(i=9;i>0;i--) { f=pow(10,i); j=s/f;s=s%f; if((!j)&amp;&amp;k); else k=0,cjc[15-i]=j+48; } moveto(10,20); outtext(cjc); } int is_bd(int x1,int y1,int i) /* 判断是否有方块 */ { int j,x2,y2; for(j=0;j<4;j++) { x2=shapes[i].xy[2*j]; y2=shapes[i].xy[2*j+1]; if(board[x1+x2+adx][y1+y2+ady])return 0; } return 1; } void fk(int re,int x1,int y1,int i) /* 方块的擦除、重写,并判断是否结束 有问题 */ { int j,x2,y2,color; for(j=0;j<4;j++) { x2=shapes[i].xy[2*j]; y2=shapes[i].xy[2*j+1]; if(!re) color=getbkcolor(); else color=shapes[i].color; if(re==2) { if((x1+x2)<=-1) { printf("Game is OVER!"); getch(); end=1; } break; } else { if((x1+x2)<=-1) continue; } board[x1+x2+adx][y1+y2+ady]=re; colable[x1+x2+adx][y1+y2+ady]=color; drawblock(stx+x1+x2,sty+y1+y2,color); } /* getch(); */ } void drawblock(int x,int y,int color) /* 写1个相对单位点的函数 */ { int i,j; for(i=0;i<16;i++) for(j=0;j<16;j++) putpixel(y*16+j,x*16+i,color); } void nedr(void) /* 产生并写下一个方块的函数 */ { int j,x2,y2,i,color; setfillstyle(1,GREEN); nexti=i=random(19); bar(shy*16,shx*16,(shy+4)*16,(shx+4)*16); for(j=0;j4;i--) { for(j=1;j4;i--) for(j=1;j<12;j++) colable[i][j]=colable[i-k][j],board[i][j]=board[i-k][j]; setfillstyle(1,BLUE); bar(sty*16,stx*16,(sdy)*16-1,(sdx+1)*16-1); for(i=5;i<24;i++) for(j=1;j9)) { if(TimerCounter>9)TimerCounter=0; fk(0,x1,y1,i); if(is_bd((k=x1+1),y1,i)) fk(re,x1=k,y1,i); else { fk(re,x1,y1,i); is_line(); fk(2,x1,y1,i); if(end)break; i=nexti;x1=-4;y1=3; fk(re,x1,y1,i); nedr(); } } } KillTimer(); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值