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

发布于 2024-10-20 17:47:27 字数 5696 浏览 1 评论 0原文

这是我的代码。我正在尝试绘制一个简单的四边形,并在其两侧放置一个棋盘图案。我想允许用户用鼠标围绕这块旋转。一切都工作正常,除了纹理 - 它是倾斜的,并且只覆盖了四边形的大约一半。有人能看出我做错了什么明显的事情吗?谢谢。

#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;
}

半覆盖,扭曲

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) : (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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沙沙粒小 2024-10-27 17:47:27

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文