OpenGL绘制多边形边框线

2024-05-02 14:32

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

利用OpenGL如何在绘制多边形的时候同时绘制其变现呢?
网上一种解决方案是利用glPolygonMode,将多边形绘制两次,一次绘制面,一次绘制边。这种方案理论上是可行的(我没有试过),但是OpenGL要进行两次绘制,效率上明显是不高的。

如果以顺时针绘制则是反面,逆时针绘制则是正面 
// 设置正面为填充模式
glPolygonMode(GL_FRONT, GL_FILL);
// 设置反面为线形模式
glPolygonMode(GL_BACK, GL_LINE);
// 设置逆时针绘制一个正方形

参考了Easy wireframe display with barycentric coordinates这篇博文,参考其方法,使用Barycentric Coordinates(重心坐标),在GLSL中直接进行判断,如果离边近的像素就渲染成别的颜色。

要注意的主要有两点:
1. 在定点坐标数组中增加一个重心坐标属性,如下图。
重心坐标
2. 在GLSL中对重心坐标进行判断。

参考代码如下:
(使用了GLEW、SFML和GLM第三方库)

#include <GL/glew.h>
#include <SFML/Window.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>// Shader sources
const GLchar* vertexSource ="#version 150 core\n""varying vec3 vBC;""attribute vec3 position;""attribute vec3 barycentric;""uniform mat4 model;""uniform mat4 view;""uniform mat4 proj;""void main() {""   vBC = barycentric;""   gl_Position = proj * view * model * vec4(position, 1.0);""}";
const GLchar* fragmentSource ="#version 150 core\n""varying vec3 vBC;""void main() {""   if(any(lessThan(vBC, vec3(0.005)))){""       gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);""   }""   else{""       gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);""   }""}";int main()
{sf::ContextSettings settings;settings.depthBits = 24;settings.stencilBits = 8;sf::Window window(sf::VideoMode(800, 600, 32), "OpenGL", sf::Style::Titlebar | sf::Style::Close, settings);// Initialize GLEWglewExperimental = GL_TRUE;glewInit();glEnable(GL_DEPTH_TEST);// Create Vertex Array ObjectGLuint vao;glGenVertexArrays(1, &vao);glBindVertexArray(vao);// Create a Vertex Buffer Object and copy the vertex data to itGLuint vbo;glGenBuffers(1, &vbo);GLfloat vertices[] = {// 三维定点坐标        //重心坐标-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,-0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f};glBindBuffer(GL_ARRAY_BUFFER, vbo);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// Create and compile the vertex shaderGLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexSource, NULL);glCompileShader(vertexShader);// Create and compile the fragment shaderGLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentSource, NULL);glCompileShader(fragmentShader);// Link the vertex and fragment shader into a shader programGLuint shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);glUseProgram(shaderProgram);// Specify the layout of the vertex dataGLint posAttrib = glGetAttribLocation(shaderProgram, "position");glEnableVertexAttribArray(posAttrib);glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);GLint baryAttrib = glGetAttribLocation(shaderProgram, "barycentric");glEnableVertexAttribArray(baryAttrib);glVertexAttribPointer(baryAttrib, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));// Set up projectionglm::mat4 view = glm::lookAt(glm::vec3(1.5f, 1.5f, 1.5f),glm::vec3(0.0f, 0.0f, 0.0f),glm::vec3(0.0f, 0.0f, 1.0f));GLint uniView = glGetUniformLocation(shaderProgram, "view");glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));glm::mat4 proj = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 1.0f, 10.0f);GLint uniProj = glGetUniformLocation(shaderProgram, "proj");glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));glm::mat4 model;GLint uniModel = glGetUniformLocation(shaderProgram, "model");model = glm::rotate(model, glm::radians(180.0f), glm::vec3(0.0f, 0.0f, 1.0f));glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));while (window.isOpen()){sf::Event windowEvent;while (window.pollEvent(windowEvent)){switch (windowEvent.type){case sf::Event::Closed:window.close();break;}}// Clear the screen to blackglClearColor(0.0f, 0.0f, 0.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Draw cubeglDrawArrays(GL_TRIANGLES, 0, 36);// Swap bufferswindow.display();}glDeleteProgram(shaderProgram);glDeleteShader(fragmentShader);glDeleteShader(vertexShader);glDeleteBuffers(1, &vbo);glDeleteVertexArrays(1, &vao);return EXIT_SUCCESS;
}

