OpenGL三角形的双面不同颜色的绘制

对于一个三角形,我要给它正反面不同的颜色。然后通过旋转,看出它的效果。

我只想到了2种方法,下面我来写一下这两种方法。

第一种方法,通过角度的判断重设glColor3f的参数(这种方法局限性很大,不推荐,不喜欢的可以直接跳过看第二种)。

对于一个平面,我们知道,当它旋转到一定角度的时候,它就变成了一条线,那么,我们只要对这个角度进行一下判断就可以了。

下面是我的测试代码:

#include <GL/glut.h>

GLfloat yrot; //饶y轴旋转

void display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
	glLoadIdentity(); // 重置当前的模型观察矩阵
	glTranslatef(0.0f, 0.0f, -5.0f); // 移入屏幕5个单位
	glColor3f(1.0f, 0.0f, 0.0f); // 颜色设置为红色
	if ((int)yrot % 360 > 90 && (int)yrot % 360 < 270)
		glColor3f(1.0f, 1.0f, 0.0f); // 黄色
	glRotatef(yrot, 0.0f, 1.0f, 0.0f);
	glBegin(GL_TRIANGLES); // 开始绘制三角形
		glVertex3f(0.0f, 1.0f, 0.0f); // 上顶点
		glVertex3f(-1.0f, -1.0f, 0.0f); // 左下顶点
		glVertex3f(1.0f, -1.0f, 0.0f); // 右下顶点
	glEnd(); // 结束绘制
	glutPostRedisplay(); // 重绘
	glFlush(); // 强制刷新缓冲

}

第二种方法,在同一个地方绘制两个三角形(不同颜色的),然后通过剔除多边形背面的方式实现。

先来介绍一下绘制方式,在默认情况下,逆时针绘制的是正面,顺时针绘制的是背面,当然,可以通过glFrontFace(GL_CCW)是它相反。

既然如此,那么就可以绘制两个正好相反的三角形,一个正面(红色)一个背面(蓝色)。

然后对其剔除背面就可以了。

如何剔除?

void glCullFace(GLenum mode); 通过这个函数

看一下它的参数:

GL_FRONT: 剔除正面多边形

GL_BACK:剔除背面多边形

GL_FRONT_AND_BACK:剔除所有多边形

那么这里,就使用GL_BACK这个参数。

然后要使用剔除功能的时候,启用一下glEnable(GL_CULL_FACE);即可。

接下来我来说一下实现的原理:

在绘制的时候是一个正面(红色)一个背面(蓝色)。

在启用glEnable(GL_CULL_FACE);剔除的功能后,我们告诉OpenGL说:“我看不见的你给我剔除了把!”。

一开始,我们看到的是红色三角形,因为它是正面。OpenGL认为,看得见的是正面,看不见的是背面。

其实,我们可以这么想,对于这两个三角形,一个红色三角形,一个蓝色三角形,因为被剔除了背面,所以,它们始终只有一个面,即正面。

当这两个三角形,不断旋转,旋转到红色三角形即将没有了的时候,这个时候,是不是原本是正面的红色三角形要变成了背面(因为看不见了嘛~)?结果就要被剔除了,然后此时,原本是背面的蓝色三角形,变成了正面,因为我们可以看到正面,所以接下来看到的就是蓝色三角形了。

下面,我贴一下这种方法的源码:

#include <GL/glut.h>

GLfloat yrot; //饶y轴旋转

void display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
	glLoadIdentity(); // 重置当前的模型观察矩阵
	glTranslatef(0.0f, 0.0f, -5.0f); // 移入屏幕5个单位
	glColor3f(1.0f, 0.0f, 0.0f); // 颜色设置为红色
	glRotatef(yrot, 0.0f, 1.0f, 0.0f);
	glBegin(GL_TRIANGLES); // 开始绘制三角形
		glVertex3f(0.0f, 1.0f, 0.0f); // 上顶点
		glVertex3f(-1.0f, -1.0f, 0.0f); // 左下顶点
		glVertex3f(1.0f, -1.0f, 0.0f); // 右下顶点
	glEnd(); // 结束绘制
	glColor3f(0.0f, 1.0f, 1.0f); // 颜色设置为蓝色
	glBegin(GL_TRIANGLES); // 反方向绘制
		glVertex3f(1.0f, -1.0f, 0.0f);
		glVertex3f(-1.0f, -1.0f, 0.0f);
		glVertex3f(0.0f, 1.0f, 0.0f);
	glEnd();
	yrot += 0.2f;
	glutPostRedisplay(); // 重绘
	glFlush(); // 强制刷新缓冲

}

void initGL()
{
	glViewport(0, 0, 300, 300); // 重置当前的视口
	glMatrixMode(GL_PROJECTION); // 选择投影矩阵
	glLoadIdentity(); // 重置投影矩阵
	gluPerspective(45.0f, (GLfloat)300 / (GLfloat)300, 0.1f, 100.0f); // 设置视口的大小
	glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵
	glLoadIdentity(); // 重置模型观察矩阵

	glShadeModel(GL_SMOOTH); // 平滑投影
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 黑色背景
	glClearDepth(1.0f); // 设置深度缓存
	glEnable(GL_DEPTH_TEST); // 启用深度测试
	glDepthFunc(GL_LEQUAL);	// 深度测试类型
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 透视修正

	glCullFace(GL_BACK); // 剔除背面
	glEnable(GL_CULL_FACE); // 启用剔除功能
}

