为什么我的openGL纹理只覆盖了我的四边形的一半?来源包括

时间:2011-03-07 02:14:10

标签: c opengl textures glut

这是我的代码。我试图绘制一个简单的四边形,并在它的两侧放置棋盘图案。我想让用户用鼠标围绕这件旋转。一切都很好,除了纹理 - 它是倾斜的,只覆盖四边形的一半。任何人都可以看到一些明显我做错的事吗?感谢。

#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) : (viewAngleX < - 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;
}

half-covered,distorted

1 个答案:

答案 0 :(得分:5)

你的代码对我来说很好;我怀疑问题出在你用于纹理的源图像中。仔细检查图像是否符合您的想象。例如,使用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