如何在opengl中正确构造四边形

时间:2014-12-16 20:20:46

标签: c opengl

我是OpenGL的新手,在熟悉基本形状的渲染后,我决定学习如何添加纹理,快速谷歌搜索给了我SOIL库。我决定通过将一个纹理应用到填充窗口的四边形来开始简单。这是我的代码:

#include <stdlib.h>
#include <stdio.h>

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <SOIL/SOIL.h>

#define WIDTH 0x320
#define HEIGHT 0x258
#define INIT_X 0
#define INIT_Y 0

GLuint texture;

GLuint glInitTexture(char* filename)
{
    FILE* f = NULL;
    f = fopen(filename, "r");
        if(f == NULL)
        {
            fprintf(stderr, "cannot load file %s!", filename);
            exit(1);
        }
    GLuint t = SOIL_load_OGL_texture(filename, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS);

    glBindTexture(GL_TEXTURE_2D, t);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    return t;
}

void init()
{
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);

    texture = glInitTexture("image.png");
}

void drawImage(GLuint file,
    float x,
    float y,
    float w,
    float h,
    float angle)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glPushMatrix();
    glTranslatef(x, y, 0.0);
    glRotatef(angle, 0.0, 0.0, 1.0);

    glBindTexture(GL_TEXTURE_2D, file);

    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex3f(x, y, 0.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(x, y + h, 0.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(x + w, y + h, 0.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(x + w, y, 0.0f);
    glEnd();

    glFlush();
    glPopMatrix();
}

void reshape(int w, int h)//courtesy of http://www.lighthouse3d.com/tutorials/glut-tutorial/preparing-the-window-for-a-reshape/
{
    if(h == 0) h = 1;
    float ratio = w * 1.0 / h;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, w, h);
    gluPerspective(45.0, ratio, 0.1, 1000.0);
    glMatrixMode(GL_MODELVIEW);
}

void render()
{
    glLoadIdentity();
    drawImage(texture, 0.0f, 0.0f, 4.0f, 4.0f, 0.0);
    glutSwapBuffers();
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(WIDTH, HEIGHT);
    glutInitWindowPosition(INIT_X, INIT_Y);
    glutCreateWindow("Applying Textures");

    glutDisplayFunc(render);
    glutIdleFunc(render);
    glutReshapeFunc(reshape);
    glutIgnoreKeyRepeat(1);

    init();
    glutMainLoop();

    return 0;
}

然而,当我加载编译并运行程序时,我唯一得到的是一个带有白色背景的窗口。我还应该注意文件&#34; image.png&#34;确实存在并填充红色以与白色背景形成对比以用于测试目的。我想知道我做错了什么和/或我错过了什么。

1 个答案:

答案 0 :(得分:1)

身份模型视图矩阵导致原点朝向-Z轴的“相机”。

你的drawImage()正在向下与一个与Z = 0平面共面的四边形。这是后面的身份矩阵的近剪裁平面。

将相机向后滑动一点,这样就不会嵌入Z = 0平面:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef( 0, 0, -15 );  // this is where the magic happens

所有在一起:

#include <GL/glut.h>

GLuint glInitTexture(char* filename)
{
    GLuint t = 0;

    glGenTextures( 1, &t );
    glBindTexture(GL_TEXTURE_2D, t);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    unsigned char data[] = { 255, 0, 0, 255 };
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
    return t;
}

void drawImage(GLuint file,
    float x,
    float y,
    float w,
    float h,
    float angle)
{
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glPushMatrix();
    glTranslatef(x, y, 0.0);
    glRotatef(angle, 0.0, 0.0, 1.0);

    glBindTexture(GL_TEXTURE_2D, file);
    glEnable(GL_TEXTURE_2D);

    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex3f(x, y, 0.0f);
    glTexCoord2f(0.0, 2.0); glVertex3f(x, y + h, 0.0f);
    glTexCoord2f(2.0, 2.0); glVertex3f(x + w, y + h, 0.0f);
    glTexCoord2f(2.0, 0.0); glVertex3f(x + w, y, 0.0f);
    glEnd();

    glPopMatrix();
}

GLuint texture;
void render()
{
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_DEPTH_TEST);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    const double w = glutGet( GLUT_WINDOW_WIDTH );
    const double h = glutGet( GLUT_WINDOW_HEIGHT );
    gluPerspective(45.0, w / h, 0.1, 1000.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef( 0, 0, -15 );

    drawImage(texture, 0.0f, 0.0f, 4.0f, 4.0f, 0.0);

    glutSwapBuffers();
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(600, 600);
    glutCreateWindow("Applying Textures");
    glutDisplayFunc(render);

    texture = glInitTexture("image.png");

    glutMainLoop();
    return 0;
}