为啥我的 OpenGL 纹理不起作用?
Posted
技术标签:
【中文标题】为啥我的 OpenGL 纹理不起作用?【英文标题】:Why don't my OpenGL textures work?为什么我的 OpenGL 纹理不起作用? 【发布时间】:2012-11-24 16:13:44 【问题描述】:我正在尝试恢复我在大学工作的一个旧项目。
这是一个基本的 OpenGL 动画,带有一些相机控件和模型加载。我已经让它工作了,但我不知道为什么没有为“天空盒”或“云平面”加载纹理。
我确信几年前他们使用几乎相同的代码。我所做的最大改变是从 SDL 移植到 GLUT,但我不知道这会对事情产生什么影响。
以下是一些与渲染天空盒相关的行:
glBindTexture(GL_TEXTURE_2D, skybox[i]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glVertexPointer(3, GL_FLOAT, 0, face);
glTexCoordPointer(2, GL_FLOAT, 0, texture);
glDrawArrays(GL_QUADS, 0, 4);
我没有收到任何警告或运行时异常。纹理根本不显示。
我的代码中有这样的内容:glEnableClientState(GL_TEXTURE_COORD_ARRAY);
和 glEnable(GL_TEXTURE_2D);
有什么想法吗?我真的很想让它再次正常工作。
完整来源在这里:
//Camera start location and rotation, boundaries are -0.5 -> +0.5 in each axis.
#define CAMERA_START_X -0.6
#define CAMERA_START_Y -0.2
#define CAMERA_START_Z -1.8
#define CAMERA_START_R 330
#define CAMERA_START_MOMENTUM 0.15
//Camera keyboard-event motion speed per second, independent of frame rate or machine.
#define CAMERA_ROTATION 100
#define CAMERA_ELEVATION 2
#define CAMERA_MOMENTUM 0.1
//Cloud plane configuration constants.
#define CLOUDS 12
#define CLOUD_SECTIONS 3
#define CLOUD_INNER_PLANES 0.2
#define CLOUD_OUTER_PLANES 0.8
//Frame rate, lowering the frame rate may improve performance on older computers.
#define FPS 60
//Other global constants.
#define PI 3.141592
#define SCALE_FACTOR 0.0001
//Print OpenGL errors to console if true.
#define DEBUG false
#include <GLUT/glut.h>
#include "glm.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
//*****************************************
// Global Variables
//*****************************************
//Use glm's texture id variable to maintain consistency.
extern GLenum _glmTextureTarget;
//Models.
GLMmodel* eagle;
GLMmodel* airplane;
//Cloud plane.
float cloudPlaneV[CLOUDS][CLOUDS][7][CLOUD_SECTIONS][3];
GLuint cloudTexture;
//Camera location and rotation.
float cameraX = CAMERA_START_X * SCALE_FACTOR;
float cameraY = CAMERA_START_Y * SCALE_FACTOR;
float cameraZ = CAMERA_START_Z * SCALE_FACTOR;
float cameraR = CAMERA_START_R;
//Key event values for camera control.
float rotationDirection = 0;
float elevationDirection = 0;
float momentumDirection = 0;
//Skybox texture indices.
GLuint skybox[6];
//Skybox vertices.
GLfloat vertices[8][3] =
-1, -1, -1, // 0: left, bottom, back
-1, -1, +1, // 1: left, bottom, front
-1, +1, -1, // 2: left, top, back
-1, +1, +1, // 3: left, top, front
+1, -1, -1, // 4: right, bottom, back
+1, -1, +1, // 5: right, bottom, front
+1, +1, -1, // 6: right, top, back
+1, +1, +1;// 7: right, top, front
//Skybox cube faces.
GLubyte faces[6][4] =
1, 0, 2, 3, // 0: west
4, 5, 7, 6, // 1: east
4, 0, 1, 5, // 2: below
7, 3, 2, 6, // 3: above
5, 1, 3, 7, // 4: south
0, 4, 6, 2;// 5: north
//Standard texture winding.
GLfloat texture[4][2] =
0.0, 0.0, // 0: left, bottom
1.0, 0.0, // 1: right, bottom
1.0, 1.0, // 2: right, top
0.0, 1.0;// 3: left, top
//Animation variables.
bool fullscreen = 0;
float window_w, window_h;
bool forceReshape = false;
int frame = -1;
bool paused = false;
float momentum = CAMERA_START_MOMENTUM * SCALE_FACTOR;
float momentumBeforePause;
float planePriorX = 0, planePriorY = 0, planePriorZ = 0;
float planePostX = 0, planePostY = 0, planePostZ = 0;
float planeRotX = 0, planeRotY = 0, planeRotZ = 0;
float eaglePriorX = -0.5, eaglePriorY = 0.03, eaglePriorZ = 0.1;
float eaglePostX = 0, eaglePostY = 0, eaglePostZ = 0;
float eagleRotX = 0, eagleRotY = 0, eagleRotZ = 0;
//*****************************************
// Loading Objects
//*****************************************
void loadObjects()
eagle = glmReadOBJ("resources/models/eagle.obj");
glmVertexNormals(eagle, 180.0, false);
glmUnitize(eagle);
airplane = glmReadOBJ("resources/models/airplane.obj");
glmVertexNormals(airplane, 180.0, false);
glmUnitize(airplane);
//*****************************************
// Camera
//*****************************************
void updateCamera()
//Reset position and rotation.
glLoadIdentity();
//Camera rotation.
cameraR += rotationDirection * CAMERA_ROTATION / FPS;
if (cameraR < 0) cameraR += 360;
if (cameraR > 360) cameraR -= 360;
//Camera location.
momentum += momentumDirection * CAMERA_MOMENTUM * SCALE_FACTOR / FPS;
if (momentum < 0) momentum = 0;
cameraX += momentum * -sin(cameraR * PI / 180);
cameraY += elevationDirection * CAMERA_ELEVATION * SCALE_FACTOR / FPS;
cameraZ += momentum * cos(cameraR * PI / 180);
//Move the world, not the camera.
glRotatef(cameraR, 0, 1, 0);
glTranslatef(cameraX, cameraY, cameraZ);
//*****************************************
// Skybox
//*****************************************
void loadSkybox()
GLfloat width = 600, height = 600;
skybox[0] = glmLoadTexture("resources/textures/skybox/west.jpeg", GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, &width, &height);
skybox[1] = glmLoadTexture("resources/textures/skybox/east.jpeg", GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, &width, &height);
skybox[2] = glmLoadTexture("resources/textures/skybox/bottom.jpeg", GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, &width, &height);
skybox[3] = glmLoadTexture("resources/textures/skybox/top.jpeg", GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, &width, &height);
skybox[4] = glmLoadTexture("resources/textures/skybox/south.jpeg", GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, &width, &height);
skybox[5] = glmLoadTexture("resources/textures/skybox/north.jpeg", GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, &width, &height);
//Draws the skybox.
void drawSkybox()
//Disable lighting, enable textures.
glDisable(GL_LIGHTING);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//Augment such that camera is at the center.
GLfloat center[8][3];
for (int i = 0; i < 8; i++)
center[i][0] = vertices[i][0] - cameraX;
center[i][1] = vertices[i][1] - cameraY;
center[i][2] = vertices[i][2] - cameraZ;
//Draw eace face.
GLfloat face[4][3];
for (int i = 0; i < 6; i++)
for (int j = 0; j < 4; j++)
for (int k = 0; k < 3; k++)
face[j][k] = center[faces[i][j]][k];
glBindTexture(GL_TEXTURE_2D, skybox[i]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glVertexPointer(3, GL_FLOAT, 0, face);
glTexCoordPointer(2, GL_FLOAT, 0, texture);
glDrawArrays(GL_QUADS, 0, 4);
//Enable lighting, disable textures.
glEnable(GL_LIGHTING);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//*****************************************
// Cloud Plane
//*****************************************
void calculateCloudPlane()
//Calculate the increment.
float incr = 2 * PI / CLOUD_SECTIONS;
//Use cosArr and sinArr to reuse the sine and cosine calculation.
float cosArr[CLOUD_SECTIONS + 1], sinArr[CLOUD_SECTIONS + 1];
for (int i = 0; i < CLOUD_SECTIONS + 1; i++)
cosArr[i] = cos(i * incr);
sinArr[i] = sin(i * incr);
//Calculate a circle.
float circle[CLOUD_SECTIONS][3];
for (int i = 0; i < CLOUD_SECTIONS; i++)
circle[i][0] = cosArr[i];
circle[i][1] = 0;
circle[i][2] = sinArr[i];
//Calculate a cloud from the circle.
float cloud[7][CLOUD_SECTIONS][3];
float xScale, zScale, xTrans, zTrans;
for (int i = 0; i < 7; i++)
switch (i)
//Scale everything down quite a bit, we only want a light covering.
case 0: xScale = 0.0625; zScale = 0.0625; xTrans = 0; zTrans = 0;
break;
case 1: xScale = 0.0625; zScale = 0.0625; xTrans = 0.0625; zTrans = 0;
break;
case 2: xScale = 0.0625; zScale = 0.0625; xTrans = -0.0625; zTrans = 0;
break;
case 3: xScale = 0.0625; zScale = 0.0625; xTrans = 0.0625 * cos(60 * PI / 180); zTrans = 0.0625 * sin(60 * PI / 180);
break;
case 4: xScale = 0.0625; zScale = 0.0625; xTrans = 0.0625 * cos(120 * PI / 180); zTrans = 0.0625 * sin(120 * PI / 180);
break;
case 5: xScale = 0.0625; zScale = 0.0625; xTrans = 0.0625 * cos(240 * PI / 180); zTrans = 0.0625 * sin(240 * PI / 180);
break;
case 6: xScale = 0.0625; zScale = 0.0625; xTrans = 0.0625 * cos(300 * PI / 180); zTrans = 0.0625 * sin(300 * PI / 180);
break;
for (int j = 0; j < CLOUD_SECTIONS; j++)
cloud[i][j][0] = circle[j][0] * xScale + xTrans;
cloud[i][j][1] = circle[j][1];
cloud[i][j][2] = circle[j][2] * zScale + zTrans;
//Calculate a cloud plane from the cloud.
for (int i = 0; i < CLOUDS; i++)
for (int j = 0; j < CLOUDS; j++)
for (int k = 0; k < 7; k++)
for (int l = 0; l < CLOUD_SECTIONS; l++)
cloudPlaneV[i][j][k][l][0] = cloud[k][l][0] - CLOUDS / 2 + i;
cloudPlaneV[i][j][k][l][1] = cloud[k][l][1];
cloudPlaneV[i][j][k][l][2] = cloud[k][l][2] - CLOUDS / 2 + j;
//Load texture.
float width = 256, height = 256;
cloudTexture = glmLoadTexture("resources/textures/cloud.jpeg", GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, &width, &height);
//Draws 4 planes containing 'cloud' type objects with parameters defined as constants above.
void drawCloudPlane()
glPushMatrix();
glDisable(GL_LIGHTING);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//Move the plane with camera, utilises integer truncation.
int xOffset = -cameraX / SCALE_FACTOR;
float yOffset = -cameraY / SCALE_FACTOR;
int zOffset = -cameraZ / SCALE_FACTOR;
glTranslatef(xOffset, yOffset, zOffset);
//Bind data pointers.
glBindTexture(GL_TEXTURE_2D, cloudTexture);
glVertexPointer(3, GL_FLOAT, 0, cloudPlaneV);
glTexCoordPointer(2, GL_FLOAT, 0, texture);
//Top plane.
glPushMatrix();
glTranslatef(0, CLOUD_OUTER_PLANES, 0);
for (int i = 0; i < CLOUDS * CLOUDS * 7; i++)
glDrawArrays(GL_POLYGON, i * CLOUD_SECTIONS, CLOUD_SECTIONS);
glPopMatrix();
//2nd plane.
glPushMatrix();
glTranslatef(0, CLOUD_INNER_PLANES, 0);
for (int i = 0; i < CLOUDS * CLOUDS * 7; i++)
glDrawArrays(GL_POLYGON, i * CLOUD_SECTIONS, CLOUD_SECTIONS);
glPopMatrix();
//3rd plane.
glPushMatrix();
glTranslatef(0, -CLOUD_INNER_PLANES, 0);
for (int i = 0; i < CLOUDS * CLOUDS * 7; i++)
glDrawArrays(GL_POLYGON, i * CLOUD_SECTIONS, CLOUD_SECTIONS);
glPopMatrix();
//Bottom plane.
glPushMatrix();
glTranslatef(0, -CLOUD_OUTER_PLANES, 0);
for (int i = 0; i < CLOUDS * CLOUDS * 7; i++)
glDrawArrays(GL_POLYGON, i * CLOUD_SECTIONS, CLOUD_SECTIONS);
glPopMatrix();
glEnable(GL_LIGHTING);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
//*****************************************
// Lights
//*****************************************
//Set up lights at points on the skybox that match the textures.
void setupLights()
glEnable(GL_LIGHTING);
glEnable(_glmTextureTarget);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_RESCALE_NORMAL);
//Set global ambience.
GLfloat global_ambient[] = 0.5, 0.5, 0.5, 1;
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
//Set up a light source at the sun's location.
glEnable(GL_LIGHT0);
GLfloat light0_ambient[] = 0, 0, 0, 1;
GLfloat light0_diffuse[] = 0.5, 0.5, 0.5, 1;
GLfloat light0_specular[] = 0.7, 0.7, 0.7, 1;
GLfloat light0_position[] = -1, 1, -1, 1;
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
//Set up a light source at the sun's reflection.
//The reflection is half as bright as the sun.
glEnable(GL_LIGHT1);
GLfloat light1_ambient[] = 0, 0, 0, 1;
GLfloat light1_diffuse[] = 0.25, 0.25, 0.25, 1;
GLfloat light1_specular[] = 0.35, 0.35, 0.35, 1;
GLfloat light1_position[] = -1, -1, -1, 1;
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);
//This augments the lighting to match the skybox, required after camera rotation.
void augmentLights()
GLfloat light0_position[] = -1 / SCALE_FACTOR, 1 / SCALE_FACTOR, -1 / SCALE_FACTOR, 1;
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
GLfloat light1_position[] = -1 / SCALE_FACTOR, -1 / SCALE_FACTOR, -1 / SCALE_FACTOR, 1;
glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
//*****************************************
// Main Scene
//*****************************************
void drawEagle()
glPushMatrix();
//Scale the eagle down to size.
glScalef(0.5, 0.5, 0.5);
//Face forward.
glRotatef(180, 0, 1, 0);
glmDraw(eagle, GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
void drawAirplane()
glPushMatrix();
//Rotate the plane so that it faces forward.
glRotatef(270, 1, 0, 0);
glRotatef(90, 0, 0, 1);
glmDraw(airplane, GLM_SMOOTH | GLM_MATERIAL | GLM_TEXTURE);
glPopMatrix();
//Keeps angles within bounds - prevents overflow.
void bounds(float &angle)
if (angle > 360) angle -= 360;
if (angle < 0) angle += 360;
void drawScene()
glPushMatrix();
//Set the animation control variables.
if (!paused) frame++;
int ticks = frame % 1440;
if (frame % 1440 == 0)
ticks = 0;
//Reset animation object positions and rotations.
planePriorX = 0, planePriorY = 0, planePriorZ = 0;
planePostX = 0, planePostY = 0, planePostZ = 0;
planeRotX = 0, planeRotY = 0, planeRotZ = 0;
eaglePriorX = -0.5, eaglePriorY = 0.03, eaglePriorZ = -0.1;
eaglePostX = 0, eaglePostY = 0, eaglePostZ = 0;
eagleRotX = 0, eagleRotY = 0, eagleRotZ = 0;
//Apply scene transformations.
glRotatef(30, 0, 1, 0);
glTranslatef(0, 0, -1500 * frame * SCALE_FACTOR);
//Make sure angles are in bounds.
bounds(planeRotX); bounds(planeRotY); bounds(planeRotZ);
bounds(eagleRotX); bounds(eagleRotY); bounds(eagleRotZ);
if (!paused)
//Airplane transformation events.
//Constant swaying.
planeRotZ -= 0.5 * cos(ticks * 2 * PI / 180);
planePostY -= 0.01 * cos(ticks * PI / 180);
//Spin upside-down.
if (ticks >= 180 && ticks < 360) planeRotZ -= PI * 0.5 * sin(ticks * PI / 180);
//Spin back round.
if (ticks >= 360 && ticks < 540) planeRotZ += PI * 0.5 * sin(ticks * PI / 180);
//Dive.
if (ticks >= 720 && ticks < 900)
planeRotX -= 0.25 * PI * sin(ticks * 2 * PI / 180);
planePriorY -= 0.005 * PI * sin(ticks * PI / 180);
planePriorZ -= 0.01 * PI * sin(ticks * 0.5 * PI / 180);
//Loop-the-loop
if (ticks >= 900 && ticks < 1220)
planeRotX += 1;
planePriorY += 0.015 * PI * sin((ticks - 180) * PI / 180);
planePriorZ -= 0.015 * PI * cos((ticks - 180) * PI / 180);
//Reset position.
if (ticks >= 1220 && ticks < 1440)
// These values were found by minimising errors using binary division.
planeRotX -= 0.1262345 * PI * sin(ticks * PI / 180);
planePriorY -= 0.002379563 * PI * sin(ticks * 0.5 * PI / 180);
planePriorZ -= 0.003826425 * PI * sin(ticks * 0.5 * PI / 180);
//Eagle transformation events.
//Set default position.
eaglePriorX = -1;
eaglePriorZ = 0.4;
//Set start position over left wing.
if (ticks >= 0 && ticks < 180)
eaglePriorX = -0.5;
eaglePriorY = 0.03;
eaglePriorZ = -0.1;
//Move a little with the wing.
if (ticks >= 0 && ticks < 90)
eagleRotZ -= cos(ticks * 2 * PI / 180);
eaglePostY -= 0.009 * sin(ticks * 2 * PI / 180);
//Move back, up and left.
if (ticks >= 90 && ticks < 180)
eaglePriorX -= (float)0.5 / 90 * (ticks - 90);
eaglePriorZ += (float)0.5 / 90 * (ticks - 90);
eaglePostY += 0.009 * sin((ticks - 90) * 2 * PI / 180);
//Swaying.
if (ticks >= 90 && ticks < 1350)
eagleRotZ -= 0.6 * cos((ticks + 90) * PI / 180);
eaglePostY -= 0.01 * cos((ticks + 90) * 2 * PI / 180);
//Avoid plane collision.
if (ticks >= 360 && ticks < 540) eagleRotZ += 0.25 * PI * sin(ticks * 2 * PI / 180);
//Glide from side to side.
if (ticks >= 720 && ticks < 1080) eaglePriorX += 0.4 * PI * sin(ticks * 0.5 * PI / 180);
//Move back to start position.
if (ticks >= 1350 && ticks < 1440)
eaglePriorX += (float)0.5 / 90 * (ticks - 1350);
eaglePriorZ -= (float)0.5 / 90 * (ticks - 1350);
//Avoid plane collision.
if (ticks >= 1400 && ticks < 1420) eaglePriorY += 0.01;
if (ticks >= 1420 && ticks < 1440) eaglePriorY -= 0.01;
//Apply the transformations then draw the airplane.
glPushMatrix();
glTranslatef(planePriorX, planePriorY, planePriorZ);
glRotatef(planeRotX, 1, 0, 0);
glRotatef(planeRotY, 0, 1, 0);
glRotatef(planeRotZ, 0, 0, 1);
glTranslatef(planePostX, planePostY, planePostZ);
drawAirplane();
glPopMatrix();
//Apply the transformations then draw the eagle.
glPushMatrix();
glTranslatef(eaglePriorX, eaglePriorY, eaglePriorZ);
glRotatef(eagleRotX, 1, 0, 0);
glRotatef(eagleRotY, 0, 1, 0);
glRotatef(eagleRotZ, 0, 0, 1);
glTranslatef(eaglePostX, eaglePostY, eaglePostZ);
drawEagle();
glPopMatrix();
glPopMatrix();
//*****************************************
// GLUT
//*****************************************
//Initialisation function.
void init(int argc, char **argv)
//Initialise GLUT.
glutInit(&argc, argv);
// Use doule buffering.
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(760, 760);
//Create window.
glutCreateWindow("Come Fly With Me - by Chris Patuzzo");
//Set up camera.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, 1, 0.00001, 1 / SCALE_FACTOR);
glMatrixMode(GL_MODELVIEW);
//Set the clear color.
glClearColor(0, 0, 0, 1);
//Use z-buffer, lighting, normal scaling.
glEnable(GL_DEPTH_TEST);
//Set up two lights; the sun and its reflection.
setupLights();
//Use vertex arrays.
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_TEXTURE_2D);
//Load skybox and objects.
loadSkybox();
loadObjects();
//Calculate cloud plane.
calculateCloudPlane();
void reshape(int width, int height)
int min = (width > height) ? height : width;
glViewport((width - min) / 2, (height - min) / 2, min, min);
//Main display loop.
void display()
//Clear buffers.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Augment camera, draw skybox.
updateCamera();
drawSkybox();
//Scale the world and reset light positions.
glScalef(SCALE_FACTOR, SCALE_FACTOR, SCALE_FACTOR);
augmentLights();
//Draw the plane containing clouds and the main scene.
drawCloudPlane();
drawScene();
//Swap buffers.
glutSwapBuffers();
void timer(int n)
if (DEBUG)
printf("%s\n", gluErrorString(glGetError()));
fflush(stdout);
if (forceReshape)
float w = glutGet(GLUT_WINDOW_WIDTH);
float h = glutGet(GLUT_WINDOW_HEIGHT);
reshape(w, h);
glutPostRedisplay();
glutTimerFunc(1000 / FPS, timer, 0);
void keyDown(unsigned char key, int x, int y)
switch (key)
case 'q': exit(0);
case 'w': momentumDirection++; break;
case 'a': rotationDirection--; break;
case 's': momentumDirection--; break;
case 'd': rotationDirection++; break;
case '=': elevationDirection--; break;
case '-': elevationDirection++; break;
case '0': momentum = 0; break;
case ' ':
if (paused)
paused = false;
momentum = momentumBeforePause;
else
paused = true;
momentumBeforePause = momentum;
momentum = 0;
break;
case 'r':
//Reset the camera.
cameraX = CAMERA_START_X * SCALE_FACTOR;
cameraY = CAMERA_START_Y * SCALE_FACTOR;
cameraZ = CAMERA_START_Z * SCALE_FACTOR;
cameraR = CAMERA_START_R;
momentum = CAMERA_START_MOMENTUM * SCALE_FACTOR;
rotationDirection = 0;
elevationDirection = 0;
momentumDirection = 0;
//Reset animation frame, set unpaused.
frame = -1;
paused = false;
//Reset animation object positions and rotations.
planePriorX = 0, planePriorY = 0, planePriorZ = 0;
planePostX = 0, planePostY = 0, planePostZ = 0;
planeRotX = 0, planeRotY = 0, planeRotZ = 0;
eaglePriorX = -0.5, eaglePriorY = 0.03, eaglePriorZ = -0.1;
eaglePostX = 0, eaglePostY = 0, eaglePostZ = 0;
eagleRotX = 0, eagleRotY = 0, eagleRotZ = 0;
break;
case 'p':
//Pause the animation.
paused = true;
momentumBeforePause = momentum;
momentum = 0;
//Set frame.
frame = 605;
//Move the camera.
cameraX = 0.004524;
cameraY = 0.000052;
cameraZ = 0.007764;
cameraR = 306;
//Reset animation object positions and rotations.
planePriorX = 0, planePriorY = -0.871533, planePriorZ = -1.577791;
planePostX = 0, planePostY = -0.44244, planePostZ = 0;
planeRotX = 312, planeRotY = 0, planeRotZ = 13.651090;
eaglePriorX = -1, eaglePriorY = 0.03, eaglePriorZ = 0.4;
eaglePostX = 0, eaglePostY = -0.293748, eaglePostZ = 0;
eagleRotX = 0, eagleRotY = 0, eagleRotZ = 18.295479;
break;
case 'y':
//Pause the animation.
paused = true;
momentumBeforePause = momentum;
momentum = 0;
//Set frame.
frame = 224;
//Move the camera.
cameraX = 0.001829;
cameraY = -0.000004;
cameraZ = 0.00298;
cameraR = 138;
//Reset animation object positions and rotations.
planePriorX = 0, planePriorY = 0, planePriorZ = 0;
planePostX = 0, planePostY = -0.5829, planePostZ = 0;
planeRotX = 0, planeRotY = 0, planeRotZ = 267.401611;
eaglePriorX = -1, eaglePriorY = 0.03, eaglePriorZ = 0.4;
eaglePostX = 0, eaglePostY = 0.000001, eaglePostZ = 0;
eagleRotX = 0, eagleRotY = 0, eagleRotZ = 43.981647;
break;
case 'u':
//Pause the animation.
paused = true;
momentumBeforePause = momentum;
momentum = 0;
//Set frame.
frame = -1;
//Move the camera.
cameraX = 0.000094;
cameraY = -0.000036;
cameraZ = -0.000103;
cameraR = 42;
//Reset animation object positions and rotations.
planePriorX = 0, planePriorY = 0, planePriorZ = 0;
planePostX = 0, planePostY = 0, planePostZ = 0;
planeRotX = 0, planeRotY = 0, planeRotZ = 0;
eaglePriorX = -0.5, eaglePriorY = 0.03, eaglePriorZ = -0.1;
eaglePostX = 0, eaglePostY = 0, eaglePostZ = 0;
eagleRotX = 0, eagleRotY = 0, eagleRotZ = 0;
break;
case 'h':
printf("\n\n*** Controls ***\n\nW: Accelerate\nS: Decelerate\nA: Turn left\nD: Turn right\n=: Increase elevation\n-: Decrease elevation\n0: Stop moving\nSpace: Pause animation\n\nF: Fullscreen\nP: Set viewpoint A\nU: Set viewpoint B\nY: Set viewpoint C\n\nH: Help\nR: Reset\nQ: Quit");
break;
case 'f':
if (fullscreen)
glutReshapeWindow(window_w, window_h);
fullscreen = false;
else
window_w = glutGet(GLUT_WINDOW_WIDTH);
window_h = glutGet(GLUT_WINDOW_HEIGHT);
glutFullScreen();
fullscreen = true;
forceReshape = true;
break;
void keyUp(unsigned char key, int x, int y)
switch (key)
case 'w': momentumDirection--; break;
case 'a': rotationDirection++; break;
case 's': momentumDirection++; break;
case 'd': rotationDirection--; break;
case '=': elevationDirection++; break;
case '-': elevationDirection--; break;
//Entry point.
int main(int argc, char **argv)
init(argc, argv);
glutDisplayFunc(display);
glutTimerFunc(1000 / 60, timer, 0);
glutSetKeyRepeat(0);
glutKeyboardFunc(keyDown);
glutKeyboardUpFunc(keyUp);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
【问题讨论】:
“我没有收到任何警告或运行时异常。”那是因为 OpenGL 不会警告你或抛出异常。相反,操作设置全局状态,您可以查询该状态以查看操作是否成功。您应该始终这样做,即使这会使您的代码不太清晰。The biggest change I've made is porting from SDL to GLUT, but I don't see how that would affect things.
您没有看到切换工具包和代码中所需的大量更改可能会“影响事物”吗?
【参考方案1】:
谢谢立方。
我添加了一个调试 sn-p 来帮助追踪问题:
if (DEBUG)
printf("%s\n", gluErrorString(glGetError()));
fflush(stdout);
使用二进制除法,我很快发现这一行出错了'invalid enumerant':
glEnable(GL_VERTEX_ARRAY);
这是因为它应该是:
glEnableClientState(GL_VERTEX_ARRAY);
我今天学到了宝贵的一课。
【讨论】:
如果这能解决您的问题,请随时接受您自己的答案!这样人们就知道如果遇到同样的问题,这就是他们正在寻找的答案。 +1:就这样,世界又多了一位高效且有用的软件开发人员。 :)以上是关于为啥我的 OpenGL 纹理不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
使用 GLFW3 在 OpenGL 上下文之间共享纹理不起作用