昨天,听说SONY出了SDK,果断的下载了。大感这次SONY可谓下足功夫!作为索青,我表示此文可能存在一定的不客观。

-------------------------------------

首先是发布页面

 

http://www.playstation.com/pss/developer/openbeta/index_e.html

除了SDK Download以外,还提供了PlayStation®Suite Development Assistant的下载,此物只能在PSV的浏览器中下载,其真相则是重定向到PS Store下载一个免费版的App,该APP在PSV上运行必须联网认证。也就是说未来SONY会像苹果一样,在PSV上调试可能直接在App部分收费或与PSN帐号关联。

而在ANDROID智能手机上运行,并没有要求输入PSN帐号。所以,没有PSV的用户也可在手机上调试。但是,由于本人用的SONY本家的手机,所以不清楚其他牌子的手机是否支持。


几个比较明确的事

  • 未来做好的APP和GAME会像苹果需要审查才能上PS Store,且会有定价限制。 也就是说游戏质量对得起价格。
  • PSN帐号 年费制度
  • SDK包含模拟器,没有设备的同学也能用。
  • PSV以及有PS认证的手机可以进行SDK的测试与调试。PS/PSP/PS3不支持。
  • 开发者与SONY的利益分配,是否支持PSN相关功能暂不明确,未定。


SDK安装

   N个下一步。

 

系统环境

   暂时只有Windows环境,且必须得有.Net 4.0。如果没有.Net Framework,安装过程中会自动给你装上。 官方没有说明什么时候支持Linux和MacOS。

 

集成开发工具 IDE

   请不要怪我孤陋寡闻,因为我觉得这是我见过最友好的IDE了。

  • MonoDevelop,界面和Visual Studio没太多区别。快捷键有些许不同。
  • GIT版本控制
  • 有单元测试
  • 主要语言C#,MONO架构
  • 暂时不支持可嵌入C++或者支持调用C++库。网上说法是MONO构架不支持C++/CLI功能。但是世事难料,未来应该会加上。
  • 没有说明哪些库不可用,但目前看来System命名空间下的东西可用。
  • 提供了多个方面的API

  • 一键Run,和WM开发一样的选设备,不像Android开发,设置那么多。很方便,很傻瓜。
  • 有单独的UI编辑器 UIComposer
  • 支持Flash CS5.5 Uncompressed Document (*.xfl) or Flash CS5 Uncompressed Document (*.xfl),用来做UI。
  • 不同类型的游戏DEMO,各种方面的SAMPLES应有尽有。
  • 详细的文档与教程
  • 暂无3D引擎,只有OpenGL函数,支持Cg language.
  • PSV和智能手机上调试的时候都会要求安一个DEV ASSISTANT。(实则为虚拟机)


以下直接COPY文档

 

The following features and services will be added by the future version upgrade of SDK.

  • The service to distribute the created PS Suite applications in PlayStation(R)Store.
  • Development environment using Visual Studio
  • Support for programming languages other than C#
  • Support for model data output from 3D tools other than Maya
  • Low level audio API
  • Camera
  • Position information
  • Video playback
  • API for network services
  • DRM(Digital rights management) and packaging support
以上东东,未来会不会加还只是个传说。

 

从目前看来,这样一个还不算非常完整的库对个人和小型开发团体而言,真是非常有用,不仅大大降低开发门槛,还简化了开发者各种环境配置的困扰。

最后,就是期待SDK能加上那些功能,否则那传说中的99刀/年的费用,还是有点坑爹。毕竟C# Only,不仅仅移植困难(跑去iOS和Android的C++多平台开发),性能本身也是个问题。 性能什么的,论坛里的各种吐槽,作为索亲只能看,不敢回。

个人觉得,SDK的目标群体应该就是个人和小型团体。

posted @ 2012-04-20 21:16 OpLusX 阅读(158) 评论(0) 编辑

转自 http://apps.hi.baidu.com/share/detail/30555651

  在高性能网络服务器程序的开发过程中,我们不能使用同步阻塞,同步非阻塞, 异步阻塞这几种IO模型。这几种IO模型只能应对吞吐量较小或一般的应用。面对巨大吞吐量的应用程序,如大型在线MMOG,游戏服务器,登录服务器等的设 计通常都要采用异步非阻塞IO模型,即事件驱动的设计方法。事件驱动的设计中,函数指针和回调函数是必不可少的编程技术,函数指针是最为基础的知识,本文 先详细描述函数指针的相关知识,打好基础,为后续的开发做好准备。另一篇文章中讨论回调函数。
