完整的GLFW应用程序示例

news/2025/9/28 9:20:51/文章来源:https://www.cnblogs.com/xiongwei/p/19116122
/** 完整的GLFW应用程序示例* 包含窗口创建、输入处理、渲染循环等所有主要功能* 每行代码都有详细注释,便于学习GLFW的使用*/#include <GLFW/glfw3.h>  // GLFW主头文件
#include <iostream>      // 用于控制台输出
#include <cmath>         // 用于数学计算// 全局变量定义
GLFWwindow* g_window = nullptr;  // 全局窗口指针
int g_windowWidth = 800;         // 窗口宽度
int g_windowHeight = 600;        // 窗口高度
float g_backgroundColor[3] = {0.2f, 0.3f, 0.3f};  // 背景颜色(RGB)
bool g_wireframeMode = false;    // 线框模式标志/** 错误回调函数* 当GLFW发生错误时自动调用*/
void errorCallback(int error, const char* description) {std::cerr << "GLFW错误 " << error << ": " << description << std::endl;
}/** 窗口大小改变回调函数* 当用户调整窗口大小时自动调用*/
void framebufferSizeCallback(GLFWwindow* window, int width, int height) {g_windowWidth = width;g_windowHeight = height;// 设置视口大小,匹配窗口大小glViewport(0, 0, width, height);std::cout << "窗口大小改变: " << width << " x " << height << std::endl;
}/** 键盘按键回调函数* 当用户按下或释放键盘按键时调用*/
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {// 只处理按键按下事件,忽略重复和释放事件if (action == GLFW_PRESS) {switch (key) {case GLFW_KEY_ESCAPE:// ESC键:关闭窗口std::cout << "ESC键按下,关闭窗口" << std::endl;glfwSetWindowShouldClose(window, true);break;case GLFW_KEY_SPACE:// 空格键:切换背景颜色g_backgroundColor[0] = static_cast<float>(rand()) / RAND_MAX;g_backgroundColor[1] = static_cast<float>(rand()) / RAND_MAX;g_backgroundColor[2] = static_cast<float>(rand()) / RAND_MAX;std::cout << "空格键按下,切换背景颜色" << std::endl;break;case GLFW_KEY_W:// W键:切换线框模式g_wireframeMode = !g_wireframeMode;if (g_wireframeMode) {glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);std::cout << "线框模式: 开启" << std::endl;} else {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);std::cout << "线框模式: 关闭" << std::endl;}break;case GLFW_KEY_F:// F键:切换全屏/窗口模式static bool fullscreen = false;fullscreen = !fullscreen;if (fullscreen) {// 获取主显示器模式GLFWmonitor* monitor = glfwGetPrimaryMonitor();const GLFWvidmode* mode = glfwGetVideoMode(monitor);// 切换到全屏模式glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);std::cout << "切换到全屏模式" << std::endl;} else {// 切换到窗口模式glfwSetWindowMonitor(window, nullptr, 100, 100, g_windowWidth, g_windowHeight, 0);std::cout << "切换到窗口模式" << std::endl;}break;case GLFW_KEY_P:// P键:打印窗口信息int x, y;glfwGetWindowPos(window, &x, &y);std::cout << "窗口位置: (" << x << ", " << y << ")" << std::endl;std::cout << "窗口大小: " << g_windowWidth << " x " << g_windowHeight << std::endl;break;}}
}/** 鼠标移动回调函数* 当鼠标移动时调用*/
void cursorPosCallback(GLFWwindow* window, double xpos, double ypos) {// 可以在这里处理鼠标移动逻辑// 示例:每100次调用打印一次位置(避免过于频繁的输出)static int callCount = 0;if (callCount++ % 100 == 0) {std::cout << "鼠标位置: (" << xpos << ", " << ypos << ")" << std::endl;}
}/** 鼠标按钮回调函数* 当鼠标按钮按下或释放时调用*/
void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods) {if (action == GLFW_PRESS) {double xpos, ypos;glfwGetCursorPos(window, &xpos, &ypos);switch (button) {case GLFW_MOUSE_BUTTON_LEFT:std::cout << "左键点击位置: (" << xpos << ", " << ypos << ")" << std::endl;break;case GLFW_MOUSE_BUTTON_RIGHT:std::cout << "右键点击位置: (" << xpos << ", " << ypos << ")" << std::endl;break;case GLFW_MOUSE_BUTTON_MIDDLE:std::cout << "中键点击位置: (" << xpos << ", " << ypos << ")" << std::endl;break;}}
}/** 鼠标滚轮回调函数* 当鼠标滚轮滚动时调用*/
void scrollCallback(GLFWwindow* window, double xoffset, double yoffset) {std::cout << "鼠标滚轮: X=" << xoffset << ", Y=" << yoffset << std::endl;
}/** 窗口焦点回调函数* 当窗口获得或失去焦点时调用*/
void windowFocusCallback(GLFWwindow* window, int focused) {if (focused) {std::cout << "窗口获得焦点" << std::endl;} else {std::cout << "窗口失去焦点" << std::endl;}
}/** 窗口图标化回调函数* 当窗口被最小化或恢复时调用*/
void windowIconifyCallback(GLFWwindow* window, int iconified) {if (iconified) {std::cout << "窗口被最小化" << std::endl;} else {std::cout << "窗口恢复" << std::endl;}
}/** 初始化GLFW和创建窗口* 返回true表示成功,false表示失败*/
bool initializeGLFW() {// 设置错误回调函数glfwSetErrorCallback(errorCallback);// 初始化GLFW库if (!glfwInit()) {std::cerr << "GLFW初始化失败!" << std::endl;return false;}// 配置GLFW窗口属性glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);  // OpenGL主版本号glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);  // OpenGL次版本号glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);  // 使用核心模式glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);      // 窗口可调整大小glfwWindowHint(GLFW_SAMPLES, 4);                // 4倍多重采样抗锯齿#ifdef __APPLE__// macOS需要额外的配置glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif// 创建窗口和OpenGL上下文g_window = glfwCreateWindow(g_windowWidth, g_windowHeight, "GLFW完整示例 - 学习OpenGL", nullptr, nullptr);if (!g_window) {std::cerr << "创建GLFW窗口失败!" << std::endl;glfwTerminate();return false;}// 将窗口的上下文设置为当前线程的主上下文glfwMakeContextCurrent(g_window);// 设置垂直同步(1表示开启,0表示关闭)glfwSwapInterval(1);// 设置各种回调函数glfwSetFramebufferSizeCallback(g_window, framebufferSizeCallback);glfwSetKeyCallback(g_window, keyCallback);glfwSetCursorPosCallback(g_window, cursorPosCallback);glfwSetMouseButtonCallback(g_window, mouseButtonCallback);glfwSetScrollCallback(g_window, scrollCallback);glfwSetWindowFocusCallback(g_window, windowFocusCallback);glfwSetWindowIconifyCallback(g_window, windowIconifyCallback);// 设置输入模式glfwSetInputMode(g_window, GLFW_STICKY_KEYS, GLFW_TRUE);  // 启用粘性键glfwSetInputMode(g_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);  // 正常光标模式std::cout << "GLFW初始化成功!" << std::endl;std::cout << "控制说明:" << std::endl;std::cout << "  ESC - 退出程序" << std::endl;std::cout << "  空格 - 随机改变背景颜色" << std::endl;std::cout << "  W - 切换线框模式" << std::endl;std::cout << "  F - 切换全屏/窗口模式" << std::endl;std::cout << "  P - 打印窗口信息" << std::endl;return true;
}/** 渲染一个简单的旋转三角形*/
void renderTriangle(float time) {// 开始绘制三角形glBegin(GL_TRIANGLES);// 计算旋转角度(随时间变化)float angle = time * 50.0f;  // 每秒旋转50度// 第一个顶点(红色)glColor3f(1.0f, 0.0f, 0.0f);  // 红色glVertex2f(0.0f * cos(angle) - 0.5f * sin(angle), 0.0f * sin(angle) + 0.5f * cos(angle));// 第二个顶点(绿色)glColor3f(0.0f, 1.0f, 0.0f);  // 绿色glVertex2f(-0.5f * cos(angle) - (-0.5f) * sin(angle), -0.5f * sin(angle) + (-0.5f) * cos(angle));// 第三个顶点(蓝色)glColor3f(0.0f, 0.0f, 1.0f);  // 蓝色glVertex2f(0.5f * cos(angle) - (-0.5f) * sin(angle), 0.5f * sin(angle) + (-0.5f) * cos(angle));glEnd();
}/** 渲染场景*/
void renderScene(float time) {// 清除颜色缓冲区glClear(GL_COLOR_BUFFER_BIT);// 设置投影矩阵为正交投影glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);// 设置模型视图矩阵glMatrixMode(GL_MODELVIEW);glLoadIdentity();// 渲染旋转三角形renderTriangle(time);
}/** 主函数 - 程序入口点*/
int main() {std::cout << "启动GLFW应用程序..." << std::endl;// 初始化GLFWif (!initializeGLFW()) {return -1;}// 设置初始视口glViewport(0, 0, g_windowWidth, g_windowHeight);// 获取时间基准double lastTime = glfwGetTime();int frameCount = 0;// 主渲染循环while (!glfwWindowShouldClose(g_window)) {// 计算帧率double currentTime = glfwGetTime();frameCount++;// 每秒更新一次帧率显示if (currentTime - lastTime >= 1.0) {std::string title = "GLFW示例 - FPS: " + std::to_string(frameCount);glfwSetWindowTitle(g_window, title.c_str());frameCount = 0;lastTime = currentTime;}// 设置清除颜色(背景色)glClearColor(g_backgroundColor[0], g_backgroundColor[1], g_backgroundColor[2], 1.0f);// 渲染场景renderScene(static_cast<float>(currentTime));// 交换前后缓冲区(双缓冲技术)glfwSwapBuffers(g_window);// 处理事件(输入、窗口事件等)glfwPollEvents();// 检查某些特定按键状态(持续按下的处理)if (glfwGetKey(g_window, GLFW_KEY_R) == GLFW_PRESS) {// R键持续按下时重置背景颜色g_backgroundColor[0] = 0.2f;g_backgroundColor[1] = 0.3f;g_backgroundColor[2] = 0.3f;}}// 清理资源glfwDestroyWindow(g_window);glfwTerminate();std::cout << "程序正常退出" << std::endl;return 0;
}

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/920441.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站规划建设实训大型电商网站开发方案

