OpenGL -版本-扩展

1. 检查自己的OpenGL版本

// glGetString 函数
const char* version = (const char*)glGetString(GL_VERSION);
printf("OpenGL 版本:%s\n",version);
/*
	glGetString(GL_VERSION); 返回一个表示版本的字符串,格式为 X.X.X 
	这就是三个整数,用少数点隔开,第一个数表示OpenGL主版本号,第二个
	数表示OpenGL次版本号,第三个数表示厂商发行代号。
*/

// 通过 sscanf 函数,也可以把字符串分成三个整数,以便详细的进行判断
int main_vsersion,sub_version,release_version;
const char* version = (const char*)glGetString(GL_VERSION);
sscanf(version,"%d.%d.%d",&main_version,&sub_version,&release_version);
printf("OpenGL 版本:%s\n",version);
printf("主版本号:%d\n",main_version);
printf("次版本号:%d\n",sub_version);
printf("发行版本号:%d\n",release_version);

// 返回OpenGL的提供厂商
glGetString(GL_VERSION);
// 返回执行 OpenGL渲染的设备
glGetString(GL_RENDERER);
// 返回所有支持的扩展,每两个扩展之间用空格隔开

2. EXT 扩展和 ARB 扩展

EXT 扩展是由多个厂商共同协商形成的扩展,在扩展名字中,“提供扩展的厂商”一栏
将不再是具体的厂商名,而是EXT三个字母。例如GL_EXT_bgra 就是一个EXT扩
展。

ARB扩展不仅是由多个厂商共同协商而成,还需要经过 OpenGL 体系结构审核委员
会(即ARB) 的确认,在扩展名字中,“提供扩展的厂商” 一栏不再是具体的厂商名字,
而是ARB 三个字母。比如 GL_ARB_imaging ,就是一个ARB 扩展。

程序中,判断OpenGL 是否支持某个扩展
// glGetString(GL_EXTENSIONS) 会返回 当前 OpenGL所支持的所有扩展的名字,中间用空格分开,这个就是我们判断是否支持某个扩展的依据。
#include <string.h>
int hasExtension(const char* name)
{
	const char* extensions = (const char*)glGetString(GL_EXECTIONS);
	// 指针移动
	const char* end = extensions + strlen(extensions);
	size_t name_length = strlen(name);
	
	while(extensions < end)
	{
		// 函数功能为在一个串中查找给定字符的第一个匹配之处。函数原型为:char *strchr(const char *str, int c)
		size_t position = strchr(extensions,' ') - extensions;
		// int strncmp ( const char * str1, const char * str2, size_t n );功能是把 str1 和 str2 进行比较,最多比较前 n 个字节,若str1与str2的前n个字符相同,则返回0;若s1大于s2,则返回大于0的值;若s1 小于s2,则返回小于0的值
		if(position == name_length && strncmp(extensions,name,position) == 0)
		{
			return 1;
		}
		extensions += (position + 1);
	}
	return 0;
}
/*
	该代码 判断 OpenGL 是否支持特定扩展,可以看到,判断时完全时字符串处理来实现的。
	循环检测,找到第一个空格,然后比较空格之前的字符串是否与指定的名字一致。若一致,说明扩展是被支持的,否则,继续比较。若所有内容都比较完,说明扩展不被支持。
*/
扩展的函数、常量,在命名时与通常的OpenGL函数、常量有少许区别。
扩展的函数。常量将以厂商的名字作为后缀。
比如ARB 扩展 ,所有ARB 扩展的函数、 函数名都以ARB 结尾,常量都以_ARB结尾
glGenBufferARB( 函数)
GL_ARRAY_BUFFER_ARB(常量)


若知道OpenGL 支持某个扩展,则如何调用扩展中的函数,大致的思路就是利用函数
指针。但是不幸的是,在不同的操作系统中,获取这些函数指针的方法各不相同。

使用GLEE, 代码由两个文件组成, 一个是GLee.c, 一个是 GLee.h 两个文件都放到自
己的源代码一起编译,运行时候,GLee 可以自动判断所有扩展是否被支持,如果支
持,GLEE 会自动读取对应的函数。
#include "GLee.h"
#include <GL/glut.h> // GLee.h 要在 glut.h 之前使用
// GLEE 也可以帮助我们判断 OpenGL 是否支持某个扩展,因此有了 GLEE,前面那个判断是否支持扩展的函数就不太必要了

示例代码

/*
	我们选择一个目前绝大多数显卡都支持的扩展 GL_ARB_window_pos,来说
    明如何使用 GLEE 来调用 OpenGL 扩展功能.

	通常我们在绘制像素时,需要用 glRasterPos*函数来指定绘制的位置.	
	glRasterPos*函数使用的不是屏幕坐标,这个坐标需要经过各种变换
	最后才得到屏幕上的窗口位置。

	通过 GL_ARB_window_pos 扩展,我们可以直接用屏幕上的坐标来指定绘制
	的位置,不再需要经过变换,这样在很多场合会显得简单。
*/
#include "GLee.h"
#include <GL/glut.h>

void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	if(GLEE_ARB_window_pos) // 如果支持GL_ARB_window_pos 则使用glWindowPos2iARB 函数,指定绘制位置
	{
		printf("支持 GL_ARB_window_pos\n");
		printf("使用 glWindowPos 函数\n");
		glWindowPos2iARB(100, 100);
	}
	else // 如果不支持 GL_ARB_window_pos 则只能使用 glRasterPos*系列函数
	{
		/*
			先计算出一个经过变换后能够得到 (100, 100)的坐标(x, y, z)
			然后调用 glRasterPos3d(x, y, z);
		*/
		GLint viewport[4];
		GLdouble modelview[16], projection[16];
		GLdouble x, y, z;

		printf("不支持 GL_ARB_window_pos\n");
		printf("使用 glRasterPos 函数\n");
		glGetIntegerv(GL_VIEWPORT, viewport);
        glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
        glGetDoublev(GL_PROJECTION_MATRIX, projection);
        gluUnProject(100, 100, 0.5, modelview, projection, viewport,
&x, &y, &z);
		glRasterPos3d(x, y, z);
	}
	{
		// 绘制一个 5*5 的像素块
		GLubyte pixels[5][5][4];
		// 把像素中的所有像素都设置为红色
		int i,j;
		for(i = 0;i < 5;++i)
		{
			for(j = 0;j < 5;++j)
			{
				pixels[i][j][0] = 255; // red
				pixels[i][j][1] = 0; // green
				pixels[i][j][2] = 0; // blue
				pixels[i][j][3] = 255; // alpha
			}
		}
		glDrawPixels(5, 5, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
	}
	glutSwapBuffers();
}
int main(int argc, char* argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(512, 512);
	glutCreateWindow("OpenGL");
	glutDisplayFunc(&display);
	glutMainLoop();
}
/*
	可以看到,使用了扩展以后,代码会简单得多了。不支持 
	GL_ARB_window_pos 扩展时必须使用较多的代码才能实现的功能,
	使用 GL_ARB_window_pos 扩展后即可简单的解决。
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值