尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
C++ OPENGL 贝塞尔曲线绘制
代码#include glad/glad.h #include GLFW/glfw3.h #include iostream #include vector struct Point { float x; float y; }; // 二次贝塞尔 Point bezier(float t, Point a, Point c, Point z) { return { (1 - t) * (1 - t) * a.x 2 * t * (1 - t) * c.x t * t * z.x, (1 - t) * (1 - t) * a.y 2 * t * (1 - t) * c.y t * t * z.y, }; } // 定义三次贝塞尔曲线的函数 void bezierCurve2(float t, std::vectorGLfloat controlPoints, GLfloat x, GLfloat y) { // 假设我们有4个控制点绘制一个三次贝塞尔曲线 GLfloat p0x controlPoints[0], p0y controlPoints[1]; GLfloat p1x controlPoints[2], p1y controlPoints[3]; GLfloat p2x controlPoints[4], p2y controlPoints[5]; GLfloat p3x controlPoints[6], p3y controlPoints[7]; x pow(1 - t, 3) * p0x 3 * t * pow(1 - t, 2) * p1x 3 * pow(t, 2) * (1 - t) * p2x pow(t, 3) * p3x; y pow(1 - t, 3) * p0y 3 * t * pow(1 - t, 2) * p1y 3 * pow(t, 2) * (1 - t) * p2y pow(t, 3) * p3y; } // 绘制贝塞尔曲线 void drawBezierCurve() { std::vectorGLfloat controlPoints {0.0, 0.0, 0.2, 0.5, 0.8, 0.5, 1.0, 1.0}; // 控制点 glBegin(GL_LINE_STRIP); for (float t 0.0; t 1.0; t 0.01) { GLfloat x, y; bezierCurve2(t, controlPoints, x, y); glVertex2f(x, y); } glEnd(); glBegin(GL_LINE_STRIP); for (float t 0.0; t 1.0; t 0.01) { auto pt bezier(t, {controlPoints[0], controlPoints[1]}, {controlPoints[2], controlPoints[3]}, {controlPoints[4], controlPoints[5]}); glVertex2f(pt.x, pt.y); } glEnd(); } // 计算贝塞尔曲线长度 float calcBezierCurveLen() { std::vectorGLfloat controlPoints {0.0, 0.0, 0.2, 0.5, 0.8, 0.5, 1.0, 1.0}; // 控制点 Point oldPt {0.0, 0.0}; float newLen 0; for (float t 0.0; t 1.0; t 0.01) { auto newP bezier(t, {controlPoints[0], controlPoints[1]}, {controlPoints[2], controlPoints[3]}, {controlPoints[4], controlPoints[5]}); newLen sqrt(pow(newP.x - oldPt.x, 2.0) pow(newP.y - oldPt.y, 2.0)); oldPt newP; } return newLen; } void framebuffer_size_callback(GLFWwindow *window, int width, int height); void processInput(GLFWwindow *window); // settings const unsigned int SCR_WIDTH 800; const unsigned int SCR_HEIGHT 600; const char *vertexShaderSource #version 330 core\n layout (location 0) in vec3 aPos;\n void main()\n {\n gl_Position vec4(aPos.x, aPos.y, aPos.z, 1.0);\n }\0; const char *fragmentShaderSource #version 330 core\n out vec4 FragColor;\n void main()\n {\n FragColor vec4(1.0f, 0.5f, 0.2f, 1.0f);\n }\n\0; int main() { // glfw: initialize and configure // ------------------------------ glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); #endif // glfw window creation // -------------------- GLFWwindow *window glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, LearnOpenGL, NULL, NULL); if (window NULL) { std::cout Failed to create GLFW window std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); // glad: load all OpenGL function pointers // --------------------------------------- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout Failed to initialize GLAD std::endl; return -1; } // build and compile our shader program // ------------------------------------ // vertex shader unsigned int vertexShader glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, vertexShaderSource, NULL); glCompileShader(vertexShader); // check for shader compile errors int success; char infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout ERROR::SHADER::VERTEX::COMPILATION_FAILED\n infoLog std::endl; } // fragment shader unsigned int fragmentShader glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, fragmentShaderSource, NULL); glCompileShader(fragmentShader); // check for shader compile errors glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n infoLog std::endl; } // link shaders unsigned int shaderProgram glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // check for linking errors glGetProgramiv(shaderProgram, GL_LINK_STATUS, success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout ERROR::SHADER::PROGRAM::LINKING_FAILED\n infoLog std::endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // set up vertex data (and buffer(s)) and configure vertex attributes // ------------------------------------------------------------------ float vertices[] { 0.5f, 0.5f, 0.0f, // top right 0.5f, -0.5f, 0.0f, // bottom right -0.5f, -0.5f, 0.0f, // bottom left -0.5f, 0.5f, 0.0f // top left }; unsigned int indices[] { // note that we start from 0! 0, 1, 3, // first Triangle 1, 2, 3 // second Triangle }; unsigned int VBO, VAO, EBO; glGenVertexArrays(1, VAO); glGenBuffers(1, VBO); glGenBuffers(1, EBO); // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0); glEnableVertexAttribArray(0); // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attributes bound vertex // buffer object so afterwards we can safely unbind glBindBuffer(GL_ARRAY_BUFFER, 0); // remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep // the EBO bound. // glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // You can unbind the VAO afterwards so other VAO calls wont accidentally modify this VAO, but this rarely happens. // Modifying other VAOs requires a call to glBindVertexArray anyways so we generally dont unbind VAOs (nor VBOs) when // its not directly necessary. glBindVertexArray(0); // uncomment this call to draw in wireframe polygons. // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // render loop // ----------- while (!glfwWindowShouldClose(window)) { // input // ----- processInput(window); // render // ------ glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // draw our first triangle glUseProgram(shaderProgram); glBindVertexArray(VAO); // seeing as we only have a single VAO theres no need to bind it every time, but well do // so to keep things a bit more organized // glDrawArrays(GL_TRIANGLES, 0, 6); // glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // glBindVertexArray(0); // no need to unbind it every time drawBezierCurve(); // 绘制曲线 // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) // ------------------------------------------------------------------------------- glfwSwapBuffers(window); glfwPollEvents(); } // optional: de-allocate all resources once theyve outlived their purpose: // ------------------------------------------------------------------------ glDeleteVertexArrays(1, VAO); glDeleteBuffers(1, VBO); glDeleteBuffers(1, EBO); glDeleteProgram(shaderProgram); // glfw: terminate, clearing all previously allocated GLFW resources. // ------------------------------------------------------------------ glfwTerminate(); return 0; } // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly // --------------------------------------------------------------------------------------------------------- void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) GLFW_PRESS) glfwSetWindowShouldClose(window, true); } // glfw: whenever the window size changed (by OS or user resize) this callback function executes // --------------------------------------------------------------------------------------------- void framebuffer_size_callback(GLFWwindow *window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); }效果C字体库开发之字符显示四-CSDN博客创作不易小小的支持一下吧
RELATED