1. 引言 Go&#xff08;也称为Golang&#xff09;是一种开源的编程语言&#xff0c;由Google在2007年启动的项目中开发而来。它是一种静态类型的编译型语言&#xff0c;旨在提供高效、可靠的性能。相比于其他编程语言&#xff0c;Golang具有更高的执行效率和并发能力&#xff…

物理笔记

\(P\cdot V=N\cdot K\cdot T\) \(N\) 为分子数量 \(K\) 为常量 \(1.38\times 10^{-23} J\cdot K^{-1}\) 现在推到温度 \(T\) 代表分子平均动能。 考虑单个分子在正方体内运动 \(\Delta p=2mv_x\) \(F=\frac{\Delta p}{…

基于Python+Vue开发的商城管理系统源码+运行步骤

项目简介该项目是基于Python+Vue开发的商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Python编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Pyt…

HTML5-和-CSS3-迁移即时入门-全-

HTML5 和 CSS3 迁移即时入门(全)原文:zh.annas-archive.org/md5/94106B0DE1B83990A3B43B022F07C0DB 译者:飞龙 协议:CC BY-NC-SA 4.0前言 采用新技术总是一个具有挑战性的过程,特别是当它被视为对流行和广为认可…

HTML5-多人游戏开发-全-

HTML5 多人游戏开发(全)原文:zh.annas-archive.org/md5/58B015FFC16EF0C30C610502BF4A7DA3 译者:飞龙 协议:CC BY-NC-SA 4.0前言 欢迎来到《使用 HTML5 开发多人游戏》。本书将教你如何开发支持多个玩家在同一游戏…

HTML5-地理位置即时操作指南-全-

HTML5 地理位置即时操作指南(全)原文:zh.annas-archive.org/md5/d561e9d990e59031e96fb80bd9bd24f6 译者:飞龙 协议:CC BY-NC-SA 4.0前言 欢迎来到 Instant HTML5 Geolocation How-to。本指南将帮助你快速轻松地使…

暖色网站专项培训网站建设方案

51单片机—————8位单片机 裸机驱动 无系统 linux驱动 有系统 驱动-----反映硬件变化 MCU 微控器 MPU CPU GPU 图像处理 IDE 集成开发环境 peripheral 外设 SOC&#xff1a; system on chip P0&#xff1a;8bit——8个引脚 位运算 & …

哪里有免费的网站网址商城网站栏目

声明 下面的题目作答都是自己认为正确的答案&#xff0c;并非官方答案&#xff0c;如果有不同的意见&#xff0c;可以评论区交流。 这些题目也是笔者从各个地方收集的&#xff0c;感觉有些题目答案并不正确&#xff0c;所以在个别题目会给出自己的见解&#xff0c;欢迎大家讨论…

[Kernel] - Heterogeneous Memory Management (HMM)

[Kernel] - Heterogeneous Memory Management (HMM)Heterogeneous Memory Management (HMM) https://www.kernel.org/doc/html/latest/mm/hmm.html Provide infrastructure and helpers to integrate non-conventional…

GreenPlum - Get field types

GreenPlum - Get field types import psycopg2conn = psycopg2.connect(dbname="your_db",user="your_user",password="your_password",host="your_host",port="5432&qu…

搭建环境

环境的流程 一、介绍环境(在linux搭建) 多有米 jdk+linux+服务器(tomcat)+mysql+代码包 jdk 1.8版本 linux(centos) 服务器 tomcat(目前用) 、apache、nginx 数据库 mysql 数据包(后缀 是.mysql)…

山东建设厅科技处网站python官网下载安装

写在前面 如果只有一个kafka实例的话&#xff0c;那么文章中提到kafka集群kafka实例 一、什么是消息发送者端的ack机制 ack机制&#xff1a;消息确认发送成功的标识 由谁发起该标识&#xff1a;kafka集群 发起该标识的场景&#xff1a;kafka集群确认已经收到了消息。 由谁接收…

20250928

周末了 看了下棕榈 前期好像走了个小五波吧 要涨么?不过大周期看还有个Yc的波段

Easysearch 国产替代 Elasticsearch:8 大核心挑战解读

Easysearch 国产替代 Elasticsearch:8 大核心挑战解读pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&q…

Typescript概述和思维导图

TypeScript 简要概述 TypeScript 是由微软开发的开源编程语言,它是 JavaScript 的一个超集。这意味着任何有效的 JavaScript 代码也都是有效的 TypeScript 代码。 核心价值在于其强大的静态类型系统。主要特点:静态类…

9-28

初态只有一个,终态可以有多个 自动机是进行词法分析的工具

Qt结合ffmpeg代码实现udp推流/组播推流/rtp推流/监控GB28181推流/onvif推流

一、前言说明 之前已经用ffmpeg代码实现了rtsp和rtmp推流,在没有搞过推流的时候,以为很难,其实推流就是保存文件到一个rtsp/rtmp地址,完全复用保存到MP4文件的代码,唯一不同的时候就是在avformat_alloc_output_co…

个人网站建设多少钱网站建设翻译插件

矩阵中的路径 题目 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是…

新乡住房与城乡建设厅网站xsxz wordpress

近日&#xff0c;腾讯的大动作一个接一个&#xff0c;前脚刚公布2023上半年财报&#xff0c;后脚就开启了2024校招&#xff0c;不得不让人感叹腾讯真速度&#xff01; 此次招聘对象为毕业时间在2023年9月至2024年8月期间的2024届应届毕业生&#xff0c;覆盖北上广深等多个城市…

在线做漫画的网站营销网络的建设是什么意思

欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列&#xff0c;持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列&#xff0c;持续更新中 【youcans 的 OpenCV 例程 200 篇】124. 孔洞填充的泛洪算法 3. 形态学算法 形态学处理的主要应用是提取图像中用来表示和描述形状…