第一部分   函数指针

函 数指针提供了一些非常有趣,高效和优雅的编程技术。你可以使用它们来替换switch/if语句,以实现自己的延迟绑定或者实现自己的回调函数。但是,需 要付出一些代价,因为函数指针的语法相对复杂。在很多计算机书籍和文档中,对函数指针的描述都停留在表面上。函数指针使用起来不像普通指针那样容易出错, 因为我们不会用函数指针去分配和释放内存。要使用函数指针,我们只需要理解什么是函数指针,熟悉函数指针的语法既可。

什么是函数指针?
         函数指针就是一个指针变量,用来指向函数地址。对于函数地址,我们可能有些陌生,不太容易理解。为此,我们需要明白,正在运行的程序(也叫进程)在内存中 占据一定的空间。进程包括编译好的程序代码和需要使用的变量。于是,程序代码中的函数就是一些字符域,要得到一个函数地址,也就是得到这些字符域的起始地 址。唯一重要的是,你(说编译器或处理器更恰当一些)如何解释指针指向的内存。

下页是用来说明函数指针如何替换if/switch语句要用到的几个例子函数:
// The four arithmetic operations ... one of these functions is selected
// at runtime with a swicth or a function  pointer 
float Plus    (float a, float b) { return a+b; }
float Minus    (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide (float a, float b) { return a/b; }

1. 函数指针的三种形式:
    指向普通C函数的函数指针        --- C语言中的函数指针
    指向C++类静态成员函数的函数指针    --- C++
    指向C++类非静态成员函数的函数指针   --- C++

    前两种函数指针在本质上是一样的,那么,什么是函数指针的本质?指针的本质又是什么?我相信谁都知道,指针的本质就是地址。那么,函数指针的本质自然也就 是函    数地址。我们定义函数指针的目的就是要用它来存放某个函数的地址。问题在这里,类成员函数的地址表示和普通C函数的地址是不一样的。要表示一个类例的成员 函    数,光有函数地址还不够,因为每个类实例拥有一个非静态成员函数,而每个实例在内存中都要占据一定的空间,所以,非静态类成员函数的地址由两部分组成,一 个是    实例地址,一个是函数地址。实例地址通过隐含的this指针来传递。函数地址就是函数在实例所占内存中的偏移地址,只不过这个地址通过函数名取得,我们不 需要关心其偏移具体是多少.

    静态成员函数和非静态成员函数的区别是,静态成员函数并不是第个实例都拥有一个这样的函数。所以,静态成员函数的地址并不需要实例地址,也就是说,没有this指    针。其地址实质上和普通的C函数地址是一样的,只不过在定义函数指针时会有所不同。

    说到这里,几者的区别已经很清楚了。第一种和第三种的区别,两者的区别是:要得到一个类实例的成员函数指向非静态成员函数的函数指针需要一个隐含参数:指 向类    实例的this指针。而指向普通C函数的函数指针只需要得到函数地址既可。 这两种类型的函数指针是不兼容的,即,不可互相赋值。

    这两种类型的指针分别是怎么定义的呢?
    指向普通函数的指针:
    int (*pt2Function)(float, char, char) = NULL;                       // C

    指向类成员函数的指针:
    int (TMyClass::*pt2Member)(float, char, char) = NULL;               // C++
    int (TMyClass::*pt2ConstMember)(float, char,char) const = NULL;      // C++

    todo : 指向静态成员函数的函数指针定义

2.    调用约定(Calling Convention)
    The calling convention tells the compiler things like how to pass the arguments or how to generate the name of a function.
    下页是几种调用约定:
    __cdecal : 默认
    __stdcall
    __pascal
    __fastcall

    上面四个约定都是属于函数签名的,因此,function and functions pointers with different calling convention are incompatible with each other! For  Borland and     Microsoft compilers you specify a specific calling conventions between the return type and the function's for function pointer's name. For GNU GCC you use the     __attribute__ keyword: write the function definitions followed by the keyword __attrubute__ and then state the calling convention in double parentheses.

    // define the calling convention

    void __cdecl DoIt(float a, char b, char c);     // Borland and Microsoft compile
    void   DoIt(float a, char b, char c) __attribute__((cdecl)); // GNU GCC

3. 将函数地址赋给函数指针
    将函数地址赋给函数指针比较简单,直接将有效函数名(包括类成员函数名)作为右值赋给函数指针即可。但是,为了程序可移植性,应该在函数名前加上取地址操 作符&, 即便这是可选的。对于类成员函数,其地址必须包括类名和范围操作符(::).而且必须保证在赋值发生的地方这些函数是可见的。

    // C
    int DoIt(float a, char b, char b, char c) { printf("DoIt \n"); return a+b+c ; }
    int DoMore(float a, char b, char b, char c) { printf("DoMore \n"); return a+b+c ; }

    pt2Function = DoIt;  // short form, ommit the address operator
    pt2Function = &DoMore;  // 正规方式,移植性较好。

    //C++
    class TMyClass
    {
    public:
                 int DoIt(float a, char b, char c) { cout << "TMyClass::DoIt" << endl; return a+b+c;
                 int DoMore(float a, char b, char c) const
                { cout <<"TMyClass::DoMore" << endl; return a-b+c ;}
    };

    pt2ConstMember = &TMyClass::DoMore; // correct assignment using address operator
    pt2Member = &TMyClass::DoIt; // note: pt2Member may also legally point to &DoMore

    注意,指向成员函数的指针的定义时,需要指定类名:
    int (TMyClass::*pt2Member)(float, char, char) = NULL;
    使用时不用类名
    pt2ConstMember = &TMyClass::DoMore;
   
    另一个注意点是,定义时成员函数指针时,指针符号*是在成员函数名之前;而取函数地址时,取地址符号是在类名前。
   
4. 函数指针的比较
  可以用比较操作符来对函数指针进行比较,
    // C if(pt2Function >0){
    if(pt2Function == &DoIt)
        printf("Pointer points to DoIt\n"); }
    else
        printf("Pointer not initialized!!\n");
    // C++
    if(pt2ConstMember == &TMyClass::DoMore) // check if initialized
        cout << "Pointer points to TMyClass::DoMore" << endl;
5. 通过函数指针调用函数
    在C语言中,通过*操作符来从函数指针得到函数地址,从而调用函数,或者直接使用函数指针代替函数名字来调用函数。在c++中,使用两操作符 .*和->* 与类的实例一起来调用实例成员函数(非静态成员函数);
    int result1 = pt2Function(12, ‘a’, ‘b’);     // 这是C中的简短方式
    int result2 = (*pt2Function)(12, ‘a’, ‘b’);  // 这是C中的标准方式

    TMyClass instance1;
    int result3 = (instance1.*pt2Member)(12, ‘a’, ‘b’);  // C++
    int result4 = (*this->*pt2Member)(12, ‘a’, ‘b’);     // 如果this指针有效(如在内中的其他成员内调用)
   
    TMyClass * instance2 = new TMyClass;
    int result4 = (instance2->*pt2Member)(12, ‘a’, ‘b’);  // C++中通过对象指针调用非静态成员函数
    delete instance2;

6. 如何将函数指针作为参数传递
    这是回调函数的关键,因为回调函数中就需要将函数指针作为参数传递。请看下页的例子。
   
    值得注意的是,如何将一个函数参数声明为函数指针。这和在外面定义函数指针语法是一样的。将函数DoIt地址作为实参传递给函数PassPtr的形参时,
    也是在函数名DoIt的面前加上取地址符号&.

    void PassPtr(int (*pt2Func)(float, char, char))
    {
        int result = (*pt2Func)(12, ‘a’, ‘b’);
        cout << result << endl;
    }

    void Pass_A_Function_Pointer()
    {
        cout << endl << “Executing ‘Pass_A_Function_Pointer’” << endl;
        PassPtr(&DoIt);
    }


7. 如何返回一个函数指针
    先把要用到的函数定义拷贝到这里,以便对照函数指针对他们的引用格式。
    float Plus    (float a, float b) { return a+b; }
    float Minus    (float a, float b) { return a-b; }
    float Multiply(float a, float b) { return a*b; }
    float Divide (float a, float b) { return a/b; }
   
    问题:如何定义一个函数,使之返回一个函数指针,并且该指针所指函数的返回类型是fload,参数为两个float。
    解答:有两种方式。一种是直接在函数定义语句中定义该函数要返回的函数指针。另一种是先用typedef定义要返回的函数指针类型,再
    用该类型定义作为函数的返回类型。

    // 直接返回函数值: GetPtr1是一个函数,它需要一个char参数,并且返回一个函数指针。该指针指向的函数有两个float参数,人    返回值类型是float.通过参数opCode确定该返回哪个函数。下面这个定义需要注意的是,第一个float定义的是函数指针所指函数的返    回类型。这个定义格式与平时所见到的函数定义语法有点不一样。返回函数指针的函数定义与普通函数的定义在形式上有些不同,需要习    惯它。用正式语言描述下面这个定义: 定义了一个名为GetPtr1的函数,其返回类型为一个函数指针,该指针所指的函数有两个float类    型参数,返回类型为float. 再说一遍,这个float是所指函数的返回类型。
    float (*GetPtr1(const char opCode))(float, float)
    {
        if(opCode == ‘+’)
            return &Plus;
        else
            return &Minus;
    }

    // 使用typedef: 定义一个函数指针指向一个返回类型是float,并且有两个float类型参数的函数。
    typedef float(*pt2Func)(float, float);
   
    注意,上面这行语句定义了一个类型名pt2Func,而不是一个普通变量。
   
    pt2Func GetPtr2(const char opCode)
    {
        if (opCode == ‘+’ )
            return &Plus;
        else
            return &Minus;
    }

    注意GetPtr2函数中,返回函数地址的方式也是直接在函数名前加取地址操作符。

    //执行示例代码
    void Return_A_Function_Pointer()
    {
        cout << “Execute ‘Return_A_Function_Pointer’” << endl;
        float (*pt2Function)(float, float) = NULL;
        pt2Function=GetPtr1(‘+’ );
        cout << (*pt2Function)(2, 4) << endl;

        pt2Function=GetPtr2(‘-’ );
        cout << (*pt2Function)(2,4);
    }   

8. 如何使用函数指针数组
   
    // C 语言
    typedef int (*pt2Function)(float, char, char);
   
    void Array_Of_Function_Pointers()
    {
        printf(“\nExecuting ‘Array_Of_Function_Pointers’\n”);
       
        //定义一个数组并将每个元素都初始化为NULL,<funcArr1> 和<funcArr2>都是包括10个元素
        // 第一种方法:先使用typedef定义一个函数指针类型,然后再用该指针类型像普通类型那样定义数组
        pt2Function funcArr1[10] = {NULL};
       
        // 第二种方法:直接定义数组
        int (*funcArr2[10](float, char, char) = {NULL};
   
        funcArr1[0] = funcArr2[1] = &DoIt;
        funcArr1[1] = funcArr2[0] = &DoMore;

        printf(“%d\n”, funcArr1[1](12, ‘a’, ‘b’);
        printf(“%d\n”, funcArr1[0](12, ‘a’, ‘b’);
        printf(“%d\n”, funcArr2[1](56, ‘a’, ‘b’);
        printf(“%d\n”, funcArr2[0](34, ‘a’, ‘b’);
    }

    // C++
    typedef int(TMyClass::*pt2Member(float, char, char);
   
    void Array_Of_Member_Function_pointer()
    {
        cout << endl << “Executing ‘Array_Of_Member_function_Pointer’ << endl;
        // 方法1: 使用typedef 先定义一个指向类成员函数的函数指针类型,再用该类型来定义数组。
        pt2Member funcArr1[10] = {NULL};

        // 方法2: 直接定义数组
        int (TMyClass::*funcArr2[10](float, char, char) = {NULL};

        funcArr1[0] = funcArr2[1] = &TMyClass::DoIt;
        funcArr1[1] = funcArr2[0] = &TMyClass::DoMore;

        TMyClass instance;
        cout << (instance.*funcArr1[1](12, ‘a’, ’b’) << endl;
        cout << (instance.*funcArr1[0](12, ‘a’, ’b’) << endl;
        cout << (instance.*funcArr2[1](34, ‘a’, ’b’) << endl;
        cout << (instance.*funcArr2[0](35, ‘a’, ’b’) << endl;
    }
 

posted @ 2011-10-28 15:11 OpLusX 阅读(95) 评论(0)  编辑
1.没有glDisable(GL_TEXTURE_2D),导致基本几何作图全部失败。

2.镜头位置没调好,导致所有物体不可见.

3.物体位置数据错误,导致物体大大超出镜头显示范围.

4.纹理没有GL_CLAMP_TO_EDGE 导致边界拼接出现缝线.

5.纹理没有GL_REPEAT导致使用超出1.0纹理坐标技巧失败,显示单色插值.

6.没有glEnable(GL_TEXTURE_2D)导致全白纹理.

7.glEnable(GL_TEXTURE_2D)后没有使用纹理顶点导致如glColor效果的纯单色.

8. 应该在作图循环设置灯光位置,因为 The position is transformed by the modelview matrix when glLight is called (just as if it were a point), and it is stored in eye coordinates.

9.灯光位置应该是4个float,3个float程序不出错,但结果完全扭曲。

10.打开灯光却没设置顶点法线,到头一场空。

11.Window Class 没有CS_OWNDC,导致glDrawPixels失败,如在子窗口View上进行象素写入操作.

12.没有设置PIXELFORMATDESCRIPTOR的cAlphaBits,导致glReadPixels读取alpha通道数据失败,统统为0.

13.手动实现的多层纹理闪烁,出现线带,没有使用glPolygonOffset.

14.glDrawPixels 格式GL_RGB或GL_BGR_EXT的数据时崩溃,且数据有效,没有使用glPixelStorei(GL_UNPACK_ALIGNMENT, 1);导致图像行默认4字节对齐,导致OpenGL数据读取越界崩溃.相应的要为glReadPixels设置 glPixelStorei(GL_PACK_ALIGNMENT, 1);

15.glReadPixel读取被覆盖的OpenGL窗口部分的图像数据时,读出数据混乱无效,OpenGL Pixel Ownership检测导致,标准如此.使用PixelBuffer,或强制置前OpenGL窗口解决.

16.glReadPixels读取总是从FrameBuffer的左下往右上读取,毫无参数可设置改变方向,真是笨到家了. 载入图像一般还是从上到下比较容易理解.

17.使用glDepthMask(GL_FALSE)后不打开,glClear无法清除深度缓冲,导致现象:场景起始静止正常,一旦移动出现不规则的透明无渲染区域,深度缓存逻辑混乱.

18. gluPerspective(45.0f, (GLfloat)cxPixels/(GLfloat)cyPixels, 0.1f, 2000.0f);这里的0.1f将导致物体和地面的相交处闪烁,原因待查,至少取1.0f.

19.没有显示定义shiniess或shiniess为0,在shader中对gl_FrontMaterial.shininess使用pow计算,结果不可测,黑色条带闪烁,quite not understand.

20.纹理出现白色点状闪烁,没有Mipmap过滤导致!

21.任何初装的Windows系统,多好的机器,一开始对OpenGL只支持1.1,连多重纹理都没有,需要警惕这种机器,装着DX9,微软真恶心,::SwapBuffer直接崩溃,故需要检测显卡至少支持了1.2标准,否则要求更新显卡驱动程序.

22.3D和2D,透视和正射模式混合时,2D模式的渲染覆盖不了3D的渲染,原因深度测试失败,
      a.2D下渲染时所取点深度确实大于3D点的深度.
      b.glOrtho参数错误,导致2D渲染所得深度值错误,如zNear被取负数!
      c.使用glDisable(GL_DEPTH_TEST);

23.glDrawElements崩溃,
      a.glXXXPointer设置的缓冲错误,顶点索引越界引用顶点数组.
      b.当前glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer);硬件缓冲和内存缓冲混淆.

24.画面上出现方块形背景色,原因,渲染一次后,在glClear时glDepthMask没有打开,glClear没能clear掉depth,但clear掉颜色缓冲,depth值持续到下一次render,导致depth test没通过,颜色画不上.

25. 树叶挡在物体前,树叶间隙或蛀洞本应该透明却呈现背景色.原因,没有启用Alpha过滤.一般不可能用几何形状勾勒出叶子的形状,只用较大的多边形包围叶 子,用Alpha过滤掉空隙.此时不启用Alpha过滤,出现Alpha为0的三角面也被渲染,但得到的是背景图像,并且由于Alpha为0的三角面离视 点近,后面的物体渲染无法通过深度测试补上透明的空隙区域.

26.atlgdi.h里有#pragma comment(lib, "opengl32.lib"),导致无源无故链接opengl32.lib失败.




from : http://www.cnitblog.com/linghuye/archive/2005/08/13/1845.html
posted @ 2011-10-17 20:53 OpLusX 阅读(31) 评论(0)  编辑

 转自:http://soft-app.iteye.com/blog/925104

关于RenderTarget的注意事项

1. 设置一个RenderTarget会导致viewport变成跟RenderTarget一样大

2. 反锯齿类型必须跟DepthStencilBuffer一样

3. RenderTarget的类型必须跟DepthStencilBuffer的类型兼容, 可以用IDirect3D9::CheckDepthStencilMatch进行检测

4. DepthStencilBuffer的大小必须>=RenderTarget的大小

5. IDirect3DDevice9::SetRenderTarget的第0个不能为NULL

6. Usage为D3DUSAGE_RENDERTARGET的Texture不能进行反锯齿, 而且Pool必须为D3DPOOL_DEFAULT. 如果想利用RenderTarget做为纹理又想反锯齿, 可以先把场景渲染到一个CreateRenderTarget创建的Surface(或BackBuffer)上, 再用IDirect3DDevice9::StretchRect拷贝到纹理上

7. D3DX提供了一个ID3DXRenderToSurface, 简化了RenderTarget的使用. 注意它的BeginScene跟EndScene与再用IDirect3DDevice9的同名函数对不能嵌套, 因为实际上内部还是调用的IDirect3DDevice9的, 用PIX可以看到它进行了哪些调用. 还有就是这个接口仍然不能反锯齿, 而且每次都要保存/恢复一堆状态, 总觉得不爽

8. RTT不能既做为输入就做为输出目标, 某些显卡上可能只会给一个warning, 有些显卡上则会发生报错/黑屏/死机之类不可预计的事情...另外, Depth stencil texture(参见Hareware shadow map)也有同样的问题, 用完之后要SetTexture(n, NULL)清空, 不然A卡会黑屏/花屏/深度错误, 既使你没有使用, 只要它被寄存器引用了, 显卡还是会当做是正在使用的, 这时就不能做为depth stencil buffer

9. RTT如果想保存到文件中, 是不能直接SaveToTexture的. 需要创建一个OffscreenSurface, 拷贝过去, 再保存. 不过N卡好像不支持DXT1格式的OffscreenSurface, 可以创建Texture, 取其level0的surface代替.

10. N卡在开启了锯齿后冒似所有的RTT都要反锯齿, 不然深度测试会失败-_-

11. Intel的显卡在RTT没有设置DepthBuffer时可能所有绘制全部深度测试失败, 需要关闭深度测试再画.

posted @ 2011-10-17 20:40 OpLusX 阅读(19) 评论(0)  编辑

工作原因接触了Gfx Scaleform 3.1。本人表示此东东异常强大。但是要用好他有很多性能问题,不仅仅是程序时要考虑的!更需要美术和FLASH制作人员共同努力。

关于GFX具体是什么东西以及干什么用的。本人不做介绍,只是谈论一下使用时的一些思考和经验之谈。因为相关方面的文章几乎没有,而且又是商业系统。所以,就在这里做个小小的总结。


1. Flash中的Object对象可以完全由C++代码进行实现,并且在Flash中进行调用。包括Function函数。凭借这点我们可以让客户端的逻辑拥有脚本接口,并且提供给Flash数据和控制客户端的接口。

2. Flash中的TextField控件由Gfx进行了一定的扩展,所以关于HTML的使用上除了<img>标记基本与常规情况下的Flash相同,关于<img>标记的使用就必须要涉及到第三点所提到的相关内容了。理由:GFX中的<img>无法直接从外部取相对路径的图片文件。

3. Flash中的图片加载问题需要C++进行实现与管理,Gfx只提供了简单的接口GImageBase,具体实现以及图片内存管理都需要客户端进行处理。包括动画图片以及可渲染图片,都可以进行实现。当然,如果图片本身包含在相应的Flash文件(.FLA)中可以直接通过到处标记符加载,无需通过客户端。

  关于图片加载问题,最值得说明的是设备重置问题, 设备一旦发生丢失后,就必须要调用Gfx的相关函数使其Renderer进行重置,否则Gfx可能无法继续进行运行。然后,也是最关键的一点,就是设备重置前必须先告知并且释放GImageBase相关的接口。否则。重置是无法成功的。最后一点,就是托管图片与非托管图片的问题以及引用计数的问题 都是必须要注意的。以上后面几点属于细节问题。因此我就不多提了(如果遇到问题请看红字亮点)。

4. 焦点问题,在一般的单窗口,单菜单界面的游戏环境中可能不会遇到问题,但是在复杂且多窗口的情况下,这个问题就凸显出来了。我主要介绍2种技巧,一个是利用FLASH的Selection侦听器,可以知当前所选MovieClip的信息,还有就是利用CLIK框架中的FocusManager来得知当前焦点的信息,通过以上2个技巧可以全面了解当前FLASH环境下焦点是处于什么控件上,并且用来区分是 文字输入框 还是 普通按钮。

5. 窗口击穿的问题,在很多游戏中,窗口往往是透明的,例如聊天文本框。如果是通过FLASH的HITTEST或者使用GFX提供的HITTEST函数执行效率非常差。因为会完全遍历所有MOVIECLIP。所以有一个简单的方法就是将背景设置为FLASH的"按钮",然后利用GFX提供的getTopEntity函数,高效的获取当前鼠标光标正处于什么控件上。从而得出当前是否能够有效击穿窗口结果。

6. 文字渲染问题,GFX还提供了一套文字渲染系统,并且能够直接渲染HTML文字,但是这个系统并不是完美的,和FLASH中的textField有所不同,他不支持内嵌图片,同时还有一个文档中未说明的技巧,就是TEXTFORMAT标签的使用。如果有朋友遇到文字显示格式的问题,可以去查查看。

7. 字体问题,根据GFX的介绍,字体问题有3种解决方案,但是根据实际使用,只有一种方案比较有效,就是利用C++建立GFXFONTMAP,并引入内嵌完整字体的SWF。另外2种方案对于中文环境的支持比较糟糕。很多非主流文字都无法正常显示。

8. 自定义控件的设计,CLIK框架非常强大,所以详细的阅读其代码是非常有必要的,特别是CORELIST与SCROLLLIST这2个类,并且我们可以通过此2类的学习,可以设计出各种必要的控件。


最后。。。如果想到新的我会加的。

posted @ 2010-10-25 21:51 OpLusX 阅读(146) 评论(0) 编辑

由于工作原因,此项目一直没空搭理。所以决定关闭!

另外本人决定将此项目的难度降低!将重新立项目。由原来的FPS游戏将直接改变为一个小游戏。但是框架必须做到强大。以便将来进行扩展。弱化的仅仅是游戏逻辑。

IRRLICHT虽然提供了很好很简单的图像引擎。以及简单易用的函数,但是要和物理结合起来。。。有点困难。部分功能无法分割。

一步一步来吧。 

posted @ 2009-12-08 23:12 OpLusX 阅读(42) 评论(0)  编辑
摘要: 一个很有趣的需求就是算纪念日,来自:兔宝 这个小工具的功能就是算距离纪念日还有多少天,以及多少天后是什么日子的啦。相关下载:/Files/oplusx/SpDayCount算算纪念日可执行程序.rar/Files/oplusx/SpDayCount算算纪念日源代码.rar阅读全文
posted @ 2009-11-17 20:19 OpLusX 阅读(109) 评论(0) 编辑
摘要: 在写服务程序的过程,由于很多权限涉及到“域”,所以服务程序需要用“用户名”登录。然后在WINDOWS的策略设置中,“本地计算机”策略 - 计算机配置 - Windows 设置 - 安全设置 - 本地策略 - 用户权限 其中有这样一个策略设置“作为服务登录”。顾名思义,这里就是需要进行修改的地方。如果没有...阅读全文
posted @ 2009-11-09 16:32 OpLusX 阅读(156) 评论(0) 编辑
摘要: 采用WIN32的函数就能快速查询到磁盘信息。具体代码如下:[代码]以上代码比较简单。发布此文主要是之前做了一个测试测试目的:WIN系统启动后如果不登录界面,即停留在winlogon.exe的“登录框”界面,不进行用户登录,是否可以检测到网络映射和网络硬盘。测试结果:在系统未登录前,不可以检测到网络硬盘,网络映射。同时还得到以下结果:在登录后,使用SYSTEM账户的服务,可以...阅读全文
posted @ 2009-11-05 10:15 OpLusX 阅读(154) 评论(1) 编辑
摘要: 在注册表中的HKEY_USERS根键下 每个用户都有 .DEFAULT\Control Panel\Desktop键来控制桌面的配置。其中的子键Wallpaper代表的是背景图的路径,而WallpaperStyle和TileWallpaper则分别代表的是现实的风格。在实例程序中通过修改参数可以得到以下三种风格。 EWPS_TILE,平铺 EWPS_CENTER,居中 EWPS_STRETC...阅读全文
posted @ 2009-11-04 09:50 OpLusX 阅读(166) 评论(0) 编辑