Windows下stdlib.h与glut.h中exit()函数重复定义的解决方案

本文介绍了解决Windows环境下使用GLUT进行OpenGL开发时遇到的exit()函数在stdlib.h与glut.h中重复定义的问题。通过修改glut.h中的exit()声明,可以避免编译错误。

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

The Solution for 'redefinition of exit()' in glut.h and stdlib.h

 

 

    When develop GLUT projects in Windows system, we always encounter this problem or like:

 

D:/Program Files/Microsoft Visual Studio .NET2003/Vc7/include/stdlib.h(256) : error C2381: 'exit' : redefinition;__declspec(noreturn) differs
D:/programs/glut-3.7.6-bin/GL/glut.h(146) : see declaration of'exit'

 

    We could simply solve this problem by opening glut.h and find the definition of exit() function (about line 144). Replace them by following. Then rebuild project:


  1. #if defined(_WIN32)  
  2. # ifndef GLUT_BUILDING_LIB  
  3. #if _MSC_VER >= 1200  
  4. _CRTIMP __declspec(noreturnvoid __cdecl exit(int);  
  5. #else  
  6. _CRTIMP void __cdecl exit(int);  
  7. #endif  
  8. # endif  
  9. #else  

 

 

    Windows下用到GLUT进行OpenGL开发时,时常会碰到exit()这个函数在stdlib.h与glut.h两个头文件中重复定义的情况,解决方案如下:

    打开glut.h,找到exit()函数定义的地方(144行左右),替换为以下内容:

 

  1. #if defined(_WIN32)  
  2. # ifndef GLUT_BUILDING_LIB  
  3. #if _MSC_VER >= 1200  
  4. _CRTIMP __declspec(noreturnvoid __cdecl exit(int);  
  5. #else  
  6. _CRTIMP void __cdecl exit(int);  
  7. #endif  
  8. # endif  
  9. #else  

 

    然后重新编译项目即可。

#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
要在代码中将 `WordMap.jpg` 图片作为纹理映射到球体上,需要进行以下步骤: 1. **加载纹理图像**:使用 OpenGL 的扩展库(如 SOIL 或者 stb_image)来加载纹理图像。 2. **生成和绑定纹理对象**:创建纹理对象并绑定到球体上。 3. **修改绘制函数**:在绘制球体时启用纹理,并设置纹理坐标。 以下是修改后的代码示例,假设你已经安装了 `SOIL` 库来加载纹理图像: ```cpp #include <windows.h> #include <GL/glut.h> #include <stdlib.h> #include <SOIL/SOIL.h> // 引入SOIL库 GLuint texture_id; void loadTexture(const char* filename) { texture_id = SOIL_load_OGL_texture( filename, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT ); if(texture_id == 0) { fprintf(stderr, "SOIL loading error: '%s'\n", SOIL_last_result()); exit(1); } glBindTexture(GL_TEXTURE_2D, texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } void init(void) { glClearColor(0, 0, 0, 0); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // 光照参数配置 GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); // 加载纹理 loadTexture("WordMap.jpg"); // 额外的光照参数配置 GLfloat light1_ambient[] = { 0.1, 0.1, 0.1, 1.0 }; GLfloat light1_diffuse[] = { 0.5, 0.5, 0.5, 1.0 }; GLfloat light1_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light1_position[] = { 1.0, 2.0, 3.0, 0.0 }; glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular); glLightfv(GL_LIGHT1, GL_POSITION, light1_position); glEnable(GL_LIGHT1); GLfloat light2_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; GLfloat light2_diffuse[] = { 0.8, 0.8, 0.8, 1.0 }; GLfloat light2_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light2_position[] = { -1.0, -2.0, -3.0, 0.0 }; glLightfv(GL_LIGHT2, GL_AMBIENT, light2_ambient); glLightfv(GL_LIGHT2, GL_DIFFUSE, light2_diffuse); glLightfv(GL_LIGHT2, GL_SPECULAR, light2_specular); glLightfv(GL_LIGHT2, GL_POSITION, light2_position); glEnable(GL_LIGHT2); } void display() { double time = glutGet(GLUT_ELAPSED_TIME) / 1000.0; double a = time * 90.0; glClearColor(0.0f, 0.34f, 0.57f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 绘制第一个球体 glPushMatrix(); glTranslatef(-0.3, 0.0, 0.0); glTranslated(-0.5, 0.5, -3); glRotatef(285.0, 1.0, 0.0, 0.0); glRotatef(90.0, 1.0, 0.0, 0.0); glRotated(a, 0, 0, 1); // 启用纹理 glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture_id); glutSolidSphere(0.5, 30, 30); // 实心球 // 禁用纹理 glDisable(GL_TEXTURE_2D); glPopMatrix(); // 绘制第二个球体 glPushMatrix(); glTranslatef(0.7, 0.0, 0.0); glTranslated(-0.5, -0.5, -3); glRotatef(90.0, 1.0, 0.0, 0.0); glRotatef(90.0, 1.0, 0.0, 0.0); glRotated(a, 0, 0, 1); // 启用纹理 glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture_id); glutSolidSphere(0.5, 30, 30); // 实心球 // 禁用纹理 glDisable(GL_TEXTURE_2D); glPopMatrix(); glutSwapBuffers(); } void idle(void) { glutPostRedisplay(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowPosition(100, 100); glutInitWindowSize(500, 500); glutCreateWindow("旋转球"); glutReshapeFunc(resize); glutDisplayFunc(display); glutIdleFunc(idle); init(); glutMainLoop(); return 0; } ``` ### 关键点说明: 1. **加载纹理**:使用 `SOIL_load_OGL_texture` 函数加载纹理图像,并生成纹理 ID。 2. **启用纹理**:在绘制球体之前,启用纹理并绑定纹理对象。 3. **禁用纹理**:在绘制完球体后,禁用纹理以避免影响其他图形的绘制。 确保你在编译时链接了 SOIL 库,例如: ```sh g++ your_code.cpp -lglut -lGL -lGLU -lSOIL ``` 这样,`WordMap.jpg` 就会被正确地映射到球体上了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值