第一个 OpenGL ES的小程序

http://blog.sina.com.cn/s/blog_b0c5954101019ers.html

#import "King_ViewController.h"


@interface King_ViewController ()


@end


@implementation King_ViewController

@synthesize baseEffect;


//这个数据类型用于储存每个定点的位置信息

typedef struct{

    GLKVector3 positionCoords;

    

}SceneVerTex;

//声明在demo中三角形定点数据静态变量 这个例子中得顶点坐标是挑选出来的,因为默认的用于一个OpenGL上下文的可见坐标系是分别沿着 X Y Z轴从-1.01.0的。例子中的三角形坐标把它置于可见坐标系的中央并且与X Y 所形成的平面对齐。

static const SceneVerTex vertices[] =

{

    {{-0.5f,-0.5f,0.0f}},

    {{0.5f,-0.5f,0.0f}},

    {{-0.5f,0.5f,0.0f}}

};


- (void)viewDidLoad

{

    

    NSLog(@"%s",__func__);

    [super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

    // 将她继承的view属性的类型转换成GLKview类型。类似GLKVeiwController 的子类之恩能够与GLKVie实例或者其子类的实例一起正常工作。

    GLKView * view = (GLKView * )self.view;

    

    //断言检查storyboard加载的的视图是否确实是正确的类型。 错误会抛出NSInternal--tion:内部不匹配异常

    NSAssert([view isKindOfClass:[GLKView class]], @"view controller's view is not a GLKview");

    

    //分配并初始化一个内奸的EAGLContext类的实例izhege实例会封装一个特定于某个平台的OpenGL ES上下文。OpenGL的上下文不仅会保存OpenGL ES的状态,还会控制GPU去执行渲染运算。

    view.context = [[EAGLContext  alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    

    //在任何其他的OpenGL ES配置或渲染发生之前,应用得GLKView实例的上下文属性都需要设置为当前。EAGLContext实例即支持OpenGL ES1.1,又支持OpenGL ES2.0。本例使用的是2.0版本(苹果建议使用2.0:灵活性)。

    [EAGLContext setCurrentContext:view.context];

    

    //实例化基础效果实例,如果没有GLKitGLKBaseEffect类,就需要为这个简单的例子编写一个小的GPU程序,使用2.0Shading Language,而GLKBaseEffect会在需要的时候自动的构建GPU程序并极大地简化本例。

    self.baseEffect = [[GLKBaseEffect allocinit];

    self.baseEffect.useConstantColor = GL_TRUE;

    

    //控制渲染像素颜色的方式有多种。这个应用的GLKBaseEffect实例使用一个恒定不变的白色来渲染三角形。

    //下面代码中使用的再GLKit中定义的用于保存4个颜色元素值的C数据结构体GLKVector4来设置这个恒定值。

    self.baseEffect.constantColor = GLKVector4Make(1.0f1.0f1.0f1.0f);

    

    //glClearColor函数设置当前glClearColor上下文的 清除颜色为不透明黑色。清除颜色由RGBA颜色元素值组成,用于在上下文的帧缓存被清除时初始化每个像素的颜色值。

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    

    //为缓存生成一个独一无二的标示符  step1

    //函数解析 : 第一个参数用于指定要生成的缓存标示符的数量,第二个参数是一个指针,指向生成标示符的内存保存位置。

    //在当前情况下,一个标示符被生成,保存在vertexBufferID成员变量中

    glGenBuffers(1, &vertexBufferID);

    

    //为接下来的运算绑定缓存   step2

    //glBindBuffer函数绑定用于指定标示符的缓存到当前缓存。但是在任意时刻每种类型只能绑定一个缓存。如果在这个例子中使用了两个顶点属性的数字缓存,那么同一时刻不能被绑定。

    //第一个参数 是一个常量,用于指定要绑定哪一种类型的缓存。 OpenGL ES2.0目前只支持两种类型的缓存。GL_ELEMENT_ARRAY_BUFFER 与GL_ARRAY_BUFFERGL_ARRAY_BUFFER类型用于指定一个顶点属性的数组,例如,本例中三角形定点的位置。第二个参数是要绑定的缓存的标示符。

    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);

    

    

    //复制数据到 缓存中     step3

    //glBufferData 函数复制应用的额顶点数据到当前上下文所绑定的顶点缓存中。

    //第一个参数用于指定要更新当前上下文中所绑定的时哪一个缓存。

    //第二个参数指定要复制进这个缓存的自己的数量。

    //第三个参数是要复制的字节的地址

    //第四个参提示了在未来的运算中可能被怎样运用

    //GL_STATIC_DRAW 提示告诉上下文,缓存中的内容适合复制到GPU控制的内存,因为很少对齐进行修改。这个信息可帮助OpenGL ES优化内存使用。

    //GL_DYNAMIC_DRAW  提示数据会频繁改变,同时提示ES 以不同的方式处理缓存中得存储。

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    

}


//此委托方法的实现告诉baseEffect装备好当前的OpenGL ES的上下文,一边为使用baseEffect生成的属性和Shading Language程序的绘画做好准备。

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect

{

    NSLog(@"%s",__func__);

    

    //

    [self.baseEffect prepareToDraw];

    

    //glClear 函数设置当前绑定的帧缓存的像素颜色渲染缓存中的每一个能有除了像素颜色缓存之外的其他附加的缓存,并且如果其他的缓存被使用了,他们可通过在函数中指定不懂得参数来消除。glClear 函数会有效地设置帧缓存中每一个像素的颜色为背景颜色。

    glClear(GL_COLOR_BUFFER_BIT);

    

    

    //glEnableVertexAttribArra启动定点缓存渲染操作。 step 4

    glEnableVertexAttribArray(GLKVertexAttribPosition);

    

    //glVertexAttribPointer 函数会告诉 OpenGL ES 定点数据在哪里,以及解释为每个顶点保存的数据。 step 5

    //第一个参数指示当前绑定的缓存包含每个定点的位置信息

    //第二个参数指示每个顶点位置有三个组成部分

    //第三个参数告诉ES 每个部分都保存为一个浮点类型的值

    //第四个参数告诉ES 小数点固定数据是否可以被改变。 没有使用所以用GL_FALSE

    //第五个参数叫做 步幅,他指定了每个订单的保存需要多少个字节。

    //最后一个参数 NULL,这告诉OpenGL ES可以从当前绑定的定点缓存的开始位置访问定点数据。

    glVertexAttribPointer(GLKVertexAttribPosition,3, GL_FLOAT, GL_FALSE, sizeof(SceneVerTex),NULL);

    //

    //调用glDrawArrays 执行绘图。 step 6

    //第一个参数告诉GPU 怎么处理绑定的顶点缓存内的顶点数据。

    //第二个和第三个 分别制定缓存内的需要渲染的第一个顶点的位置,炫耀渲染的顶点的数量。

    glDrawArrays(GL_TRIANGLES, 0, 3);

    

    //至此, 例子中显示的场景已经被完全的渲染出来了,cpu 和gpu的运算是一部的。这个例子中所有代码都是运行在cpu上的。然后在需要进一步处理的时候向gpu 发送命令。gpu可能也会处理发送自ios 的core animation的命令。因此在任何给定时刻gpu总公钥执行多少处理并不一定。

}



//视图被最终卸载时调用。卸载的试图将不再被绘制,因此任何指示再回只是需要的OpenGL ES 缓存都可以被安全的删除。

-(void)viewDidUnload

{

    NSLog(@"%s",__func__);


    [super viewDidUnload];


    // 删除不再需要的定点缓存 和上下文。 step 7    

    GLKView * view = (GLKView *)self.view;

    [EAGLContext setCurrentContext:view.context];

    

    //设置vertexBufferID 为0 避免了在对应的缓存被删除以后还是勇气无效的标示符。

    if (0 != vertexBufferID) {

        glDeleteBuffers(1, &vertexBufferID);

        vertexBufferID = 0;

    }

    //设置视图的上下文属性为nil,并设置当前上下文为nil。以便让ios 收回所有上下文使用的内存和其他资源。

    ((GLKView *)self.view).context = nil;

    [EAGLContext setCurrentContext:nil];

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 我可以给你一些参考代码,你可以使用OpenGL的API来创建一个窗口,然后在这个窗口中渲染3D图形: #include <GL/glut.h> int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow("OpenGL - First window demo"); glutDisplayFunc(display); glutMainLoop(); return 0; } ### 回答2: C语言是一种常用于编写低级操作系统和嵌入式系统的程序设计语言,而OpenGL是一种用于图形处理和三维渲染的编程接口。 下面是一个使用C语言编写的简单的OpenGL程序的代码示例: ```c #include <GL/glut.h> void display() { // 清空颜色缓冲区 glClear(GL_COLOR_BUFFER_BIT); // 设置绘图颜色为红色 glColor3f(1.0f, 0.0f, 0.0f); // 绘制一个矩形 glBegin(GL_QUADS); glVertex2f(-0.5f, -0.5f); glVertex2f(0.5f, -0.5f); glVertex2f(0.5f, 0.5f); glVertex2f(-0.5f, 0.5f); glEnd(); // 刷新缓冲区,显示绘制结果 glFlush(); } int main(int argc, char** argv) { // 初始化OpenGL glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(400, 400); glutCreateWindow("OpenGL Program"); // 设置绘图函数 glutDisplayFunc(display); // 进入主循环 glutMainLoop(); return 0; } ``` 以上代码实现了一个使用OpenGL绘制一个红色矩形的简单窗口程序。首先导入了在OpenGL中常用的glut库,然后通过定义display函数来进行画图操作,绘制一个红色的矩形。最后在main函数中进行OpenGL的初始化和窗口的创建,并将display函数设置为绘图函数,进入主循环进行显示。 通过以上代码示例,我们可以学习到如何使用C语言编写一个基本的OpenGL程序,利用OpenGL库的函数来进行图形绘制操作。 ### 回答3: 下面是一个使用C语言和OpenGL编写的简单程序,实现了一个绘制彩色三角形的效果: ``` #include <GL/glut.h> void display() { glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲区 glLoadIdentity(); // 重置当前矩阵为单位矩阵 glBegin(GL_TRIANGLES); // 开始绘制三角形 glColor3f(1.0f, 0.0f, 0.0f); // 设置当前颜色为红色 glVertex3f(0.0f, 1.0f, 0.0f); // 设置三角形的第一个顶点坐标 glColor3f(0.0f, 1.0f, 0.0f); // 设置当前颜色为绿色 glVertex3f(-1.0f, -1.0f, 0.0f); // 设置三角形的第二个顶点坐标 glColor3f(0.0f, 0.0f, 1.0f); // 设置当前颜色为蓝色 glVertex3f(1.0f, -1.0f, 0.0f); // 设置三角形的第三个顶点坐标 glEnd(); // 结束绘制 glFlush(); // 刷新缓冲区,将绘制的结果显示到窗口上 } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); glutInitWindowPosition(100, 100); glutInitWindowSize(400, 400); glutCreateWindow("OpenGL Example"); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // 设置清除颜色为黑色 glutDisplayFunc(display); // 注册绘制回调函数 glutMainLoop(); // 进入主循环,等待事件触发 return 0; } ``` 这个程序使用了OpenGL库中的函数和常量,通过调用`glutInit`等函数进行初始化,然后在`display`函数中绘制了一个彩色的三角形。`glClear`用来清除颜色缓冲区,`glLoadIdentity`用来重置当前矩阵为单位矩阵,`glBegin`和`glEnd`用来开始和结束绘制图形的命令序列,`glVertex3f`用来设置顶点坐标,`glColor3f`用来设置当前颜色。 在`main`函数中,我们使用`glutInitDisplayMode`来设置显示模式,`glutInitWindowPosition`和`glutInitWindowSize`来设置窗口的位置和大小,`glutCreateWindow`来创建窗口并设置窗口标题。然后,我们使用`glClearColor`来设置清除颜色,这里设置为黑色。最后,我们注册了`display`函数为绘制回调函数,使用`glutMainLoop`进入主循环,程序会一直运行,等待事件触发。 当程序运行后,会打开一个OpenGL窗口,窗口标题为"OpenGL Example",窗口大小为400x400像素。在窗口中央绘制了一个彩色的三角形,顶点颜色分别为红色、绿色和蓝色。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值