|
整理自之前使用的163博客原创文章。
GLSL项目中需要使用GLEW库,因此先要安装GLEW库和在Xcode中配置GLEW。要使GLEW在Xcode中被正确链接,又需要通过MacPorts来安装GLEW。下文以MacPorts-->GLEW-->GLSL的顺序来阐述。
环境:系统 OS X 10.9.2 (13C64),工具 Xcode 5.1,图形卡 Intel Iris 1024 MB
1 MacPorts安装
MacPorts是与apt-get和yum类似的软件管理包,下载与系统对应的安装包后进行安装(安装过程中会联网进行更新,导致安装过程很久,建议断网安装)。安装之后打开终端运行
$ sudo port -v selfupdate
进行更新。如果更新时在如下状态下卡的时间很久,
---> Updating the ports tree
Synchronizing local ports tree from rsync://rsync.macports.org/release/tarballs/ports.tar
receiving file list ... done
ports.tar
使用control+z终止更新,终端输入
$ sudo vim /opt/local/etc/macports/sources.conf
打开配置文件,更改最后一行的默认下载地址(参考“解决安装macports,不能更新的问题”,参考下载网址列表),如可修改为韩国镜像:
#rsync://rsync.macports.org/release/tarballs/ports.tar [default]
#http://www.macports.org/files/ports.tar.gz [default]
rsync://cjj.kr.rsync.macports.org/macports/release/tarballs/ports.tar
改好后wq保存退出,再次运行
$ sudo port -v selfupdate
进行更新,更新成功后会显示如下信息:
---> MacPorts base is already the latest version
The ports tree has been updated. To upgrade your installed ports, you should run port upgrade outdated
安装过程中遇到其它问题请戳:
Mac OS X Lion安装MacPorts(让你在Mac的Shell下更加游刃有余)
Mac中MacPorts安装和使用
Mac OS X中MacPorts安装和使用
2 GLEW库安装
glew库主要有如下三种安装方式:1)在Xcode中直接导入framework(下载地址);2)编译glew源代码进行安装(参考“Installing GLEW in Mac OS X (Leopard)”);3)通过MacPorts进行安装。
实测了三种方式,均可成功安装glew库,但前两种方式在Xcode中链接不成功,本文通过MacPorts进行安装(参考“GLEW: Apple Mach-O Linker (Id) Error”)。
终端输入
$ sudo port install glew
进行安装,安装成功后显示:
---> Installing glew @1.10.0_0
---> Activating glew @1.10.0_0
---> Cleaning glew
---> Updating database of binaries: 100.0%
---> Scanning binaries for linking errors: 100.0%
---> No broken files found.
安装过程中遇到其它问题请戳
cannot link glew under xcode4, macosx lion
3 Xcode中GLSL的配置
Mac系统中已内置openGL、GLUT和GLSL,无需安装。
启动Xcode,新建Cocoa Application工程,删除“TriangleAppDelegate.*”文件、“*main.m”文件和“MainMenu.xib”文件。右键单击"Supporting Files"添加新文件,选择"C++ File"。添加后,删除对应的头文件。右键单击"Frameworks",添加"OpenGL.framework"和"GLUT.framework"(参考“MAC OS X And Win7 vs2010 搭建OpenGL”,参考“在Xcode中使用GLUT开发OpenGL应用程序”)。
下面是添加对GLEW库的链接,在build setting中添加如下参数即可:
other linker flags: -lGLEW
header search paths: /opt/local/include/
library search paths: /opt/local/lib/
4 Hello World
在supporting files下添加basic.vert:
1 void main(){
2 gl_Position = ftransform();
3 }
在supporting files下添加basic.frag:
1 void main() {
2 gl_FragColor = vec4(0.4,0.4,0.8,1.0);
3 }
在supporting files下添加textfile.h:
1 #ifndef macGL_textfile_h
2 #define macGL_textfile_h
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 char *textFileRead(const char *fn);
9 int textFileWrite(char *fn, char *s);
10 unsigned char *readDataFromFile(char *fn);
11 #endif
在supporting files下添加textfile.cpp:
1 #include "textfile.h"
2
3 unsigned char * readDataFromFile(char *fn){
4 FILE *fp;
5 unsigned char *content = NULL;
6 int count=0;
7
8 if (fn != NULL) {
9 fp = fopen(fn,"rb");
10 if (fp != NULL) {
11 fseek(fp, 0, SEEK_END);
12 count = ftell(fp);
13 rewind(fp);
14 if (count > 0) {
15 content = (unsigned char *)malloc(sizeof(unsigned char) * (count+1));
16 count = fread(content,sizeof(unsigned char),count,fp);
17 content[count] = '\0';
18 }
19 fclose(fp);
20 }
21 }
22
23 return content;
24 }
25
26
27 char *textFileRead(const char *fn) {
28 FILE *fp;
29 char *content = NULL;
30 int count=0;
31
32 if (fn != NULL) {
33 fp = fopen(fn,"rt");
34 if (fp != NULL) {
35 fseek(fp, 0, SEEK_END);
36 count = ftell(fp);
37 rewind(fp);
38 if (count > 0) {
39 content = (char *)malloc(sizeof(char) * (count+1));
40 count = fread(content,sizeof(char),count,fp);
41 content[count] = '\0';
42 }
43 fclose(fp);
44 }
45 }
46 return content;
47 }
48
49
50 int textFileWrite(char *fn, char *s) {
51 FILE *fp;
52 int status = 0;
53 if (fn != NULL){
54 fp = fopen(fn,"w");
55 if (fp != NULL) {
56 if (fwrite(s,sizeof(char),strlen(s),fp) == strlen(s))
57 status = 1;
58 fclose(fp);
59 }
60 }
61 return(status);
62 }
View Code 在supporting files下添加GLSLTest.cpp。其中display函数中的glutWireTeapot()是glut内置的画茶壶的函数。注意MAC下特有的glBindVertexArrayAPPLE,glBindVertexArrayAPPLE,glGenVertexArraysAPPLE:
1 //#pragma comment(lib,"libGLEW.a")
2
3 #include <GL/glew.h>
4
5 #include "textfile.h"
6
7 #include <glut/glut.h>
8 #include <iostream>
9 using namespace std;
10
11 GLuint vShader,fShader;//顶点着色器对象
12
13 //顶点位置数组
14 float positionData[] = {
15 -0.8f, -0.8f, 0.0f,
16 0.8f, -0.8f, 0.0f,
17 0.0f, 0.8f, 0.0f };
18 //颜色数组
19 float colorData[] = {
20 1.0f, 0.0f, 0.0f,
21 0.0f, 1.0f, 0.0f,
22 0.0f, 0.0f, 1.0f };
23
24 GLuint vaoHandle;//vertex array object
25
26 void initShader(const char *VShaderFile,const char *FShaderFile)
27 {
28 //1、查看GLSL和OpenGL的版本
29 const GLubyte *renderer = glGetString( GL_RENDERER );
30 const GLubyte *vendor = glGetString( GL_VENDOR );
31 const GLubyte *version = glGetString( GL_VERSION );
32 const GLubyte *glslVersion =
33 glGetString( GL_SHADING_LANGUAGE_VERSION );
34 GLint major, minor;
35 glGetIntegerv(GL_MAJOR_VERSION, &major);
36 glGetIntegerv(GL_MINOR_VERSION, &minor);
37 cout << "GL Vendor :" << vendor << endl;
38 cout << "GL Renderer : " << renderer << endl;
39 cout << "GL Version (string) : " << version << endl;
40 cout << "GL Version (integer) : " << major << "." << minor << endl;
41 cout << "GLSL Version : " << glslVersion << endl;
42
43 //2、编译着色器
44 //创建着色器对象:顶点着色器
45 vShader = glCreateShader(GL_VERTEX_SHADER);
46 //错误检测
47 if (0 == vShader)
48 {
49 cerr << "ERROR : Create vertex shader failed" << endl;
50 exit(1);
51 }
52
53 //把着色器源代码和着色器对象相关联
54 const GLchar *vShaderCode = textFileRead(VShaderFile);
55 const GLchar *vCodeArray[1] = {vShaderCode};
56 glShaderSource(vShader,1,vCodeArray,NULL);
57
58 //编译着色器对象
59 glCompileShader(vShader);
60
61
62 //检查编译是否成功
63 GLint compileResult;
64 glGetShaderiv(vShader,GL_COMPILE_STATUS,&compileResult);
65 if (GL_FALSE == compileResult)
66 {
67 GLint logLen;
68 //得到编译日志长度
69 glGetShaderiv(vShader,GL_INFO_LOG_LENGTH,&logLen);
70 if (logLen > 0)
71 {
72 char *log = (char *)malloc(logLen);
73 GLsizei written;
74 //得到日志信息并输出
75 glGetShaderInfoLog(vShader,logLen,&written,log);
76 cerr << "vertex shader compile log : " << endl;
77 cerr << log << endl;
78 free(log);//释放空间
79 }
80 }
81
82 //创建着色器对象:片断着色器
83 fShader = glCreateShader(GL_FRAGMENT_SHADER);
84 //错误检测
85 if (0 == fShader)
86 {
87 cerr << "ERROR : Create fragment shader failed" << endl;
88 exit(1);
89 }
90
91 //把着色器源代码和着色器对象相关联
92 const GLchar *fShaderCode = textFileRead(FShaderFile);
93 const GLchar *fCodeArray[1] = {fShaderCode};
94 glShaderSource(fShader,1,fCodeArray,NULL);
95
96 //编译着色器对象
97 glCompileShader(fShader);
98
99 //检查编译是否成功
100 glGetShaderiv(fShader,GL_COMPILE_STATUS,&compileResult);
101 if (GL_FALSE == compileResult)
102 {
103 GLint logLen;
104 //得到编译日志长度
105 glGetShaderiv(fShader,GL_INFO_LOG_LENGTH,&logLen);
106 if (logLen > 0)
107 {
108 char *log = (char *)malloc(logLen);
109 GLsizei written;
110 //得到日志信息并输出
111 glGetShaderInfoLog(fShader,logLen,&written,log);
112 cerr << "fragment shader compile log : " << endl;
113 cerr << log << endl;
114 free(log);//释放空间
115 }
116 }
117
118 //3、链接着色器对象
119 //创建着色器程序
120 GLuint programHandle = glCreateProgram();
121 if (!programHandle)
122 {
123 cerr << "ERROR : create program failed" << endl;
124 exit(1);
125 }
126 //将着色器程序链接到所创建的程序中
127 glAttachShader(programHandle,vShader);
128 glAttachShader(programHandle,fShader);
129 //将这些对象链接成一个可执行程序
130 glLinkProgram(programHandle);
131 //查询链接的结果
132 GLint linkStatus;
133 glGetProgramiv(programHandle,GL_LINK_STATUS,&linkStatus);
134 if (GL_FALSE == linkStatus)
135 {
136 cerr << "ERROR : link shader program failed" << endl;
137 GLint logLen;
138 glGetProgramiv(programHandle,GL_INFO_LOG_LENGTH,
139 &logLen);
140 if (logLen > 0)
141 {
142 char *log = (char *)malloc(logLen);
143 GLsizei written;
144 glGetProgramInfoLog(programHandle,logLen,
145 &written,log);
146 cerr << "Program log : " << endl;
147 cerr << log << endl;
148 }
149 }
150 else//链接成功,在OpenGL管线中使用渲染程序
151 {
152 glUseProgram(programHandle);
153 }
154 }
155
156 void initVBO()
157 {
158 // Create and populate the buffer objects
159 GLuint vboHandles[2];
160 glGenBuffers(2, vboHandles);
161 GLuint positionBufferHandle = vboHandles[0];
162 GLuint colorBufferHandle = vboHandles[1];
163
164 //绑定VBO以供使用
165 glBindBuffer(GL_ARRAY_BUFFER,positionBufferHandle);
166 //加载数据到VBO
167 glBufferData(GL_ARRAY_BUFFER,9 * sizeof(float),
168 positionData,GL_STATIC_DRAW);
169
170 //绑定VBO以供使用
171 glBindBuffer(GL_ARRAY_BUFFER,colorBufferHandle);
172 //加载数据到VBO
173 glBufferData(GL_ARRAY_BUFFER,9 * sizeof(float),
174 colorData,GL_STATIC_DRAW);
175
176 glGenVertexArraysAPPLE(1,&vaoHandle);
177 glBindVertexArrayAPPLE(vaoHandle);
178
179 glEnableVertexAttribArray(0);//顶点坐标
180 glEnableVertexAttribArray(1);//顶点颜色
181
182 //调用glVertexAttribPointer之前需要进行绑定操作
183 glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
184 glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );
185
186 glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
187 glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );
188 }
189
190 void init()
191 {
192 //初始化glew扩展库
193 GLenum err = glewInit();
194 if( GLEW_OK != err )
195 {
196 cout <<"Error initializing GLEW: " << glewGetErrorString(err) << endl;
197 }
198
199 initShader("basic.vert","basic.frag");
200
201 initVBO();
202
203 glClearColor(0.0,0.0,0.0,0.0);
204 //glShadeModel(GL_SMOOTH);
205
206 }
207
208 void display()
209 {
210 glClear(GL_COLOR_BUFFER_BIT);
211
212 ////绘制一个三角形(使用普通方法)
213 //glBegin(GL_TRIANGLES);
214 //glColor3f(0.0f,1.0f,0.0f);
215 //glVertex3f(0.0f,1.0f,0.0f);
216
217 //glColor3f(0.0f,1.0f,0.0f);
218 //glVertex3f(-1.0f,-1.0f,0.0f);
219
220 //glColor3f(0.0f,0.0f,1.0f);
221 //glVertex3f(1.0f,-1.0f,0.0f);
222 //glEnd();
223
224 //使用VAO、VBO绘制
225 glBindVertexArrayAPPLE(vaoHandle);
226 //glDrawArrays(GL_TRIANGLES,0,3);
227 glutWireTeapot(0.5);
228 GLint tiz = glGetUniformLocation(vaoHandle, "iz");
229 glUniform1iARB(tiz, 20);
230 glBindVertexArrayAPPLE(0);
231 glutWireTeapot(1.0);
232
233 glutSwapBuffers();
234 }
235
236 void keyboard(unsigned char key,int x,int y)
237 {
238 switch(key)
239 {
240 case 27:
241 glDeleteShader(vShader);
242 glUseProgram(0);
243 break;
244 }
245 }
246
247 int main(int argc,char** argv)
248 {
249 glutInit(&argc,argv);
250 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
251 glutInitWindowSize(600,600);
252 glutInitWindowPosition(100,100);
253 glutCreateWindow("GLSL Test : Draw a triangle");
254 init();
255 glutDisplayFunc(display);
256 glutKeyboardFunc(keyboard);
257
258 glutMainLoop();
259 return 0;
260 }
View Code 运行成功后的效果图:
其它参考网址:
【GLSL教程】(四)shder的简单示例
GLSL Tutorial
How to link glew in xcode
【GLSL教程】(二)在OpenGL中使用GLSL
GLSL.Refract & Reflect & Diffraction
|
|