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\n", 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\n");
        printShaderInfoLog(G_vShader_simple);
    }
    glGetShaderiv(G_fShader_simple, GL_COMPILE_STATUS, &checkResult);  
    if(GL_FALSE == checkResult) {
        printf("fragment shader compile error\n");
        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\n");
        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\n", 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);

时间: 2024-10-25 04:15:05

OpenGL 基础知识的相关文章

【OpenGL基础篇】——使用面向对象方法封装OpenGL函数(一)

OpenGL是一个开源的图形库,既可开发二维图形软件,也可开发三维图形软件.许多知名应用就是基于OpenGL开发出来,如著名的Artoolkit和Unity3D. GLUT是代表OpenGL应用工具包,英文全称为OpenGL Utility Toolkit,是一个和窗口系统无关的软件包,它由Mark Kilgard在SGI时写的.作为AUX库的功能更强大的替代品,用于隐藏不同窗口系统API的复杂性.(百度百科) 因为OpenGL的API是底层图形库API,使用起来还是有些复杂,所以,我打算使用面

opengl基础学习专题 (二) 点直线和多边形

题外话 随着学习的增长,越来越觉得自己很水.关于上一篇博文中推荐用一个 学习opengl的 基于VS2015的 simplec框架.存在 一些问题. 1.这个框架基于VS 的Debug 模式下,没有考虑Release版本 2.这个版本中chead,c基础头文件中有些宏设计的不好,例如 //4.0 控制台打印错误信息 #ifndef CERR #define CERR(fmt,...) fprintf(stderr,fmt,##__VA_ARGS__),putchar('\n') #endif/*

OpenGL基础图形编程

一.OpenGL与3D图形世界1.1.OpenGL使人们进入三维图形世界 我们生活在一个充满三维物体的三维世界中,为了使计算机能精确地再现这些物体,我们必须能在三维空间描绘这些物体.我们又生活在一个充满信息的世界中,能否尽快地理解并运用这些信息将直接影响事业的成败,所以我们需要用一种最直接的形式来表示这些信息. 最近几年计算机图形学的发展使得三维表现技术得以形成,这些三维表现技术使我们能够再现三维世界中的物体,能够用三维形体来表示复杂的信息,这种技术就是可视化(Visualization)技术.

Android 并发编程:(一)基础知识 —— 架构和组件

本章节所有内容皆为原创,如需转载,请注明出处. http://blog.csdn.net/manoel/article/details/38462631 写在前面的话 很久没写博客了,一是因为自身水平有限,怕误人子弟:二是因为感觉没什么可写的:三是因为时间有限,要寻找工作.学习和生活之间的平衡. 最近一直在研究和梳理Android多线程编程的东西,希望能够把这些分享给大家. 想必做过Android应用开发的同学应该都会知道,多线程是一个特别"诡异"的地方.之所以称为"诡异&q

[WebGL入门]三,3D绘图的基础知识

注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正. 二维和三维 三维空间--我们生活这个这个现实的世界就是一个三维空间. 在三维的世界里,所有的东西都由横,竖,深度.将这些东西重现,就是一个实时3D渲染.但是再现这个3D空间,我们是在一个2D的显示器上来实现的. 电脑和手机的屏幕,都是一个2D的显示器.至少现在还没有一个3D的显示设备,当然,研

IOS-OC的基础知识

IOS学习之路--OC的基础知识 1.项目经验 2.基础问题 3.指南认识 4.解决思路 ios开发三大块: 1.Oc基础 2.CocoaTouch框架 3.Xcode使用 -------------------- CocoaTouch Media Core Services Core OS -------------------- System Framework OC的类声明,定义域 OC关键字定义为  @class O-C特有的语句for(..in ..)迭代循环,其他的条件和循环语句和c

MySQL数据库基础知识

day02 MySQL数据库基础知识 一.基础知识概述: 基础决定你这门课程的学习成败!只有学习好这些基础知识以后,你才能真正的运用自如.才能够对数据库有更深入的了解,道路才会越走越远. 二.基础知识: 1.数据库(database):数据库就好比是一个物理的文档柜,一个容器,把我们整理好的数据表等等归纳起来. 创建数据库命令:        create database 数据库名; 2.查看数据库         show databases; 3.打开指定的数据库         use 

linux入门基础知识及简单命令介绍

linux入门基础知识介绍 1.计算机硬件组成介绍 计算机主要由cpu(运算器.控制器),内存,I/O,外部存储等构成. cpu主要是用来对二进制数据进行运算操作,它从内存中取出数据,然后进行相应的运算操作.不能从硬盘中直接取数据. 内存从外部存储中取出数据供cpu运存.内存的最小单位是字节(byte) 备注:由于32的cpu逻辑寻址能力最大为32内存单元.因此32位cpu可以访问的最大内存空间为:4GB,算法如下: 2^32=2^10*2^10*2^10*2^2 =1024*1024*1024

BroadcastReceive基础知识总结

BroadcastReceive基础知识总结 1.BroadcastReceive简介 BroadcastReceive也就是"广播接收者"的意思,顾名思义,就是用来接收来自系统和应用中的广播 在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能,当网络状态改变时,系统会产生一条广播,接收到这条广播,就能及时的做出提示和保存数据等操作,当电池的电量改变的时候,系统会产生一条广播,接收到这条广播就能在电量低的时候告知用户