整理自以前使用的163博客原創文章。php
$ 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終止更新,終端輸入html
$ sudo vim /opt/local/etc/macports/sources.conf
打開配置文件,更改最後一行的默認下載地址(參考「解決安裝macports,不能更新的問題」,參考下載網址列表),如可修改成韓國鏡像:ios
#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保存退出,再次運行macos
$ sudo port -v selfupdate
進行更新,更新成功後會顯示以下信息:vim
---> 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下更加遊刃有餘)xcode
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
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/
在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 }
在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 //一、查看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 //二、編譯着色器 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 //三、連接着色器對象 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 }
運行成功後的效果圖:
其它參考網址: