代码#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博客创作不易小小的支持一下吧
企业数字化 ERP 产品动态
相关推荐
C++弱指针做map键值 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/11 3:42:54
LLVM Visual Studio构建 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/8 13:19:53
C++ keyboard and mouse跨平台模拟 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/8 21:02:08
电工证 复审章上岗必须要这个证吗 电工证复审章没过期怎么办?良心建议帮你搞懂 证书过期了不知道怎么复审延期?你是不是也在为电工证复审章的问题头疼?别急,这正是今天要帮你解决的痛点。电工证复审章关系到你的职业资格和岗位合法性,一旦过期,不仅影响工作,还可能带来法律责任。以下内… · 2026/11/11 13:48:52
冶金电工证网上报名,网上查询真能解决工地忙没时间复习的问题? 冶金电工证网上报名,网上查询真能解决工地忙没时间复习的问题? 工地太忙根本没时间复习考试,现在连考证都得“抢时间”了,很多人心里打鼓: 冶金电工证网上报名 靠谱吗?网上查询真能省事?其实,现在只要方法对, 冶金电工证网上报名… · 2026/11/11 13:48:52
低压电工证复训有题库多少钱才能安心通过实操考试 低压电工证复训有题库多少钱才能安心通过实操考试 实操考试心里没底怕挂科?低压电工证复训有题库多少钱?这是不少持证人员最关心的问题。特别是在漯河这样的中小施工企业,电工证不仅是上岗的前提,更是安全生产的“生命线”。复训题库的出现,虽然让考试难… · 2026/11/11 13:48:52
劳动保障部 电工证与电工证到期到哪儿年审的区别 工地太忙根本没时间复习考试?劳动保障部电工证千万别踩坑 工地太忙根本没时间复习考试?你不是一个人。很多在开封市政公用工程一线打拼的电工,手里攥着【劳动保障部 电工证】,却在面对考试时一筹莫展。别急,这篇攻略帮你把复习效率拉满, 千万别踩坑… · 2026/11/11 13:48:52
办理美的低压电工证报名需要什么材料 你之前考的证在外省能不能转过来?这波良心建议必须收好 之前考的证在外省能不能转过来?这是很多人在考虑考【美的低压电工证报名】时最关心的问题。特别是像我们信阳浉河区的房建工程从业者,很多人手里拿着外省的证,但又想在本地开展业务,这就涉及到跨省… · 2026/11/11 13:47:52
电工证丢失还能补吗?千万别踩坑,丢了证等于失业 电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。… · 2026/11/11 12:18:07
电力电缆作业证直播报名入口与办理流程良心建议 电力电缆作业证直播报名入口与办理流程良心建议 你是不是也担心学历不高报不了名?别急,今天就给你讲讲 电力电缆作业证直播 的报名流程和那些你必须知道的干货, 良心建议 在这里,别错过。 电力电缆作业证直播报名需要什么条件?… · 2026/11/10 17:46:39
英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 怕考不过白交培训费?英德电工证报考费多少钱,你真的了解吗?现在市面上培训机构五花八门,价格参差不齐,很多人一不小心就花了冤枉钱,结果还考不过。别急,今天就来给你说清楚英德电工证的… · 2026/11/10 17:11:43
_中职电工证最新政策解读 中职电工证在哪考?工地太忙根本没时间复习考试的救星来了 工地太忙根本没时间复习考试,这是很多正在备考 中职电工证 的建筑工友的真实写照。你不是不想考,而是真的没时间。但别担心,这期内容是 新乡初次报考人员… · 2026/11/11 0:00:52
昆明电工证培训价格值不值得考?老电工告诉你真相 昆明电工证培训价格值不值得考?老电工告诉你真相 之前考的证在外省能不能转过来?这个问题是很多在外地打工、换城市生活、或者是想在昆明发展的朋友最关心的。尤其是现在云南发展快,很多企业都在招持证上岗的电工,如果你手头有证但不在本地,那这个证是不… · 2026/11/11 0:00:52
特种电缆张工网上查询全攻略:外省证如何转过来 特种电缆张工网上查询全攻略:外省证如何转过来 之前考的证在外省能不能转过来?这是很多特种作业从业者最关心的问题,尤其是像特种电缆张工这类证书,直接关系到日常工作是否合规、能否顺利晋升。很多小伙伴因为证书归属地的问题,陷入职业发展的瓶颈,甚至… · 2026/11/11 0:00:52
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/10 20:19:29
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/10 19:22:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/10 17:00:47