OpenGL下实现图片满屏显示

102 篇文章 0 订阅
81 篇文章 2 订阅

实现图片满屏显示,最常用的用途是把一张图片作为显示窗体的背景图片。我这里有总两种方法:

 一、 正交模式显示背景图片

  1. 关闭深度测试
  2. 正交投影
  3. 设置四边形的尺寸为窗口四个角,将图片贴到Quad上
  4. 切换到透视模式下
  5. 开启深度测试
  6. 显示三维场景

绘制背景图片时必须关闭深度测试,否则会导致后面渲染的3d场景不能显示。 

在绘制3d场景时开启深度测试是为了保证3D模型绘制的正确性,主要指彼此的遮挡关系。

示例代码:

void display(void)
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glColor3f (1.0, 1.0, 1.0);  
  
	glDisable(GL_DEPTH_TEST);

	// 切换到正交模式
    glMatrixMode(GL_PROJECTION);  
    glLoadIdentity();  
    glOrtho(0, g_fWidth, 0, g_fHeight, 0, g_fDepth);  
    glMatrixMode(GL_MODELVIEW);  
    glLoadIdentity();  
	
	glDisable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);
	glBindTexture( GL_TEXTURE_2D, g_textureID );
 	glInterleavedArrays( GL_T2F_V3F, 0, g_bgVertices );
 	glDrawArrays( GL_QUADS, 0, 4 );	// 绘制背景图片
	glEnable(GL_LIGHTING);
	glDisable(GL_TEXTURE_2D);

    //  切换到三维场景
    glMatrixMode (GL_PROJECTION);       //回复原有的设置  
    glLoadIdentity ();  
	gluPerspective(30, g_fWidth/g_fHeight, 0.001, 100.0);
	glMatrixMode(GL_MODELVIEW);
    glLoadIdentity ();             
	gluLookAt(0, 5, 5, 0, 0, 0, 0, 1, 0);

	glEnable(GL_DEPTH_TEST);

	glPushMatrix();
	{
		glTranslatef(0, 0, 0);

		glRotatef(g_xAngle, 1, 0, 0);
		glRotatef(g_yAngle, 0, 1, 0);

		glCallList(g_modelId);	// 绘制三维图形
	} glPopMatrix();

	glFlush();
	// glutPostRedisplay();
}

 二、 透视模式显示背景图片

背景图片和3d场景都在透视模式下显示,此时为了精确实现图片满屏,需要将窗口四个角的坐标投影到3d场景中,计算出对应的四边形四个角坐标,然后图片贴上去。步骤如下:
  1. 窗口四角 投影到3d场景中,使用gluUnProject函数 计算出新的quad
  2. 关闭深度测试
  3. 绘制quad,贴图
  4. 开启深度测试
  5. 绘制3d场景
示例代码:

void display(void)
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glColor3f (1.0, 1.0, 1.0);  

	ComputeBackgroundQuad();

	glDisable(GL_DEPTH_TEST);

	// 绘制背景图片
	glDisable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);
	glBindTexture( GL_TEXTURE_2D, g_textureID );

	glEnableClientState( GL_VERTEX_ARRAY );
	glEnableClientState( GL_TEXTURE_COORD_ARRAY );
 	glInterleavedArrays( GL_T2F_V3F, 0, g_bgVertices );
 	glDrawArrays( GL_QUADS, 0, 4 );
	glDisableClientState( GL_VERTEX_ARRAY );
	glDisableClientState( GL_TEXTURE_COORD_ARRAY );

	glDisable(GL_TEXTURE_2D);

	glEnable(GL_LIGHTING);

	glEnable(GL_DEPTH_TEST);

	glPushMatrix();
	{
		glTranslatef(0, 0, g_fOffset);

		glRotatef(g_xAngle, 1, 0, 0);
		glRotatef(g_yAngle, 0, 1, 0);

		glCallList(g_modelId);
	} glPopMatrix();

	glFlush();
	// glutPostRedisplay();
}
void ComputeBackgroundQuad()
{
	GLint	viewport[4];
	GLdouble projMatrix[16];
	GLdouble modelMatrix[16];

	// glGetDoublev(GL_PROJECTION, projMatrix);  缺少matrix但是编译不报错~
	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
	glGetIntegerv(GL_VIEWPORT, viewport);

	// 
	double objX, objY, objZ;
	const double winZ = 0;  // 0 / 1
	gluUnProject(0, 0, winZ, modelMatrix, projMatrix, viewport, &objX, &objY, &objZ);
	g_bgVertices[0].x = objX;
	g_bgVertices[0].y = objY;
	g_bgVertices[0].z = objZ;

	gluUnProject(g_fWidth, 0, winZ, modelMatrix, projMatrix, viewport, &objX, &objY, &objZ);
	g_bgVertices[1].x = objX;
	g_bgVertices[1].y = objY;
	g_bgVertices[1].z = objZ;

	gluUnProject(g_fWidth, g_fHeight, winZ, modelMatrix, projMatrix, viewport, &objX, &objY, &objZ);
	g_bgVertices[2].x = objX;
	g_bgVertices[2].y = objY;
	g_bgVertices[2].z = objZ;

	gluUnProject(0, g_fHeight, winZ, modelMatrix, projMatrix, viewport, &objX, &objY, &objZ);
	g_bgVertices[3].x = objX;
	g_bgVertices[3].y = objY;
	g_bgVertices[3].z = objZ;
}

最终的效果如图:


  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值