使用OpenGL和GLUT库用C++编写一个简易计算器,可按以下步骤进行:
### 1. 初始化GLUT和OpenGL
首先,要初始化GLUT库并创建一个窗口,同时对OpenGL进行必要的设置。
```cpp
#include <GL/glut.h>
#include <iostream>
#include <string>
#include <sstream>
#include <cmath>
// 全局变量
std::string input = "";
double num1 = 0, num2 = 0;
char op = '\0';
bool waitingForSecondNum = false;
// 初始化OpenGL设置
void init() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gluOrtho2D(0, 400, 0, 400);
}
```
### 2. 绘制计算器界面
绘制计算器的按钮和显示区域。
```cpp
// 绘制文本
void drawText(float x, float y, const std::string& text) {
glRasterPos2f(x, y);
for (char c : text) {
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, c);
}
}
// 绘制按钮
void drawButton(int x, int y, int width, int height, const std::string& label) {
glBegin(GL_QUADS);
glColor3f(0.5f, 0.5f, 0.5f);
glVertex2i(x, y);
glVertex2i(x + width, y);
glVertex2i(x + width, y + height);
glVertex2i(x, y + height);
glEnd();
drawText(x + width / 2 - 5, y + height / 2 - 5, label);
}
// 绘制计算器界面
void display() {
glClear(GL_COLOR_BUFFER_BIT);
// 绘制显示区域
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2i(50, 300);
glVertex2i(350, 300);
glVertex2i(350, 350);
glVertex2i(50, 350);
glEnd();
// 显示输入内容
drawText(60, 310, input);
// 绘制按钮
drawButton(50, 200, 50, 50, "7");
drawButton(110, 200, 50, 50, "8");
drawButton(170, 200, 50, 50, "9");
drawButton(230, 200, 50, 50, "/");
drawButton(50, 140, 50, 50, "4");
drawButton(110, 140, 50, 50, "5");
drawButton(170, 140, 50, 50, "6");
drawButton(230, 140, 50, 50, "*");
drawButton(50, 80, 50, 50, "1");
drawButton(110, 80, 50, 50, "2");
drawButton(170, 80, 50, 50, "3");
drawButton(230, 80, 50, 50, "-");
drawButton(50, 20, 50, 50, "0");
drawButton(110, 20, 50, 50, ".");
drawButton(170, 20, 50, 50, "=");
drawButton(230, 20, 50, 50, "+");
glutSwapBuffers();
}
```
### 3. 处理鼠标点击事件
处理用户的鼠标点击事件,根据点击的按钮更新输入内容。
```cpp
// 处理鼠标点击事件
void mouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
y = 400 - y; // 转换坐标系
// 检查点击的按钮
if (x >= 50 && x <= 100 && y >= 200 && y <= 250) input += "7";
if (x >= 110 && x <= 160 && y >= 200 && y <= 250) input += "8";
if (x >= 170 && x <= 220 && y >= 200 && y <= 250) input += "9";
if (x >= 230 && x <= 280 && y >= 200 && y <= 250) {
if (!input.empty()) {
num1 = std::stod(input);
op = '/';
waitingForSecondNum = true;
input = "";
}
}
if (x >= 50 && x <= 100 && y >= 140 && y <= 190) input += "4";
if (x >= 110 && x <= 160 && y >= 140 && y <= 190) input += "5";
if (x >= 170 && x <= 220 && y >= 140 && y <= 190) input += "6";
if (x >= 230 && x <= 280 && y >= 140 && y <= 190) {
if (!input.empty()) {
num1 = std::stod(input);
op = '*';
waitingForSecondNum = true;
input = "";
}
}
if (x >= 50 && x <= 100 && y >= 80 && y <= 130) input += "1";
if (x >= 110 && x <= 160 && y >= 80 && y <= 130) input += "2";
if (x >= 170 && x <= 220 && y >= 80 && y <= 130) input += "3";
if (x >= 230 && x <= 280 && y >= 80 && y <= 130) {
if (!input.empty()) {
num1 = std::stod(input);
op = '-';
waitingForSecondNum = true;
input = "";
}
}
if (x >= 50 && x <= 100 && y >= 20 && y <= 70) input += "0";
if (x >= 110 && x <= 160 && y >= 20 && y <= 70) input += ".";
if (x >= 170 && x <= 220 && y >= 20 && y <= 70) {
if (!input.empty() && waitingForSecondNum) {
num2 = std::stod(input);
switch (op) {
case '+': input = std::to_string(num1 + num2); break;
case '-': input = std::to_string(num1 - num2); break;
case '*': input = std::to_string(num1 * num2); break;
case '/':
if (num2 != 0) input = std::to_string(num1 / num2);
else input = "Error";
break;
}
waitingForSecondNum = false;
}
}
if (x >= 230 && x <= 280 && y >= 20 && y <= 70) {
if (!input.empty()) {
num1 = std::stod(input);
op = '+';
waitingForSecondNum = true;
input = "";
}
}
glutPostRedisplay();
}
}
```
### 4. 主函数
在主函数中初始化GLUT和OpenGL,并进入主循环。
```cpp
// 主函数
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(400, 400);
glutCreateWindow("Simple Calculator");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
```
### 代码解释
- `init()`函数:对OpenGL的清屏颜色和投影模式进行设置。
- `display()`函数:负责绘制计算器的界面,包含显示区域和按钮。
- `mouse()`函数:处理鼠标点击事件,依据点击的按钮更新输入内容,并且在用户点击“=”时进行计算。
- `main()`函数:初始化GLUT和OpenGL,注册回调函数,然后进入主循环。
### 编译和运行
把上述代码保存为一个`.cpp`文件,例如`calculator.cpp`,接着使用以下命令进行编译:
```sh
g++ calculator.cpp -o calculator -lGL -lGLU -lglut
```
运行生成的可执行文件:
```sh
./calculator
```