OpenGL--图元

2024-05-09 07:38
文章标签 opengl 图元

本文主要是介绍OpenGL--图元,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 基础概念
    1,图元:组成3D物体最小的单位,包括:点,直线,多边形。就和化学里所有物体都是由原子组成的一样。
    2,点:数学上的点,只有位置,没有大小。但在计算机中,无论计算精度如何提高,始终不能表示一个无穷小的点。另一方面,无论图形输出设备(例如,显示器)如何精确,始终不能输出一个无穷小的点。默认情况下,OpenGL中的点将被画成单个的像素,虽然它可能足够小,但并不会是无穷小。同一像素上,OpenGL可以绘制许多坐标只有稍微不同的点,但该像素的具体颜色将取决于OpenGL的实现。当然,过度的注意细节就是钻牛角尖,我们大可不必花费过多的精力去研究“多个点如何画到同一像素上”。
    3,直线:数学上的直线没有宽度,但OpenGL的直线则是有宽度的。同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。
    4,多边形:是由多条线段首尾相连而形成的闭合区域。OpenGL规定,一个多边形必须是一个“凸多边形”(其定义为:多边形内任意两点所确定的线段都在多边形内,由此也可以推导出,凸多边形不能是空心的)。多边形可以由其边的端点(这里可称为顶点)来确定。(注意:如果使用的多边形不是凸多边形,则最后输出的效果是未定义的——OpenGL为了效率,放宽了检查,这可能导致显示错误。要避免这个错误,尽量使用三角形,因为三角形都是凸多边形)
    5,多边形细节:一,多边形可以通过glPolygonMode来指定绘制的模式,包括填充,线框,点三种模式。二,相邻的填充多边形如果共享一条边或一个顶点,共享部分像素只绘制一次,它们只包含在其中一个多边形中。三,多边形具有正面与背面之分,默认逆时针连接的顶点所围成的面是正面,可以通过glFrontFace改变。四,可以通过glCullFace剔除不需要绘制的面,提高效率。五,opengl只能渲染凸多边形,而为了绘制非凸多边形,一般把他们分解为几个凸多边形,然后再分别绘制。然而这种做法我们就不能使用glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)来绘制它的真正轮廓了(即内部的边也会绘制),这时我们可以通过glEdgeFlag来标志顶点是否是边界边,默认顶点都是边界边。(默认逆时针连接时,对于非边界边就不会绘制)
    6,可以想象,通过点、直线和多边形,就可以组合成各种几何图形。甚至于,你可以把一段弧看成是很多短的直线段相连,这些直线段足够短,以至于其长度小于一个像素的宽度。这样一来弧和圆也可以表示出来了。通过位于不同平面的相连的小多边形,我们还可以组成一个“曲面”。
    注:它们的实际渲染其实还受是否开启了抗锯齿处理和多重采样功能的影响,如果没有开启,像一些尺寸大小会进行四舍五入取邻近的整数值,而开启了就允许使用非整数的宽度,这样位于边界处的像素一般会画得淡一些。
    7,OpenGL的图元总共有10种:如下图,
    这里写图片描述

  • 实例程序
    示例1:画出正玄函数的图形

#include "GLTools.h"
#include "GLShaderManager.h"
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#endif#include <math.h>const GLfloat factor = 0.3f;
void display(void)
{GLfloat x;glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_LINES); //线段glVertex2f(-1.0f, 0.0f);glVertex2f(1.0f, 0.0f);         // 画x轴glVertex2f(0.0f, -1.0f);glVertex2f(0.0f, 1.0f);         // 画y轴glEnd();glBegin(GL_LINE_STRIP);//线带for(x=-1.0f/factor; x<1.0f/factor; x+=0.01f){glVertex2f(x*factor, sin(x)*factor);}glEnd();glFlush();  //用于单缓冲中
}int main(int argc,char* argv[])
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(250, 250);glutInitWindowPosition(100, 100);glutCreateWindow("sinFunc");glutDisplayFunc(display);glutMainLoop();return 0;
}

这里写图片描述

示例2:直线点画模式(其实就是画虚线)

