OpenGL绘制一个三角形
应该建立一个vertex shader文件和一个pixel shader文件,分别命名为shader.vsh和shader.fsh。
shader.vsh:
attribute vec3 position; //入参,主程序会将数值传入
void main()
{
gl_Position = vec4(position,); //顶点经过投影变换变换后的位置
}
shader.fsh:
void main()
{
gl_FragColor = vec4(0.5,0.5,0.5,); //顶点的颜色
}
ViewController.m中的代码如下:
//
// ViewController.m
// OpenGL学习Demo
//
// Created by 孙建飞 on 16/7/9.
// Copyright © 2016年 sjf. All rights reserved.
// #import "ViewController.h" #import <OpenGLES/ES3/gl.h>
#import <OpenGLES/ES3/glext.h> @interface ViewController ()
{
EAGLContext *context; //EAGLContent是苹果在ios平台下实现的opengles渲染层,用于渲染结果在目标surface上的更新。
GLuint program;//????????
GLuint vertexID;
// GLvoid *vec; }
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; //三点的坐标:
GLKVector3 vec[]={
{0.5,0.5,},
{-0.5,-0.5,},
{0.5,-0.5,}, };
//初始化EAGLContext时指定ES版本号OPenGLES3
context=[[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES3];
if (!context) {
NSLog(@"failed to create ES context !")
;
}
//
GLKView *view=(GLKView *)self.view;
view.context=context;
view.drawableDepthFormat=GLKViewDrawableDepthFormat24;
[EAGLContext setCurrentContext:context];
glEnable(GL_DEPTH_TEST);//开启深度测试,就是让离你近的物体可以遮挡离你远的物体
glClearColor(0.1, 0.2, 0.3, ); //设置surface的清除颜色,也就是渲染到屏幕上的背景色。
//
[self loadShaders];
glEnable(GL_DEPTH_TEST);
glClearColor(0.1, 0.2, 0.3, );
// glGenVertexArrays(<#GLsizei n#>, <#GLuint *arrays#>)
glGenVertexArrays(, &vertexID);//生成一个vao对象
glBindVertexArray(vertexID); //绑定vao
GLuint bufferID;
glGenBuffers(, &bufferID); //生成vbo
//
glBindBuffer(GL_ARRAY_BUFFER, bufferID); //绑定
// glBufferData(<#GLenum target#>, <#GLsizeiptr size#>, <#const GLvoid *data#>, <#GLenum usage#>)
glBufferData(GL_ARRAY_BUFFER, sizeof(vec), vec, GL_STATIC_DRAW); //填充缓冲对象
GLuint loc=glGetAttribLocation(program, "position"); //获得shader里position变量的索引
glEnableVertexAttribArray(loc); //启用这个索引
glVertexAttribPointer(loc, , GL_FLOAT, GL_FALSE, sizeof(GLKVector3), ); //设置这个索引需要填充的内容
glBindVertexArray(); //释放vao
glBindBuffer(GL_ARRAY_BUFFER, ); //释放vbo
}
//隐藏状态栏
- (BOOL)prefersStatusBarHidden {
return YES;
}
//
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除surface内容,恢复至初始状态。
glBindVertexArray(vertexID);
glUseProgram(program); //使用shader
glDrawArrays(GL_TRIANGLES, , ); //绘制三角形
glBindVertexArray();
glBindBuffer(GL_ARRAY_BUFFER, );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, );
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/***************************加载shader***************************/
- (BOOL)loadShaders
{
GLuint vertShader, fragShader;
NSString *vertShaderPathname, *fragShaderPathname; // Create shader program.
program = glCreateProgram(); // Create and compile vertex shader.
vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"shader" ofType:@"vsh"];
if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
NSLog(@"Failed to compile vertex shader");
return NO;
} // Create and compile fragment shader.
fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"shader" ofType:@"fsh"];
if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
NSLog(@"Failed to compile fragment shader");
return NO;
} // Attach vertex shader to program.
glAttachShader(program, vertShader); // Attach fragment shader to program.
glAttachShader(program, fragShader); // Link program.
if (![self linkProgram:program]) {
NSLog(@"Failed to link program: %d", program); if (vertShader) {
glDeleteShader(vertShader);
vertShader = ;
}
if (fragShader) {
glDeleteShader(fragShader);
fragShader = ;
}
if (program) {
glDeleteProgram(program);
program = ;
} return NO;
}
// Release vertex and fragment shaders.
if (vertShader) {
glDetachShader(program, vertShader);
glDeleteShader(vertShader);
}
if (fragShader) {
glDetachShader(program, fragShader);
glDeleteShader(fragShader);
} return YES;
} - (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
{
GLint status;
const GLchar *source; source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
if (!source) {
NSLog(@"Failed to load vertex shader");
return NO;
} *shader = glCreateShader(type);
glShaderSource(*shader, , &source, NULL);
glCompileShader(*shader); #if defined(DEBUG)
GLint logLength;
glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > ) {
GLchar *log = (GLchar *)malloc(logLength);
glGetShaderInfoLog(*shader, logLength, &logLength, log);
NSLog(@"Shader compile log:\n%s", log);
free(log);
}
#endif glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
if (status == ) {
glDeleteShader(*shader);
return NO;
} return YES;
} - (BOOL)linkProgram:(GLuint)prog
{
GLint status;
glLinkProgram(prog); #if defined(DEBUG)
GLint logLength;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > ) {
GLchar *log = (GLchar *)malloc(logLength);
glGetProgramInfoLog(prog, logLength, &logLength, log);
NSLog(@"Program link log:\n%s", log);
free(log);
}
#endif glGetProgramiv(prog, GL_LINK_STATUS, &status);
if (status == ) {
return NO;
} return YES;
} - (BOOL)validateProgram:(GLuint)prog
{
GLint logLength, status; glValidateProgram(prog);
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > ) {
GLchar *log = (GLchar *)malloc(logLength);
glGetProgramInfoLog(prog, logLength, &logLength, log);
NSLog(@"Program validate log:\n%s", log);
free(log);
} glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
if (status == ) {
return NO;
} return YES;
} @end
运行后得到如下:
参考文献:
http://blog.csdn.net/sx1989827/article/details/47974595
OpenGL绘制一个三角形的更多相关文章
- [Modern OpenGL系列(三)]用OpenGL绘制一个三角形
本文已同步发表在CSDN:http://blog.csdn.net/wenxin2011/article/details/51347008 在上一篇文章中已经介绍了OpenGL窗口的创建.本文接着说如 ...
- 【OpenGL4.0】GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形 【转】
http://blog.csdn.net/xiajun07061225/article/details/7628146 以前都是用Cg的,现在改用GLSL,又要重新学,不过两种语言很多都是相通的. 下 ...
- WebGL简易教程(三):绘制一个三角形(缓冲区对象)
目录 1. 概述 2. 示例:绘制三角形 1) HelloTriangle.html 2) HelloTriangle.js 3) 缓冲区对象 (1) 创建缓冲区对象(gl.createBuffer( ...
- OpenGl 绘制一个立方体
OpenGl 绘制一个立方体 为了绘制六个正方形,我们为每个正方形指定四个顶点,最终我们需要指定6*4=24个顶点.但是我们知道,一个立方体其实总共只有八个顶点,要指定24次,就意味着每个顶点其实重复 ...
- Unity3D学习笔记1——绘制一个三角形
目录 1. 绪论 2. 概述 3. 详论 3.1. 准备 3.2. 实现 3.3. 解析 3.3.1. 场景树对象 3.3.2. 绘制方法 4. 结果 1. 绪论 最近想学习一下Unity3d,无奈发 ...
- Opentk教程系列-1绘制一个三角形
本系列教程翻译自Neo Kabuto's Blog.已经取得作者授权. 本文原文地址http://neokabuto.blogspot.com/2013/02/opentk-tutorial-1-op ...
- OpenTK教程-2绘制一个三角形(正确的方法)
上一个教程向我们展示了如何在屏幕上画一个三角形.但是,我说过,那是一种古老的方式,即使它能够正常运行,但是现在这已经不是"正确"的方式.上篇文章中我们将几何发送到GPU的方式是所谓 ...
- OpenTK教程-2绘制一个三角形(正确的方式)
上一个教程向我们展示了如何在屏幕上画一个三角形.但是,我说过,那是一种古老的方式,即使它能够正常运行,但是现在这已经不是"正确"的方式.上篇文章中我们将几何发送到GPU的方式是所谓 ...
- OpenTK教程-1绘制一个三角形
OpenTK的官方文档是真心的少,他们把怎么去安装OpenTK说的很清楚,但是也就仅限于此,这有一篇learn opentk in 15的教程(链接已经失效,译者注),但是并不完美.你可以在15分钟内 ...
随机推荐
- SoundPool
如果应用程序经常播放密集.急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了.因为MediaPlayer存在如下缺点: 1) 延时时间较长,且资源占用率高. 2) 不支持 ...
- MySQL大数据量的导入
最近在公司备份数据库数据,简单的看了一下.当然我用的是简单的手动备份. 第一:其实最好的方法是直接用: mysqldump -u用户名 -p密码 数据库名 < 数据库名.sql 在linux在操 ...
- “全栈2019”Java多线程第八章:放弃执行权yield()方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- linux进程查看及管理的工具
介绍Linux进程查看及管理的工具:pstree, ps, pidof, pgrep, top, htop, glance, pmap, vmstat, dstat, kill, pkill, jo ...
- Python内置函数查询表——总结篇
Python3.5版本中的68个内置函数,按顺序逐个进行了自认为详细的解析,现在是时候进行个总结了.为了方便记忆,将这些内置函数进行了如下分类: 数学运算(7个) 类型转换(24个) ...
- Android-获取手机已经安装的程序
有时候我们会查询手机里面是否安装了某个程序,或者获取已经安装软件名称的集合. android这边提供了相应的接口. [java] view plaincopy final PackageManager ...
- Python中 '==' 与'is' 以及它们背后的故事
摘要 比较判断逻辑是在代码中经常使用的,在Python中常用 '==' 和 is 来做比较判断. == : 双等号是用来比较变量所指向内存单元中的值是否相等,它只关心值,并不在意值的内存地址,也就 ...
- 类型转换:static_cast、reinterpret_cast等
一.隐式类型转换 系统自动进行,不需要程序开发人员介入. int m = 3 + 45.6;// 48 把小数部分截掉,也属于隐式类型转换的一部分 double b = 3 + 45.6; // 48 ...
- Bootstrap-datepicker日期时间选择器的简单使用
日期时间选择器 目前,bootstrap有两种日历.datepicker和datetimepicker,后者是前者的拓展. Bootstrap日期和时间组件: 使用示例: 从左到右依次是十年视图.年视 ...
- python 全栈开发:str(字符串)常用方法操作 、for 有限循环以及if 循环
str(字符串)常用方法操作: 首字母大写: s = 'mylovepython' s1 = s.capitalize() print(s1) 输出: Mylovepython 单行多字符串首字母大写 ...