zoukankan      html  css  js  c++  java
  • MAC OS下使用Xcode进行GLSL编程的配置过程

    整理自之前使用的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] = '';
    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] = '';
    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

  • 相关阅读:
    Java 日期时间类
    JavaMail
    PHP连接 SQLSERVER 注意事项(经典中的经典)
    Spring 依赖注入的 几种方式
    ms sql 备份指令
    Struts2 日期类型编辑器 和 struts.xml 的存放路径
    如何将二维数组作为函数的参数传递
    gcc编译
    关于fflush(stdin)的使用与scanf输入缓冲区的问题
    LINUX socket 连接的几个问题
  • 原文地址:https://www.cnblogs.com/openxxs/p/4055916.html
Copyright © 2011-2022 走看看