• OpenGL ES纹理尺寸限制的处理方法

    大家都知道,OpenGL ES对纹理的尺寸有限制,就是长和宽都必须是2的整数次幂。(实际上OpenGL都有此限制,但有一些扩展可以解决此问题)。因此处理方案有两种:


    1. 将纹理尺寸限制为2的整数次幂。比如,我有一个480×320的背景图案,我可以用Photoshop将画布设置为512×512,在纹理映射时只使用480×320部分。当然我也可以将多个图案合成在一个纹理中,在纹理映射时根据图案的位置进行映射。
    2. 仍然使用正常的图像尺寸,但在使用时进行转换。下面是源代码:


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
            // 首先调整纹理的长和宽为2的整数次幂        
            if( (_width != 1) && (_width & (_width - 1)) )
            {
                    i = 1;
                    while((sizeToFit ? 2 * i : i) < _width)
                            i *= 2;
                    _width = i;
            }

            if( (_height != 1) && (_height & (_height - 1)) )
            {
                    i = 1;
                    while((sizeToFit ? 2 * i : i) < _height)
                            i *= 2;
                    _height = i;
            }

            // 如果调整后的图像尺寸大于最大纹理尺寸(1024),那么需要缩小
            while((_width &gt; kMaxTextureSize) || (_height &gt; kMaxTextureSize))
            {
                _width /= 2;
                _height /= 2;
                transform = CGAffineTransformScale(transform, 0.5, 0.5);
                imageSize.x *= 0.5;
                imageSize.y *= 0.5;
            }
     
  • iPhone不是Mac Pro

    本文是关于通过Objective C++的强大功能提高iPhone程序的性能。通过讨论现实世界中Savoy的Spots应用程序遇到的问题,本文展示了通过3个步骤对程序进行优化使其顺利运行的过程。


    Spots


    读文章 »

     
  • 使用UIImagePickerController从iPhone照片库或照相机获取图像

    本文讲述使用3.0的方法怎样从iPhone的照片库或照相机获取图像。


    我们将创建一个应用程序从图片库或照相机获取图像并显示与屏幕之上。下面是截图:


    photo 2

    读文章 »

     
  • iPhone程序的文档目录

    最近实在太忙,手头上的事情还没有完成,因此正在进行的几篇有关OpenGL ES的文章只能推后了。


    今天介绍一下怎样获得iPhone程序的文档目录(通常用来存储用户数据),方法一:


    1
    2
    NSString* documentsDirectory  = [NSHomeDirectory()
            stringByAppendingPathComponent:@"Documents"];


    方法二:


    1
    2
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
     
  • 怎样编写Apple Push Notification服务器

    iPhone OS 3.0一个引入注目的新特性是push notifications(推送通知),它允许向已安装相关应用程序的各设备直接发送消息。苹果在新闻提示或IM应用中展示了此特性,它也十分完美地适合于我们的服务器监视服务程序Server Density


    Server monitoring iPhone application alert view

    读文章 »

     
  • 开始学习iphone编程之六 – 简单示例代码

    下面有一些iPhone OS 3.0的范例代码。这些代码都是没有使用Interface Builder的。作为初学者,用这种方法可以更清晰的知道程序是怎样创建用户接口的。

    读文章 »

     
  • 跨平台游戏引擎开发实录之一 – 设计文档

    我目前正在开发一个跨平台游戏引擎,我准备将整个开发过程通过博客记录下来。欢迎各位朋友提出宝贵意见。


    下面是我的设计文档初稿。


    项目名称

    Portable Game Engine (PGE )


    目标

    • 跨平台,希望能支持Windows,Linux,Mac OSX,iPhone,WinCE, Android, Blackberry, Symbian phone 等
    • 简单,尽量简化编程接口
    • 2D和3D
    • 组件可选,以减小目标代码
    • 支持Unicode


    组件

    • 核心:游戏主循环,线程,垃圾收集,插件等
    • 图形系统(采用OpenGL或OpenGL ES):图像(纹理),动画,字体
    • 声音系统(采用OpenAL):音效,音乐,乐器
    • 资源管理器:压缩/解压,加密/解密
    • 输入:键盘,鼠标及触摸屏(重力感应)
    • 网络:Tcp/ip,Http, UDP
    • GUI(用户接口):菜单,文本,按钮,列表框,下拉框,选择框
    • 游戏AI
    • 游戏Physics


    开发按阶段进行。第一阶段开发Windows下的OpenGL 2D引擎,然后移植到iPhone下。

     
  • 从零开始学习OpenGL ES之五补遗 – setupView重写

    我在从零开始学习OpenGL ES之四 – 光效 一文中使用了一个普通GLfloat数组。由于它没有使用任何非OpenGL定义的数据结构,所以是最为普通和方便的方式。

     

    但在此我使用在第一部分定义的Vertex3D, Vector3DColor3D数据结构重写了 setupView:方法。并不是这种方法“更好”,但是它是一种不同的方式。当我第一次学习OpenGL时,我发现使用顶点,颜色和三角形的术语比可变长度浮点数组更容易理解。如果你和我一样,那么你会发现这个版本更容易理解。

     

    除了使用自定义数据结构外,我还减少了环境光元素的数量并将光源向右移动了一点。然后使用Vector3DMakeWithStartAndEndPoints()将移动的光源指向二十面体。这样做使得光效更为生动一点。

    -(void)setupView:(GLView*)view
    {
        const GLfloat zNear = 0.01, zFar = 1000.0, fieldOfView = 45.0;
        GLfloat size;
        glEnable(GL_DEPTH_TEST);
        glMatrixMode(GL_PROJECTION);
        size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
        CGRect rect = view.bounds;
        glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size /
                   (rect.size.width / rect.size.height), zNear, zFar);
        glViewport(0, 0, rect.size.width, rect.size.height);
        glMatrixMode(GL_MODELVIEW);
    
        // Enable lighting
        glEnable(GL_LIGHTING);
    
        // Turn the first light on
        glEnable(GL_LIGHT0);
    
        // Define the ambient component of the first light
        static const Color3D light0Ambient[] = {{0.05, 0.05, 0.05, 1.0}};
        glLightfv(GL_LIGHT0, GL_AMBIENT, (const GLfloat *)light0Ambient);
    
        // Define the diffuse component of the first light
        static const Color3D light0Diffuse[] = {{0.4, 0.4, 0.4, 1.0}};
        glLightfv(GL_LIGHT0, GL_DIFFUSE, (const GLfloat *)light0Diffuse);
    
        // Define the specular component and shininess of the first light
        static const Color3D light0Specular[] = {{0.7, 0.7, 0.7, 1.0}};
        glLightfv(GL_LIGHT0, GL_SPECULAR, (const GLfloat *)light0Specular);
        glLightf(GL_LIGHT0, GL_SHININESS, 0.4);
    
        // Define the position of the first light
       // const GLfloat light0Position[] = {10.0, 10.0, 10.0};
        static const Vertex3D light0Position[] = {{10.0, 10.0, 10.0}};
        glLightfv(GL_LIGHT0, GL_POSITION, (const GLfloat *)light0Position); 
    
        // Calculate light vector so it points at the object
        static const Vertex3D objectPoint[] = {{0.0, 0.0, -3.0}};
        const Vertex3D lightVector = Vector3DMakeWithStartAndEndPoints(light0Position[0], objectPoint[0]);
        glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, (GLfloat *)&lightVector);
    
        // Define a cutoff angle. This defines a 50° field of vision, since the cutoff
        // is number of degrees to each side of an imaginary line drawn from the light's
        // position along the vector supplied in GL_SPOT_DIRECTION above
        glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 25.0);
    
        glLoadIdentity();
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }

     

    你可以随意调整光的属性,增加额外的光源或二十面体,体验一下这些调整会为场景带来什么样的变化。这些东西是很难体验出来的,所以不要指望一晚上就理解了所有东西。

     

    原文见:setupView: from Part IV Rewritten

     
  • 从零开始学习OpenGL ES之六 – 纹理及纹理映射

    在OpenGL ES中另一种为多边形定义颜色创建材质的方法是将纹理映射到多边形。这是一种很实用的方法,它可以产生很漂亮的外观并节省大量的处理器时间。比如说,你想在游戏中造一个砖墙。你当然可以创建一个具有几千个顶点的复杂物体来定义每块砖以及砖之间的泥灰。

     

    或者你可以创建一个由两个三角形构成的方块(四个顶点),然后将砖的照片映射上去。简单的几何体通过纹理映射的方法比使用材质的复杂几何体的渲染快得多。

     

    读文章 »

     
  • 从零开始学习OpenGL ES之五 – 材质

    上一篇文章,我们讨论了光效的设定以及光效的各种属性。我们还讨论了光的三要素:散射光, 环境光高光。如果你还不是完全清楚,那么我们来复习一下,在定义材质时大量的用到这些要素。

    component


     

    作为本文的起点,我们使用了此文球体绘制 的项目文件。我们不再使用二十面体而是转向球体是因为球体是展示光和材质不同要素之间相互作用的最佳形状。

     

    读文章 »