#include "GLTools.h"
#include "GLShaderManager.h"
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#endif
//带参宏定义画线
#define drawOneLine(x1, y1, x2, y2) glBegin(GL_LINES);  \glVertex2f(x1, y1);  glVertex2f(x2, y2);    glEnd();void init()
{glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_FLAT);
}void display()
{glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0);glEnable(GL_LINE_STIPPLE); //激活点画线功能/*注:glLineStipple设置当前点画模式,参数1表重复因子(即本来连续像素 * 参数1  = 现在连续个数),参数2是一个由1或0组成的16位序列,从低位开始,如果为1则绘制这个像素,否则就不绘制。*/glLineStipple(1, 0x0101);drawOneLine(50.0, 125.0, 150.0, 125.0);glLineStipple(1, 0x00ff);drawOneLine(150.0, 125.0, 250.0, 125.0);glLineStipple(1, 0x1c47);drawOneLine(250.0, 125.0, 350.0, 125.0);glLineWidth(5.0);  //设置线宽度glLineStipple(1, 0x0101);drawOneLine(50.0, 100.0, 150.0, 100.0);glLineStipple(1, 0x00ff);drawOneLine(150.0, 100.0, 250.0, 100.0);glLineStipple(1, 0x1c47);drawOneLine(250.0, 100.0, 350.0, 100.0);/*重复因子设置为5(即:如果有2个连续为1的位,则后面2 * 5 = 10个连续绘制,反之,如果3个连续为0的位,则这里3 * 5 = 15个像素连续不绘制)*/glLineStipple(5, 0x1c47);drawOneLine(50, 50, 350, 50);glDisable(GL_LINE_STIPPLE); //关闭点画线功能glFlush();
}void reshape(int w, int h)
{glViewport(0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
}int main(int argc,char* argv[])
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(400, 150);glutInitWindowPosition(100, 100);glutCreateWindow("line");init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoop();return 0;
}

这里写图片描述

示例3:多边形的点画模式

#include "GLTools.h"
#include "GLShaderManager.h"
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#endifvoid display(void)
{//位图数据(32 * 32位的)GLubyte fly[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60,0x04, 0x60, 0x06, 0x20, 0x04, 0x30, 0x0C, 0x20,0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20,0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22,0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22,0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22,0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22,0x66, 0x01, 0x80, 0x66, 0x33, 0x01, 0x80, 0xCC,0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30,0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0,0x03, 0x31, 0x8c, 0xc0, 0x03, 0x33, 0xcc, 0xc0,0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30,0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08,0x10, 0x63, 0xC6, 0x08, 0x10, 0x30, 0x0c, 0x08,0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08};GLubyte halftone[] = {0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};glClear (GL_COLOR_BUFFER_BIT);glColor3f (1.0, 1.0, 1.0);glRectf (25.0, 25.0, 125.0, 125.0);  //绘制矩形/*glPolygonStipple:多边形点画模式,参数是一个指向32 * 32位图的指针,如果出现1对应的像素就被绘制,如果是0则不绘制*/glEnable (GL_POLYGON_STIPPLE); //激活多边形点画模式glPolygonStipple (fly);glRectf (125.0, 25.0, 225.0, 125.0);glPolygonStipple (halftone);glRectf (225.0, 25.0, 325.0, 125.0);glDisable (GL_POLYGON_STIPPLE); //关闭多边形点画模式glFlush ();
}void init (void)
{glClearColor (0.0, 0.0, 0.0, 0.0);glShadeModel (GL_FLAT);
}void reshape (int w, int h)
{glViewport (0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode (GL_PROJECTION);glLoadIdentity ();gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h);
}void keyboard(unsigned char key, int x, int y)
{switch (key){case 27: //esc键exit(0);break;}
}int main(int argc, char** argv)
{glutInit(&argc, argv);glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);glutInitWindowSize (350, 150);glutCreateWindow ("polys");init ();glutDisplayFunc(display);glutReshapeFunc(reshape);glutKeyboardFunc (keyboard);  //键盘按键回调glutMainLoop();return 0;  
}

这里写图片描述

这篇关于OpenGL--图元的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/972790

相关文章

OPENGL顶点数组, glDrawArrays,glDrawElements