int main(int argc, char *argv[])
{
	glutInit(&argc, argv); // 初始化GLUT
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // 设置显示模式(这里是单缓存和RGB颜色模式的窗口)
	glutInitWindowSize(300, 300); // 设置窗口大小
	glutInitWindowPosition(300, 300); // 设置窗口初始位置
	glutCreateWindow("双面绘制三角形"); // 创建一个窗口
	initGL(); // OpenGL的设置
	glutDisplayFunc(display); // 注册一个绘图函数
	glutMainLoop(); // 进入GLUT事件处理循环
	return 0;
}

OpenGL源码:http://www.eyesourcecode.com/forum-OpenGL-1.html

OpenGL三角形的双面不同颜色的绘制

时间: 2024-12-12 02:42:52

OpenGL三角形的双面不同颜色的绘制的相关文章

Android学习笔记&mdash;&mdash;OpenGL ES的基本用法、绘制流程与着色器编译

首先声明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. 在Android.iOS等移动平台上,开发者可以使用跨平台应用编程接口创建二维或者三维图形,或进行图像处理和计算机视觉应用,结合两者将能构建丰富有趣的交互体验.前者称为OpenGL,后者称为OpenCV,不过本文主要介绍前者,OpenCV在后续文章中涉及.OpenGL应用于桌面系统的历史已经很长了,但考虑到移动平台的特点(计算能力.性能等),将

[转]OpenGL 通过VBO实现顶点数组绘制顶点

#include "stdlib.h" #include <OpenGL/glext.h> #include <GLUT/GLUT.h> #define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes)) #define VERTICES 0 #define INDICES 1 #define NUM_BUFFERS 6 GLuint buffers[NUM_BUFFERS]; GLfloat vertices[][

OpenGL(三)之基础绘制篇

本文将会介绍使用OpenGL进行点,线,三角形乃至多边形的绘制,,, 下图是采用不同类型的图形效果 一.点 点”是一切的基础. OpenGL提供了一系列函数指定一个点.它们都以glVertex开头,后面跟一个数字和1~2个字母. 例如: glVertex2d glVertex2f glVertex3f glVertex3fv 等等. 数字表示参数的个数:2表示有两个参数,3表示三个,4表示四个. 字母表示参数的类型: s表示16位整数(OpenGL中将这个类型定义为GLshort), i表示32

Android OpenGL ES绘图教程之三 : 绘制图形

在定义了将要被OpenGL绘制的形状之后,你当然想要绘制它们.使用OpenGL ES 2.0绘制图形需要的代码可能比你想象的要多,因为API提供了大量的图形渲染管道控制接口. 这一章将介绍如何使用OpenGL ES 2.0 API绘制上一章中定义的形状 1. 初始化形状 在你做任何的绘制操作之前,你都必须进行初始化和加载计划绘制的形状.除非在执行的过程中形状所在的结构(原坐标)发生变化,你应该在render中的onSurfaceCreated()方法中初始化它们以提高内存和执行效率. publi

用OpenGL进行曲线、曲面的绘制

实验目的 1)理解Bezier曲线.曲面绘制的基本原理:理解OpenGL中一维.二维插值求值器的用法. 2)掌握OpenGL中曲线.曲面绘图的方法,对比不同参数下的绘图效果差异: 代码1:用四个控制点绘制一条三次Bezier曲线 #include "stdafx.h" #include <stdlib.h> #include <time.h> #include <GL/glut.h> //4个控制点的3D坐标--z坐标全为0 GLfloat ctrl

计算机图形学和OpenGL(二)坐标系和绘制点线函数

这节开始前我们先了解一下图元的概念.图形软件包中用来描述各种图形元素的函数称为图形输出原语,也称图元(primitive).而描述对象几何要素的输出图元一般称为几何图元.点和线是最简单的几何图元,本节就会简单介绍点和线段的绘制方法. 一.坐标系统. 坐标系统一般分为屏幕坐标和OpenGL中的绘图坐标. 在上一节中我们简单的写了个示例程序,程序中介绍了gluOrtho2D命令.我们可以利用该命令设定一个二维笛卡尔坐标系.该函数的四个变量制定的是显示图形x和y坐标范围.所以我们可以使用下面代码制定一

OpenGL下的VBO的图形绘制

为了避免反复向显卡传送相同的定点数据,绘制大量顶点数据时OpenGL下可以使用缓存对象(Buffer Object)来将数据上传到显卡. 准备数据 我们的显示数据为一正方体,如下所示 顶点数据结构为颜色(RGBA)法线(xyz)坐标(xyz) 顶点数据存储在vertices, 定点的索引数据存储在indices, 同时还需要缓存对象的句柄vertexBuffer和indexBuffer struct CUSTOM_VERTEX { float r, g, b, a; float nx, ny,

opengl基础学习专题 (三) 多边形绘制的几种样式

题外话 聪明人之所以不会成功,是由于他们缺乏坚韧的毅力. ——艾萨克·牛顿(1643年1月4日—1727年3月31日)英国 也许可以理解为 想更深一步的时候,坚持,努力和聪明缺一不可. 挺直腰杆在此向您致敬,愿您仍在天国 仍潇洒的思索着,奔跑着. 正文 在第二课中,我们学习了如何绘制几何图形,但大家如果多写几个程序,就会发现其实还是有些郁闷之处. 例如:点太小,难以看清楚:直线也太细,不舒服:或者想画虚线,但不知道方法只能用许多短直线,甚至用点组合而成. 这些问题将在本课中被解决. 下面就点.直

OpenGL学习(一)一个简单的绘制矩形程序

一段简单的绘制正方形的程序: #include <gl/glut.h> void display() { glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glVertex2f(-0.5,-0.5); glVertex2f(-0.5,0.5); glVertex2f(0.5,0.5); glVertex2f(0.5,-0.5); glEnd(); glFlush(); } int main(int argc,char**argv) { glu