相关推荐

基于FPGA与STM32的LFM脉冲压缩雷达系统设计与实现

基于FPGA与STM32的LFM脉冲压缩雷达系统设计与实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/2 1:07:16
PLFM_RADAR:轻量级主动探测系统,实现多服务健康状态实时感知

PLFM_RADAR:轻量级主动探测系统,实现多服务健康状态实时感知

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/2 1:07:16
SPI隔离实战:基于MAX14431与PIC18F87J50的软硬件设计

SPI隔离实战:基于MAX14431与PIC18F87J50的软硬件设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/2 1:07:16
MORE NEWS

更多资讯

📰

c++实现的常见缓存算法和LRU

前言 缓存的核心矛盾是容量有限而数据无限:当新的键值对要进来而缓存已满时,必须挑一个旧条目淘汰。挑谁,就是缓存淘汰算法要回答的问题。FIFO 按进入时间淘汰,LRU 按最近使用时间淘汰,LFU 按使用频率淘汰,…

📰

OpenCV颜色识别实战:HSV空间与inRange阈值调参指南

简介:这份资源面向具备一定C#基础、希望在桌面端实现图像颜色识别的开发者,围绕OpenCV的C#封装OpenCvSharp展开,重点讲解HSV颜色空间下的颜色筛选与掩码处理,可用于自动化检测、机器人视觉、物体定位等场景的入门与练手。压缩包共…

📰

气象数据分析实战:从数据清洗到趋势检验的完整实验流程

简介:这份资源面向数据分析初学者与需要完成课程实验的学生,围绕气象数据展开完整分析实践:通过爬虫代码抓取中国天气网某一城市的天气数据,再对数据做清洗与统计,生成雷达图、条形图等多种可视化图表,并配…

📰

Windows下UDP组播收发程序实战:从原理到避坑指南

简介:面向Windows平台网络编程初学者与需要实现多播通信的开发者,这份资源提供了一套可直接编译运行的UDP组播发送与接收示例工程。内容围绕Winsock编程展开,涵盖组播地址与端口设置、套接字创建绑定、通过IP_ADD_MEMBERSHIP加入多播组&#…

📰

开源备忘:我做了个在线 3D 寺庙 sansatemple.live(赛博산사)

做了一件偏「氛围」的小东西:赛博산사 / Cyber Sansa。 正式地址只认这个: https://sansatemple.live 浏览器打开就是一座可逛的 3D 寺庙:多间殿堂、可与其他访客同在(presence 有人数上限,避免房间卡死)&a…

📰

Spring Cloud Alibaba分布式商城复现:中间件、检索与下单事务

简介:围绕谷粒商城微服务分布式电商项目整理的高级篇代码与配套材料,面向具备Java后端基础、希望系统理解电商平台落地方式的开发者,重点解决微服务拆分、服务治理与高可用架构等学习诉求。内容围绕用户、商品、订单、支付等服务展开&#xf…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