glutMouseFunc

本文介绍了一个使用OpenGL和GLUT库实现的简单图形程序。该程序通过glutMouseFunc函数响应鼠标点击事件,并在屏幕上绘制从点击位置到原点的线段。此示例适合OpenGL初学者练习鼠标输入处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

初学OpenGL,写了段关于glutMouseFunc函数的示例。新手,代码写的不规范的地方请指正。

#include<stdio.h>
#include<GL/glut.h>
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(3);
glBegin(GL_POINTS);
glVertex2i(0,0);
glEnd();
glFlush();
}

void mymouse(int button,int state,int x,int y)
{
if(state==GLUT_DOWN)
{
while(x<500&&y<500){
printf("%d,%d\n",x,y);
glBegin(GL_LINES);
glVertex2i(0,0);
glVertex2i(x-250,250-y);

glVertex2i(x-250,250-y);
glEnd();
glFlush();
x=x+3;
y=y+3;
}}
}
init()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-250.0,250.0,-250.0,250.0);
}
int main(int argc,char**argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("ok");
glutDisplayFunc(display);
glutKeyboardFunc(mykey);
init();
glutMouseFunc(mymouse);
glutMainLoop();
}

随鼠标的点击而画图,执行效果:

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <math.h> #include <GL/glut.h> #include <string.h> #define PI 3.14159265358979323846 // 全局变量 typedef struct { float x, y, z; } Point3D; typedef struct { float r, g, b, a; } Color; typedef struct { int v1, v2, v3; } Face; // 网格数据结构 typedef struct { int numVertices; int numFaces; Point3D* vertices; Face* faces; Point3D* normals; // 用于光照计算的法线 float* texCoords; // 纹理坐标 } Mesh; // 变换控制 typedef struct { Point3D translation; Point3D rotation; float scale; int transformMode; // 0:旋转, 1:平移, 2:缩放 } Transform; // 应用程序状态 typedef struct { Mesh mesh; int drawMode; // 0:点, 1:边, 2:面, 3:真实感 Transform transform; Point3D pivotPoint; int lastMouseX; int lastMouseY; int mouseLeftDown; int mouseRightDown; int showHelp; int showTransformPoints; int textureEnabled; GLuint textureID; Point3D q1, q2; // 用户输入的变换点 Point3D originalP1, originalP2; // 原始北极和南极 } AppState; AppState appState; // 纹理数据(简单的棋盘纹理) #define TEX_WIDTH 64 #define TEX_HEIGHT 64 GLubyte texture[TEX_WIDTH][TEX_HEIGHT][3]; // 创建棋盘纹理 void createTexture() { for (int i = 0; i < TEX_WIDTH; i++) { for (int j = 0; j < TEX_HEIGHT; j++) { int c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0)) * 255; texture[i][j][0] = (GLubyte)c; texture[i][j][1] = (GLubyte)(c * 0.7); texture[i][j][2] = (GLubyte)(255 - c); } } } // 初始化纹理 void initTexture() { createTexture(); glGenTextures(1, &appState.textureID); glBindTexture(GL_TEXTURE_2D, appState.textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); appState.textureEnabled = 1; } // 读取网格文件 void ReadMesh(const char* fName) { FILE* fp = fopen(fName, "r"); if (!fp) { printf("无法打开文件: %s\n", fName); exit(1); } // 读取顶点数和面数 int nE; if (fscanf(fp, "%d %d %d", &appState.mesh.numVertices, &nE, &appState.mesh.numFaces) != 3) { printf("文件格式错误\n"); fclose(fp); exit(1); } // 分配内存 appState.mesh.vertices = (Point3D*)malloc(appState.mesh.numVertices * sizeof(Point3D)); appState.mesh.faces = (Face*)malloc(appState.mesh.numFaces * sizeof(Face)); appState.mesh.normals = (Point3D*)malloc(appState.mesh.numVertices * sizeof(Point3D)); appState.mesh.texCoords = (float*)malloc(appState.mesh.numVertices * 2 * sizeof(float)); // 初始化法线 for (int i = 0; i < appState.mesh.numVertices; i++) { appState.mesh.normals[i].x = 0.0f; appState.mesh.normals[i].y = 0.0f; appState.mesh.normals[i].z = 0.0f; } // 读取顶点 for (int i = 0; i < appState.mesh.numVertices; i++) { float x, y, z; if (fscanf(fp, "%f %f %f", &x, &y, &z) != 3) { printf("顶点数据错误\n"); fclose(fp); free(appState.mesh.vertices); free(appState.mesh.faces); exit(1); } appState.mesh.vertices[i].x = x; appState.mesh.vertices[i].y = y; appState.mesh.vertices[i].z = z; // 计算纹理坐标 (球面映射) float u = 0.5f + atan2(z, x) / (2.0f * PI); float v = 0.5f - asin(y) / PI; appState.mesh.texCoords[2 * i] = u; appState.mesh.texCoords[2 * i + 1] = v; } // 读取面(假设所有面都是三角形) for (int i = 0; i < appState.mesh.numFaces; i++) { int v1, v2, v3; if (fscanf(fp, "%d %d %d", &v1, &v2, &v3) != 3) { printf("面数据错误\n"); fclose(fp); free(appState.mesh.vertices); free(appState.mesh.faces); exit(1); } appState.mesh.faces[i].v1 = v1; appState.mesh.faces[i].v2 = v2; appState.mesh.faces[i].v3 = v3; // 计算面法线 Point3D p1 = appState.mesh.vertices[v1]; Point3D p2 = appState.mesh.vertices[v2]; Point3D p3 = appState.mesh.vertices[v3]; Point3D v = { p2.x - p1.x, p2.y - p1.y, p2.z - p1.z }; Point3D w = { p3.x - p1.x, p3.y - p1.y, p3.z - p1.z }; // 叉积 Point3D normal; normal.x = v.y * w.z - v.z * w.y; normal.y = v.z * w.x - v.x * w.z; normal.z = v.x * w.y - v.y * w.x; // 归一化 float len = sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z); if (len > 0) { normal.x /= len; normal.y /= len; normal.z /= len; } // 累加到顶点法线 appState.mesh.normals[v1].x += normal.x; appState.mesh.normals[v1].y += normal.y; appState.mesh.normals[v1].z += normal.z; appState.mesh.normals[v2].x += normal.x; appState.mesh.normals[v2].y += normal.y; appState.mesh.normals[v2].z += normal.z; appState.mesh.normals[v3].x += normal.x; appState.mesh.normals[v3].y += normal.y; appState.mesh.normals[v3].z += normal.z; } // 归一化顶点法线 for (int i = 0; i < appState.mesh.numVertices; i++) { float len = sqrt(appState.mesh.normals[i].x * appState.mesh.normals[i].x + appState.mesh.normals[i].y * appState.mesh.normals[i].y + appState.mesh.normals[i].z * appState.mesh.normals[i].z); if (len > 0) { appState.mesh.normals[i].x /= len; appState.mesh.normals[i].y /= len; appState.mesh.normals[i].z /= len; } } fclose(fp); printf("成功加载网格: %d 顶点, %d 面\n", appState.mesh.numVertices, appState.mesh.numFaces); // 保存原始北极和南极 appState.originalP1 = appState.mesh.vertices[0]; // 北极 appState.originalP2 = appState.mesh.vertices[appState.mesh.numVertices - 1]; // 南极 appState.q1 = appState.originalP1; appState.q2 = appState.originalP2; } // 应用变换矩阵 void applyTransformations() { // 应用平移 glTranslatef(appState.transform.translation.x, appState.transform.translation.y, appState.transform.translation.z); // 应用旋转 glRotatef(appState.transform.rotation.x, 1.0f, 0.0f, 0.0f); glRotatef(appState.transform.rotation.y, 0.0f, 1.0f, 0.0f); glRotatef(appState.transform.rotation.z, 0.0f, 0.0f, 1.0f); // 应用缩放 glScalef(appState.transform.scale, appState.transform.scale, appState.transform.scale); } // 应用球面变换(将P1变换到Q1,P2变换到Q2) void applySphereTransformation() { // 计算原始地轴向量 Point3D originalAxis; originalAxis.x = appState.originalP2.x - appState.originalP1.x; originalAxis.y = appState.originalP2.y - appState.originalP1.y; originalAxis.z = appState.originalP2.z - appState.originalP1.z; // 计算目标地轴向量 Point3D targetAxis; targetAxis.x = appState.q2.x - appState.q1.x; targetAxis.y = appState.q2.y - appState.q1.y; targetAxis.z = appState.q2.z - appState.q1.z; // 计算原始轴长度 float originalLength = sqrt(originalAxis.x * originalAxis.x + originalAxis.y * originalAxis.y + originalAxis.z * originalAxis.z); // 计算目标轴长度 float targetLength = sqrt(targetAxis.x * targetAxis.x + targetAxis.y * targetAxis.y + targetAxis.z * targetAxis.z); // 计算缩放因子 float scale = targetLength / originalLength; // 计算旋转轴和角度 Point3D axis; float angle; if (originalLength > 0 && targetLength > 0) { // 归一化向量 originalAxis.x /= originalLength; originalAxis.y /= originalLength; originalAxis.z /= originalLength; targetAxis.x /= targetLength; targetAxis.y /= targetLength; targetAxis.z /= targetLength; // 计算旋转轴(叉积) axis.x = originalAxis.y * targetAxis.z - originalAxis.z * targetAxis.y; axis.y = originalAxis.z * targetAxis.x - originalAxis.x * targetAxis.z; axis.z = originalAxis.x * targetAxis.y - originalAxis.y * targetAxis.x; // 计算旋转角度(点积) float dot = originalAxis.x * targetAxis.x + originalAxis.y * targetAxis.y + originalAxis.z * targetAxis.z; // 确保点积在有效范围内 if (dot < -1.0f) dot = -1.0f; else if (dot > 1.0f) dot = 1.0f; angle = acos(dot) * 180.0f / PI; // 应用变换 glTranslatef(appState.q1.x, appState.q1.y, appState.q1.z); glRotatef(angle, axis.x, axis.y, axis.z); glScalef(scale, scale, scale); glTranslatef(-appState.originalP1.x, -appState.originalP1.y, -appState.originalP1.z); } } // 初始化OpenGL void initGL() { glClearColor(0.1f, 0.1f, 0.15f, 1.0f); // 深蓝色背景 glEnable(GL_DEPTH_TEST); // 启用深度测试 glShadeModel(GL_SMOOTH); // 平滑着色 glEnable(GL_NORMALIZE); // 自动归一化法线 // 设置光照 GLfloat lightAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f }; GLfloat lightDiffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; GLfloat lightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat lightPosition[] = { 5.0f, 5.0f, 5.0f, 1.0f }; glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular); glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); // 设置材质 GLfloat matAmbient[] = { 0.7f, 0.7f, 0.7f, 1.0f }; GLfloat matDiffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; GLfloat matSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat matShininess[] = { 50.0f }; glMaterialfv(GL_FRONT, GL_AMBIENT, matAmbient); glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, matSpecular); glMaterialfv(GL_FRONT, GL_SHININESS, matShininess); // 初始化纹理 initTexture(); } // 绘制坐标轴 void drawAxes() { glDisable(GL_LIGHTING); glLineWidth(2.0f); glBegin(GL_LINES); // X轴 (红色) glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(1.5f, 0.0f, 0.0f); // Y轴 (绿色) glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.5f, 0.0f); // Z轴 (蓝色) glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 1.5f); glEnd(); glEnable(GL_LIGHTING); } // 绘制变换点 void drawTransformPoints() { if (!appState.showTransformPoints) return; glDisable(GL_LIGHTING); glPointSize(10.0f); // 绘制Q1点 (红色) glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); glVertex3f(appState.q1.x, appState.q1.y, appState.q1.z); glEnd(); // 绘制Q2点 (蓝色) glColor3f(0.0f, 0.0f, 1.0f); glBegin(GL_POINTS); glVertex3f(appState.q2.x, appState.q2.y, appState.q2.z); glEnd(); // 绘制连接线 glLineWidth(2.0f); glBegin(GL_LINES); glColor3f(1.0f, 0.0f, 1.0f); glVertex3f(appState.q1.x, appState.q1.y, appState.q1.z); glVertex3f(appState.q2.x, appState.q2.y, appState.q2.z); glEnd(); glEnable(GL_LIGHTING); } // 显示帮助信息 void drawHelp() { if (!appState.showHelp) return; glDisable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0, 800, 0, 600); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor3f(1.0f, 1.0f, 0.8f); glRasterPos2f(10, 580); /*const char* helpText[] = { "球面网格查看器 - 帮助信息", "--------------------------------", "视图控制:", " 鼠标左键拖动: 旋转模型", " 鼠标右键拖动: 缩放模型", "", "渲染模式:", " V: 顶点模式", " E: 边模式", " F: 面模式", " R: 真实感模式", "", "变换控制:", " T: 切换变换模式(旋转/平移/缩放)", " S: 重置变换", " P: 显示/隐藏变换点", "", "其他:", " H: 显示/隐藏帮助", " L: 切换光源", " X: 切换纹理", " 1/2: 设置变换点", " 3: 重置变换点", " F1: 系统复位", " ESC: 退出程序", };*/ const char* helpText[] = { "Sphere Mesh Viewer - Help", //球面网格查看器 - 帮助信息 "--------------------------------", "View Controls:", //视图控制: " Left mouse drag: Rotate model", // 鼠标左键拖动: 旋转模型 " Right mouse drag: Zoom model", //鼠标右键拖动: 缩放模型 "", "Render Modes:", //渲染模式 " V: Vertex mode", //V: 顶点模式 " E: Edge mode", //E: 边模式 " F: Face mode", //F: 面模式 " R: Realistic mode", //R: 真实感模式 "", "Transform Controls:", //变换控制 " T: Toggle transform mode (Rotate/Translate/Scale)", //T: 切换变换模式(旋转/平移/缩放) " S: Reset transform", //S: 重置变换 " P: Show/Hide transform points", //P: 显示/隐藏变换点 "", "Other:", " H: Show/Hide help", // H: 显示/隐藏帮助 " L: Toggle lighting", // L: 切换光源 " X: Toggle texture", // X: 切换纹理 " 1/2: Set transform points", // 1/2: 设置变换点 " 3: Reset transform points", // 3: 重置变换点 " F1: System reset", //F1: 系统复位 " ESC: Quit program", // ESC: 退出程序 }; int numLines = sizeof(helpText) / sizeof(char*); for (int i = 0; i < numLines; i++) { const char* line = helpText[i]; while (*line) { glutBitmapCharacter(GLUT_BITMAP_9_BY_15, *line); line++; } glRasterPos2f(10, 580 - (i + 1) * 18); } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glEnable(GL_LIGHTING); } // 显示状态信息 void drawStatus() { glDisable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0, 800, 0, 600); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor3f(0.8f, 0.8f, 1.0f); glRasterPos2f(10, 20); // 当前模式信息 char modeInfo[256]; const char* drawModes[] = { "Vertex", "Edge", "Face", "Realistic" }; // const char* drawModes[] = { "顶点", "边", "面", "真实感" }; const char* transformModes[] = { "Rotate", "Translate", "Scale" }; //const char* transformModes[] = { "旋转", "平移", "缩放" }; sprintf_s(modeInfo, sizeof(modeInfo), "Render Mode: %s | Transform Mode: %s | Lighting: %s | Texture: %s", //sprintf_s(modeInfo, sizeof(modeInfo), "渲染模式: %s | 变换模式: %s | 光源: %s | 纹理: %s", drawModes[appState.drawMode], transformModes[appState.transform.transformMode], glIsEnabled(GL_LIGHTING) ? "On" : "Off", // glIsEnabled(GL_LIGHTING) ? "开" : "关", appState.textureEnabled ? "On" : "Off"); //appState.textureEnabled ? "开" : "关"); const char* p = modeInfo; while (*p) { glutBitmapCharacter(GLUT_BITMAP_9_BY_15, *p); p++; } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glEnable(GL_LIGHTING); } // 显示回调函数 void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // 设置相机 gluLookAt(0.0, 0.0, 5.0, // 相机位置 0.0, 0.0, 0.0, // 观察点 0.0, 1.0, 0.0); // 上方向 // 应用交互变换 applyTransformations(); // 应用球面变换 applySphereTransformation(); // 绘制坐标轴 drawAxes(); // 绘制变换点 drawTransformPoints(); // 根据绘制模式渲染网格 if (appState.drawMode == 3) { // 真实感模式 if (appState.textureEnabled) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, appState.textureID); } else { glDisable(GL_TEXTURE_2D); } glBegin(GL_TRIANGLES); for (int i = 0; i < appState.mesh.numFaces; i++) { int v1 = appState.mesh.faces[i].v1; int v2 = appState.mesh.faces[i].v2; int v3 = appState.mesh.faces[i].v3; // 顶点1 glNormal3f(appState.mesh.normals[v1].x, appState.mesh.normals[v1].y, appState.mesh.normals[v1].z); glTexCoord2f(appState.mesh.texCoords[2 * v1], appState.mesh.texCoords[2 * v1 + 1]); glVertex3f(appState.mesh.vertices[v1].x, appState.mesh.vertices[v1].y, appState.mesh.vertices[v1].z); // 顶点2 glNormal3f(appState.mesh.normals[v2].x, appState.mesh.normals[v2].y, appState.mesh.normals[v2].z); glTexCoord2f(appState.mesh.texCoords[2 * v2], appState.mesh.texCoords[2 * v2 + 1]); glVertex3f(appState.mesh.vertices[v2].x, appState.mesh.vertices[v2].y, appState.mesh.vertices[v2].z); // 顶点3 glNormal3f(appState.mesh.normals[v3].x, appState.mesh.normals[v3].y, appState.mesh.normals[v3].z); glTexCoord2f(appState.mesh.texCoords[2 * v3], appState.mesh.texCoords[2 * v3 + 1]); glVertex3f(appState.mesh.vertices[v3].x, appState.mesh.vertices[v3].y, appState.mesh.vertices[v3].z); } glEnd(); glDisable(GL_TEXTURE_2D); } else { // 点、线、面模式 glDisable(GL_LIGHTING); if (appState.drawMode == 0) { // 点模式 glPointSize(3.0f); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_POINTS); for (int i = 0; i < appState.mesh.numVertices; i++) { glVertex3f(appState.mesh.vertices[i].x, appState.mesh.vertices[i].y, appState.mesh.vertices[i].z); } glEnd(); } else if (appState.drawMode == 1) { // 边模式 glLineWidth(1.5f); glColor3f(0.4f, 0.6f, 1.0f); glBegin(GL_LINES); for (int i = 0; i < appState.mesh.numFaces; i++) { int v1 = appState.mesh.faces[i].v1; int v2 = appState.mesh.faces[i].v2; int v3 = appState.mesh.faces[i].v3; glVertex3f(appState.mesh.vertices[v1].x, appState.mesh.vertices[v1].y, appState.mesh.vertices[v1].z); glVertex3f(appState.mesh.vertices[v2].x, appState.mesh.vertices[v2].y, appState.mesh.vertices[v2].z); glVertex3f(appState.mesh.vertices[v2].x, appState.mesh.vertices[v2].y, appState.mesh.vertices[v2].z); glVertex3f(appState.mesh.vertices[v3].x, appState.mesh.vertices[v3].y, appState.mesh.vertices[v3].z); glVertex3f(appState.mesh.vertices[v3].x, appState.mesh.vertices[v3].y, appState.mesh.vertices[v3].z); glVertex3f(appState.mesh.vertices[v1].x, appState.mesh.vertices[v1].y, appState.mesh.vertices[v1].z); } glEnd(); } else if (appState.drawMode == 2) { // 面模式 glColor3f(0.2f, 0.8f, 0.3f); glBegin(GL_TRIANGLES); for (int i = 0; i < appState.mesh.numFaces; i++) { int v1 = appState.mesh.faces[i].v1; int v2 = appState.mesh.faces[i].v2; int v3 = appState.mesh.faces[i].v3; glVertex3f(appState.mesh.vertices[v1].x, appState.mesh.vertices[v1].y, appState.mesh.vertices[v1].z); glVertex3f(appState.mesh.vertices[v2].x, appState.mesh.vertices[v2].y, appState.mesh.vertices[v2].z); glVertex3f(appState.mesh.vertices[v3].x, appState.mesh.vertices[v3].y, appState.mesh.vertices[v3].z); } glEnd(); } glEnable(GL_LIGHTING); } // 绘制帮助信息 drawHelp(); // 绘制状态信息 drawStatus(); glutSwapBuffers(); } // 窗口大小调整回调 void reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (double)width / height, 0.1, 100.0); glMatrixMode(GL_MODELVIEW); } // 键盘回调 void keyboard(unsigned char key, int x, int y) { switch (key) { case 'v': case 'V': // 顶点模式 appState.drawMode = 0; break; case 'e': case 'E': // 边模式 appState.drawMode = 1; break; case 'f': case 'F': // 面模式 appState.drawMode = 2; break; case 'r': case 'R': // 真实感模式 appState.drawMode = 3; break; case 't': case 'T': // 切换变换模式 appState.transform.transformMode = (appState.transform.transformMode + 1) % 3; break; case 's': case 'S': // 重置变换 appState.transform.translation.x = 0.0f; appState.transform.translation.y = 0.0f; appState.transform.translation.z = 0.0f; appState.transform.rotation.x = 0.0f; appState.transform.rotation.y = 0.0f; appState.transform.rotation.z = 0.0f; appState.transform.scale = 1.0f; break; case 'h': case 'H': // 显示/隐藏帮助 appState.showHelp = !appState.showHelp; break; case 'p': case 'P': // 显示/隐藏变换点 appState.showTransformPoints = !appState.showTransformPoints; break; case 'l': case 'L': // 切换光源 if (glIsEnabled(GL_LIGHTING)) { glDisable(GL_LIGHTING); } else { glEnable(GL_LIGHTING); } break; case 'x': case 'X': // 切换纹理 appState.textureEnabled = !appState.textureEnabled; break; case '1': // 设置Q1点 appState.q1.x = 0.0f; appState.q1.y = 1.5f; appState.q1.z = 0.0f; break; case '2': // 设置Q2点 appState.q2.x = 0.0f; appState.q2.y = -1.5f; appState.q2.z = 0.0f; break; case '3': // 重置变换点 appState.q1 = appState.originalP1; appState.q2 = appState.originalP2; break; case 27: // ESC键退出 exit(0); break; } glutPostRedisplay(); } // 特殊键盘回调(功能键) void specialKeys(int key, int x, int y) { switch (key) { case GLUT_KEY_F1: // 系统复位 appState.transform.translation.x = 0.0f; appState.transform.translation.y = 0.0f; appState.transform.translation.z = 0.0f; appState.transform.rotation.x = 0.0f; appState.transform.rotation.y = 0.0f; appState.transform.rotation.z = 0.0f; appState.transform.scale = 1.0f; appState.q1 = appState.originalP1; appState.q2 = appState.originalP2; break; case GLUT_KEY_UP: // 向上平移 if (appState.transform.transformMode == 1) { appState.transform.translation.y += 0.1f; } break; case GLUT_KEY_DOWN: // 向下平移 if (appState.transform.transformMode == 1) { appState.transform.translation.y -= 0.1f; } break; case GLUT_KEY_LEFT: // 向左平移 if (appState.transform.transformMode == 1) { appState.transform.translation.x -= 0.1f; } break; case GLUT_KEY_RIGHT: // 向右平移 if (appState.transform.transformMode == 1) { appState.transform.translation.x += 0.1f; } break; } glutPostRedisplay(); } // 鼠标按钮回调 void mouseButton(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON) { if (state == GLUT_DOWN) { appState.mouseLeftDown = 1; appState.lastMouseX = x; appState.lastMouseY = y; } else if (state == GLUT_UP) { appState.mouseLeftDown = 0; } } else if (button == GLUT_RIGHT_BUTTON) { if (state == GLUT_DOWN) { appState.mouseRightDown = 1; appState.lastMouseX = x; appState.lastMouseY = y; } else if (state == GLUT_UP) { appState.mouseRightDown = 0; } } } // 鼠标运动回调 void mouseMotion(int x, int y) { int dx = x - appState.lastMouseX; int dy = y - appState.lastMouseY; if (appState.mouseLeftDown) { if (appState.transform.transformMode == 0) { // 旋转模式 appState.transform.rotation.y += dx * 0.5f; appState.transform.rotation.x += dy * 0.5f; } else if (appState.transform.transformMode == 1) { // 平移模式 appState.transform.translation.x += dx * 0.01f; appState.transform.translation.y -= dy * 0.01f; } } else if (appState.mouseRightDown) { if (appState.transform.transformMode == 2) { // 缩放模式 appState.transform.scale += dy * 0.01f; if (appState.transform.scale < 0.1f) appState.transform.scale = 0.1f; } } appState.lastMouseX = x; appState.lastMouseY = y; glutPostRedisplay(); } // 初始化应用程序状态 void initAppState() { memset(&appState, 0, sizeof(AppState)); appState.drawMode = 3; // 默认真实感模式 appState.transform.scale = 1.0f; appState.showHelp = 1; // 初始显示帮助 appState.showTransformPoints = 1; // 初始显示变换点 appState.textureEnabled = 1; } // 主函数 int main(int argc, char** argv) { // 初始化GLUT glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(800, 600); glutCreateWindow("球面网格查看器 - 图形学与虚拟现实实验"); // 初始化应用程序状态 initAppState(); // 加载网格数据 ReadMesh("sphere30x20.msh"); // 设置回调函数 initGL(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutSpecialFunc(specialKeys); glutMouseFunc(mouseButton); glutMotionFunc(mouseMotion); // 主循环 glutMainLoop(); // 清理 free(appState.mesh.vertices); free(appState.mesh.faces); free(appState.mesh.normals); free(appState.mesh.texCoords); return 0; }这段代码能改成仅仅试用glad glfw的库吗
最新发布
06-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值