最后的渲染效果如下:
Wireframe

如图渲染效果不是很好,有明显的锯齿。如何反锯齿,参看原始博文Easy wireframe display with barycentric coordinates。

这篇关于OpenGL绘制多边形边框线的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

使用Python绘制蛇年春节祝福艺术图

《使用Python绘制蛇年春节祝福艺术图》:本文主要介绍如何使用Python的Matplotlib库绘制一幅富有创意的“蛇年有福”艺术图,这幅图结合了数字,蛇形,花朵等装饰,需要的可以参考下... 目录1. 绘图的基本概念2. 准备工作3. 实现代码解析3.1 设置绘图画布3.2 绘制数字“2025”3.3

使用Python绘制可爱的招财猫

《使用Python绘制可爱的招财猫》招财猫,也被称为“幸运猫”,是一种象征财富和好运的吉祥物,经常出现在亚洲文化的商店、餐厅和家庭中,今天,我将带你用Python和matplotlib库从零开始绘制一... 目录1. 为什么选择用 python 绘制?2. 绘图的基本概念3. 实现代码解析3.1 设置绘图画

Python绘制土地利用和土地覆盖类型图示例详解

《Python绘制土地利用和土地覆盖类型图示例详解》本文介绍了如何使用Python绘制土地利用和土地覆盖类型图,并提供了详细的代码示例,通过安装所需的库,准备地理数据,使用geopandas和matp... 目录一、所需库的安装二、数据准备三、绘制土地利用和土地覆盖类型图四、代码解释五、其他可视化形式1.

如何用Python绘制简易动态圣诞树

《如何用Python绘制简易动态圣诞树》这篇文章主要给大家介绍了关于如何用Python绘制简易动态圣诞树,文中讲解了如何通过编写代码来实现特定的效果,包括代码的编写技巧和效果的展示,需要的朋友可以参考... 目录代码:效果:总结 代码:import randomimport timefrom math

【WebGPU Unleashed】1.1 绘制三角形

一部2024新的WebGPU教程,作者Shi Yan。内容很好,翻译过来与大家共享,内容上会有改动,加上自己的理解。更多精彩内容尽在 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信号:digital_twin123 在 3D 渲染领域,三角形是最基本的绘制元素。在这里,我们将学习如何绘制单个三角形。接下来我们将制作一个简单的着色器来定义三角形内的像素

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

利用matlab bar函数绘制较为复杂的柱状图,并在图中进行适当标注

示例代码和结果如下:小疑问:如何自动选择合适的坐标位置对柱状图的数值大小进行标注?😂 clear; close all;x = 1:3;aa=[28.6321521955954 26.2453660695847 21.69102348512086.93747104431360 6.25442246899816 3.342835958564245.51365061796319 4.87

YOLOv8/v10+DeepSORT多目标车辆跟踪(车辆检测/跟踪/车辆计数/测速/禁停区域/绘制进出线/绘制禁停区域/车道车辆统计)

01:YOLOv8 + DeepSort 车辆跟踪 该项目利用YOLOv8作为目标检测模型,DeepSort用于多目标跟踪。YOLOv8负责从视频帧中检测出车辆的位置,而DeepSort则负责关联这些检测结果,从而实现车辆的持续跟踪。这种组合使得系统能够在视频流中准确地识别并跟随特定车辆。 02:YOLOv8 + DeepSort 车辆跟踪 + 任意绘制进出线 在此基础上增加了用户

OPENGL顶点数组, glDrawArrays,glDrawElements

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