顶点数组, glDrawArrays,glDrawElements  前两天接触OpenGL ES的时候发现里面没有了熟悉的glBegin(), glEnd(),glVertex3f()函数,取而代之的是glDrawArrays()。有问题问google,终于找到答案:因为OpenGL ES是针对嵌入式设备这些对性能要求比较高的平台,因此把很多影响性能的函数都去掉了,上述的几个函数都被移除了。接

OpenGL ES学习总结:基础知识简介

什么是OpenGL ES? OpenGL ES (为OpenGL for Embedded System的缩写) 为适用于嵌入式系统的一个免费二维和三维图形库。 为桌面版本OpenGL 的一个子集。 OpenGL ES管道(Pipeline) OpenGL ES 1.x 的工序是固定的,称为Fix-Function Pipeline,可以想象一个带有很多控制开关的机器,尽管加工

OpenGL雾(fog)

使用fog步骤: 1. enable. glEnable(GL_FOG); // 使用雾气 2. 设置雾气颜色。glFogfv(GL_FOG_COLOR, fogColor); 3. 设置雾气的模式. glFogi(GL_FOG_MODE, GL_EXP); // 还可以选择GL_EXP2或GL_LINEAR 4. 设置雾的密度. glFogf(GL_FOG_DENSITY, 0

opengl纹理操作

我们在前一课中,学习了简单的像素操作,这意味着我们可以使用各种各样的BMP文件来丰富程序的显示效果,于是我们的OpenGL图形程序也不再像以前总是只显示几个多边形那样单调了。——但是这还不够。虽然我们可以将像素数据按照矩形进行缩小和放大,但是还不足以满足我们的要求。例如要将一幅世界地图绘制到一个球体表面,只使用glPixelZoom这样的函数来进行缩放显然是不够的。OpenGL纹理映射功能支持将

OpenGL ES 2.0渲染管线

http://codingnow.cn/opengles/1504.html Opengl es 2.0实现了可编程的图形管线,比起1.x的固定管线要复杂和灵活很多,由两部分规范组成:Opengl es 2.0 API规范和Opengl es着色语言规范。下图是Opengl es 2.0渲染管线,阴影部分是opengl es 2.0的可编程阶段。   1. 顶点着色器(Vert

OpenGL/GLUT实践:流体模拟——数值解法求解Navier-Stokes方程模拟二维流体(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub:A-UESTCer-s-Code 文章目录 1 实现效果2 实现过程2.1 流体模拟实现2.1.1 网格结构2.1.2 数据结构2.1.3 程序结构1) 更新速度场2) 更新密度值 2.1.4 实现效果 2.2 颜色设置2.2.1 颜色绘制2.2.2 颜色交互2.2.3 实现效果 2.3 障碍设置2.3.1 障碍定义2.3.2 障碍边界条件判定2.3.3 障碍实现2.3.

OpenGL——着色器画一个点

一、 绘制 在窗口中间画一个像素点: #include <GL/glew.h>#include <GLFW/glfw3.h>#include <iostream>using namespace std;#define numVAOs 1GLuint renderingProgram;GLuint vao[numVAOs];GLuintcreateShaderProgram (){c

试用GLFW并创建OpenGL和DX的环境

介绍GLFW GLFW官网:https://www.glfw.org/ GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan development on the desktop. It provides a simple API for creating windows, contex

鸿蒙(API 12 Beta6版)图形加速【OpenGL ES平台内插模式】超帧功能开发

超帧内插模式是利用相邻两个真实渲染帧进行超帧计算生成中间的预测帧,即利用第N-1帧和第N帧真实渲染帧预测第N-0.5帧预测帧,如下图所示。由于中间预测帧的像素点通常能在前后两帧中找到对应位置,因此内插模式的预测帧效果较外插模式更优。由于第N帧真实渲染帧需要等待第N-0.5帧预测帧生成并送显后才能最终送显,因此会新增1~2帧的响应时延。 OpenGL ES平台 业务流程 基于OpenGL

OpenGL DMA接口

Opengl的DMA版本接口主要作用是解决以前访问opengl对象, 必须先将对象绑定到当前状态机下才能访问的问题,这会导致驱动层需要去频繁的进行对象的引用查找。  比如以前非DMA版本的接口操作顶点数据  glGenBuffers(1, &vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo);glBufferData(GL_ARRAY_BUFFER, sizeof