Here is my code. I'm attempting to draw a simple quadrilateral, and place a checkerboard pattern on both sides of it. I want to allow the user to rotate around this piece with the mouse. Everything works fine, other than the texture - it is slanted, and only covers about half of the quad. Can anyone see something glaringly obvious that I am doing wrong? Thanks.
#include "glut-3.7.6-bin\glut.h"
// Constants for rotating camera
#define CAMERA_RELEASE 0
#define CAMERA_ROTATE 1
#define CAMERA_ZOOM 2
// Current camera control setting
int cameraSetting;
// Current viewing angle and scale of the scene
float viewAngleX, viewAngleY, scaleFactor = 1.0;
// Click coordinates
int clickX, clickY;
// Screen size
const int screenWidth = 600;
const int screenHeight = 600;
// Texture data
GLuint texture;
////////////////////////////////////////////////////////////////
// Function Prototypes
////////////////////////////////////////////////////////////////
GLuint loadTexture(const char * filename);
////////////////////////////////////////////////////////////////
// Callback and Initialization Functions
////////////////////////////////////////////////////////////////
void callbackMouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
// Store clicked coordinates
clickX = x;
clickY = y;
// Set camera mode to rotate
if (button == GLUT_LEFT_BUTTON)
{
cameraSetting = CAMERA_ROTATE;
}
// Set camera mode to zoom
else if (button == GLUT_RIGHT_BUTTON)
{
cameraSetting = CAMERA_ZOOM;
}
}
// Ignore camera commands if no button is clicked
else if (state == GLUT_UP)
{
cameraSetting = CAMERA_RELEASE;
}
}
void callbackKeyboard(unsigned char key, int x, int y)
{
if (key == 'q') {
exit(0);
}
}
void callbackMotion(int x, int y)
{
if (cameraSetting == CAMERA_ROTATE)
{
// Camera rotate setting - adjust the viewing angle by the direction of motion
viewAngleX += (x - clickX) / 5.0;
viewAngleX = viewAngleX > 180 ? (viewAngleX - 360) : (viewAng开发者_如何转开发leX < - 180 ? (viewAngleX + 360) : viewAngleX);
clickX = x;
viewAngleY += (y - clickY) / 5.0;
viewAngleY = viewAngleY > 180 ? (viewAngleY - 360) : (viewAngleY < - 180 ? (viewAngleY + 360) : viewAngleY);
clickY = y;
}
else if (cameraSetting == CAMERA_ZOOM)
{
// Polygonal scale to simulate camera zoom
float currentScaleFactor = scaleFactor;
scaleFactor *= (1+ (y - clickY) / 60.0);
scaleFactor = scaleFactor < 0 ? currentScaleFactor : scaleFactor;
clickY = y;
}
glutPostRedisplay();
}
void callbackDisplay()
{
// Clear the screen
glEnable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// Set world window
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, 1, 100);
// Setup 3D environment
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,5,
0,0,0,
0,1,0);
// Rotate and scale 3D environment to current user settings
glRotatef(viewAngleX, 0, 1, 0);
glRotatef(viewAngleY, 1, 0, 0);
glScalef(scaleFactor, scaleFactor, scaleFactor);
glBegin(GL_QUADS);
glTexCoord2d(0.0, 0.0); glVertex3f(-30, -5, -30);
glTexCoord2d(1.0, 0.0); glVertex3f(30, -5, -30);
glTexCoord2d(1.0, 1.0); glVertex3f(30, -5, 30);
glTexCoord2d(0.0, 1.0); glVertex3f(-30, -5, 30);
glEnd();
// Swap frame buffers
glutSwapBuffers();
}
void windowInitialization() {
// Enable textures by default
glEnable(GL_TEXTURE_2D);
// Load texture
texture = loadTexture("checkerboard.raw");
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
////////////////////////////////////////////////////////////////
// Main
////////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
// GLUT Initialization
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(screenWidth,screenHeight);
// Create main window
glutCreateWindow("Test");
windowInitialization();
// Register callback functions
glutDisplayFunc(callbackDisplay);
glutMouseFunc(callbackMouse);
glutMotionFunc(callbackMotion);
glutKeyboardFunc(callbackKeyboard);
// Enter event processing loop
glutMainLoop();
}
////////////////////////////////////////////////////////////////
// Prototyped Functions
////////////////////////////////////////////////////////////////
GLuint loadTexture(const char * filename)
{
GLuint texture;
int width, height;
BYTE * data;
FILE * file;
// open texture data
file = fopen( filename, "rb" );
if ( file == NULL ) return 0;
// allocate buffer
width = 256;
height = 256;
data = (BYTE *) malloc( width * height * 3 );
// read texture data
fread( data, width * height * 3, 1, file );
fclose( file );
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// texture wraps over at the edges
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 1 );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 1);
// build texture
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,
GL_RGB, GL_UNSIGNED_BYTE, data );
// free buffer
free( data );
return texture;
}
Your code works fine for me; I suspect the problem is in the source image you're using for the texture. Double-check that the image is what you think it is. For example, using ImageMagick:
# Convert an image into raw RGB:
convert checkerboard.png checkerboard.rgb
# Convert raw RGB back to an image (assuming we know the size and color depth):
convert -size 256x256 -depth 8 checkerboard.rgb checkerboard.png
精彩评论