zoukankan      html  css  js  c++  java
  • OpenGL 基础知识

    1. 主函数

    int main(int argc, char* argv[]) {
        glutInit(&argc, argv);

        //初始化OPENGL显示方式 双缓冲、RGBA颜色模式
        glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
        //设定OPENGL窗口位置和大小
        glutInitWindowSize (500, 500);
        glutInitWindowPosition (100, 100);
        //打开窗口
        glutCreateWindow ("OpenGL");

        //调用初始化函数
        myinit();

        //设定窗口大小变化的回调函数,需要设定视区glViewport(0, 0, w, h);、透视方式glMatrixMode(GL_PROJECTION)与透视参数gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30.0)(角度,视景体的宽高比,沿z轴方向的两裁面之间的距离的近处,远处)


        glutReshapeFunc(myReshape);

        //设定键盘控制的回调函数
        //processSpecialKeys(int key, int x, int y)中key可以为GLUT_KEY_LEFT、GLUT_KEY_UP等
        glutSpecialFunc(processSpecialKeys);
        //processNormalKeys(unsigned char key,int x,int y)中key为ASCII
        glutKeyboardFunc(processNormalKeys);
         //10ms后执行回调function,回调中一般glutPostRedisplay()刷新页面,如果想重复执行再继续定义
        glutTimerFunc(10, function, 0);
        
        //开始OPENGL的循环
        glutDisplayFunc(display);
        glutMainLoop();
        return 0;
    }
     
    2. 用户初始化函数
    void myinit(void) {
        //打开深度检测
        glEnable(GL_DEPTH_TEST);
        //启用光照并打开默认的0号光
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        //启用颜色材质并定义什么材料追踪颜色
        glEnable(GL_COLOR_MATERIAL);
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
     
        GLenum err = glewInit();   
        if (GLEW_OK != err)  {   
            printf("glew initionlize error: %s ", glewGetErrorString(err));
        }
        //设置矩阵模式
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        //设置光源的位置、环境光、散射光、反射光的颜色
        glLightfv(GL_LIGHT0, GL_POSITION, G_vLit0Position);
        glLightfv(GL_LIGHT0, GL_AMBIENT, G_vLit0Ambient);
        glLightfv(GL_LIGHT0, GL_DIFFUSE, G_vLit0Diffuse);
        glLightfv(GL_LIGHT0, GL_SPECULAR, G_vLit0Specular);

        //Setting the textures
        loadTexImages();
        //开启颜色混合(片元操作:裁剪测试、alpha测试、模板测试、深度测试、混合、抖动、逻辑操作),定义混合因子计算方法
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    }
     
    3. 加载贴图函数
    void loadTexImages(void) {
        //生成2个贴图存入全局GLuint G_texNameArray[2]
        glGenTextures(2, G_texNameArray);

        //载入water.tga纹理
        int nWidth, nHeight, nComponents;
        GLenum eFormat;
        const char *szFileName = "Textures\water2.tga";
        
        // 读TGA文件的数据
        GLbyte *pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat);
        // 读BMP文件数据方法 AUX_RGBImageRec * pBits =auxDIBImageLoad(_T("tsIcon.bmp"));
        if(pBits == NULL)
            return;
        //切换第二幅贴图为操作贴图,指定显存指针
        glBindTexture(GL_TEXTURE_2D, G_texNameArray[1]);
        //根据图像Byte数据生成纹理,根据指针加载到显存
        gluBuild2DMipmaps(GL_TEXTURE_2D, nComponents, nWidth, nHeight, eFormat, GL_UNSIGNED_BYTE, pBits);
        free(pBits);
    }
    /*
      *  GLubyte checkImage[Height 0xff][Width 0xff][4];
      *  遍历像素,二进制某一位隔固定长度切换0/1,异或获得棋盘
      *  [0][1][2] = c = ( (i&0x8) ^ (j&0x8) ) * 255, alpha[3] = 255
      *  glBindTexture, glTexImage2D/gluBuild2DMipmaps
      */
     
    4. 显示函数
    void display(void) {
        //设置清除屏幕的颜色,并清除屏幕和深度缓冲
        glClearColor(0.9f,0.9f,0.9f,0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
        //设置平滑
        glShadeModel(GL_FLAT/GL_SMOOTH);

        //切换MODELVIEW矩阵堆栈并初始化模型变换矩阵
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        //坐标中心向Z轴平移-G_fDistance (使坐标中心位于摄像机前方)
        glTranslatef(0.0, 0.0, -G_fDistance);
        glRotatef(G_fAngle_horizon, 0.0f, 1.0f, 0.0f);
        glRotatef(G_fAngle_vertical, 1.0f, 0.0f, 0.0f);

        //绘制物体
        
        //设置物体材质参数(和光照glLightfv)类似
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, G_vMaterialSpecu);
        glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0f);
        glColor4f(0.0f, 1.0f, 0.0f, 0.0f);
        
        //开启2D贴图并绑定Gen的贴图GLuint
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, G_texNameArray[1]);
        //纹理过滤函数,设置S与T方向的贴图次数、放大缩小的过滤方式(LINEAR4像素加权平均、NEAREST像素中心)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        //纹理如何映射到每个像素上,纹理颜色如何影响片元颜色
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
       
        //切换TEXTURE矩阵堆栈是下一个矩阵操作的目标
        glMatrixMode(GL_TEXTURE);
        glLoadIdentity();
        glTranslatef(G_fWaterTexOffset, 0.0f, 0.0f);
        //切换MODELVIEW矩阵堆栈是下一个矩阵操作的目标
        glMatrixMode(GL_MODELVIEW);
     
        //绘制四边形同时绘制绑定的贴图,点坐标和贴图坐标
        glBegin(GL_QUADS);
            glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, -1.0f, -2.0f);
            glTexCoord2f(4.0f, 0.0f); glVertex3f(4.0f, -1.0f, -2.0f);
            glTexCoord2f(4.0f, 1.0f); glVertex3f(4.0f, 1.0f, -2.0f);
            glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 1.0f, -2.0f);
        glEnd();
        //关闭贴图
        glDisable(GL_TEXTURE_2D);

        //交换前后缓冲区
        glutSwapBuffers();
    }
     
    5. 初始化Shader 装载、编译、链接
    获取GLuint类型的
    点着色器对象G_vShader_simple;面着色器对象G_fShader_simple;着色器程序G_shaderProgram;
        // 创建顶点与面片Shader着色器对象
        G_vShader_simple = glCreateShader(GL_VERTEX_SHADER);  
        G_fShader_simple = glCreateShader(GL_FRAGMENT_SHADER);   
        // 读两个shader命令
        char *vs = textFileRead("Shader/simple.vert");  
    /* Shader程序直接获取修改全局变量如gl_Position, gl_Vertex等
    uniform float time;
    void main(void)  {  
        vec4 v = gl_Vertex;  
        v.z = sin(5.0*v.x + time)*0.25;  
        gl_Position =gl_ModelViewProjectionMatrix * v;  
    }
      */
        char *fs = textFileRead("Shader/simple.frag");
        const char *vv = vs;  
        const char *ff = fs; 
        // 绑定Shader命令
        glShaderSource(G_vShader_simple, 1, &vv, NULL);  
        glShaderSource(G_fShader_simple, 1, &ff, NULL);  
     
        free(vs);
        free(fs);

        // 编译与获得编译结果
        glCompileShader(G_vShader_simple);  
        glCompileShader(G_fShader_simple); 
        int checkResult;
        glGetShaderiv(G_vShader_simple, GL_COMPILE_STATUS, &checkResult);  
        if(GL_FALSE == checkResult) {
            printf("vertex shader compile error ");
            printShaderInfoLog(G_vShader_simple);
        }
        glGetShaderiv(G_fShader_simple, GL_COMPILE_STATUS, &checkResult);  
        if(GL_FALSE == checkResult) {
            printf("fragment shader compile error ");
            printShaderInfoLog(G_fShader_simple);
        }

        // 创建一个着色器程序
        G_shaderProgram = glCreateProgram();  
        // 装载着色器对象
        glAttachShader(G_shaderProgram, G_vShader_simple);  
        glAttachShader(G_shaderProgram, G_fShader_simple);  
        // 链接着色器程序
        glLinkProgram(G_shaderProgram);  
        glGetProgramiv(G_fShader_simple, GL_LINK_STATUS, &checkResult);  
        if(GL_FALSE == checkResult) {
            printf("shader link error ");
            printProgramInfoLog(G_shaderProgram);
        }
     
    附获取着色器对象错误Log的程序
    void printProgramInfoLog(GLuint programObject) {
        GLint logLen = 0, writtenLen;
        glGetShaderiv(programObject, GL_INFO_LOG_LENGTH , &logLen);       
        if (logLen > 0) {
            GLchar* info_log = (GLchar*)malloc(logLen);
            glGetProgramInfoLog(programObject, logLen, &writtenLen, info_log);  
            printf("%s ", info_log);
            free (info_log);
        }
    }

    6. display()函数中采用非固定管线Shader绘制
    //用初始化的着色器程序G_shaderProgram画一个茶壶,传入Uniform参数time
        static float shaderTime = 0.0f;
        glUseProgram(G_shaderProgram);

        GLint location =glGetUniformLocation(G_shaderProgram,"time");
        glUniform1f(location, shaderTime);

        glPushMatrix();
        glTranslatef(-1.0f, 0.0f, 0.0f);
        glutWireTeapot(1.0);
        glPopMatrix();
        shaderTime += 1.0f;

        glUseProgram(0);


  • 相关阅读:
    Jquery 图片预览插件 imgPreview
    对request.getSession(false)的理解(附程序员常疏忽的一个漏洞)
    JavaScript拖拽实现(附注释),最经典!最简单!短小精悍!
    如何使用VC++写一个小程序来检测.NetFrameWork版本
    利用TreeView实现C#工具箱效果
    JavaScript中json对象和string对象之间的转化
    Ubuntu Server上搭建可用于生产环境的ASP.NET服务器
    winexec()函数的参数说明(c++)
    C#对文件夹的判断、创建、移动、删除
    C#程序不用安装.NET环境运行(让C#程序脱离.net框架)
  • 原文地址:https://www.cnblogs.com/updateofsimon/p/4535892.html
Copyright © 2011-2022 走看看