过剩无法绘制 2D 图像

glut cannot plot a 2D image

本文关键字:2D 图像 绘制      更新时间:2023-10-16

我正在努力加载src/up.bmp并以 2D 形式显示在我的 3D 环境中。但什么都没有出现。我的错误在哪里?

#define SDL_MAIN_HANDLED
#include <math.h>
#include <SDL.h>
#include <iostream>
#include <GL/freeglut.h>
using namespace std;
int w_width = 800;
int w_height = 500;
string w_title = "Model viewer";
float line_width = 2.0f;
float camera_radius = 100.0f;
float axis_size = 20.0;
SDL_Surface* button1;
GLuint TextureID;

void draw_button(SDL_Surface* button)
{
    glGenTextures(1, &TextureID);
    glBindTexture(GL_TEXTURE_2D, TextureID);
    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);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, button->w, button->h, GL_RGB, GL_UNSIGNED_BYTE, button->pixels);
}
void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    const float ratio = (float)glutGet(GLUT_SCREEN_WIDTH) / (float)glutGet(GLUT_SCREEN_HEIGHT);
    static double t = 0.0;
    const float deg2rad = 3.1415926f / 180.0f;
    float cam_x = camera_radius*float(cos(20.0f*deg2rad))*float(cos(0.5235*deg2rad));
    float cam_y = camera_radius*float(sin(20.f*deg2rad))*float(cos(0.5235*deg2rad));
    float cam_z = camera_radius*float(sin(0.5235*deg2rad));
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90, ratio, 0.01, 10000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(cam_x, cam_y, cam_z, 0, 0, 0, 0, 0, 1);
    // sphere
    glPushMatrix();
    glColor3ub(255, 0, 0);
    glTranslated(
        0,
        0,
        0);
    glutSolidSphere(1, 20, 20);
    glPopMatrix();
    draw_button(button1);
    glFlush();
    glutSwapBuffers();
}
void timer_event(int value)
{
    glutPostRedisplay();
    glutTimerFunc(100, timer_event, value);
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutSetOption(GLUT_MULTISAMPLE, 8);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE);
    glutTimerFunc(30, timer_event, 1);
    glutInitWindowSize(w_width, w_height);
    glutInitWindowPosition(10, 10);
    glutCreateWindow(argv[0]);
    glutSetWindowTitle(w_title.c_str());
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

    glutDisplayFunc(display);
    glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
        GLUT_ACTION_GLUTMAINLOOP_RETURNS);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_TEXTURE_2D);
    button1 = SDL_LoadBMP("src/up.bmp");
    if (button1 == NULL)
    {
        cout << "Image not found" << endl;
        exit(1);
    }
    glutMainLoop();
    SDL_FreeSurface(button1);
    return 0;
}

这是我能想出的一个最小的例子:

#define SDL_MAIN_HANDLED
#include <math.h>
#include <SDL.h>
#include <iostream>
#include <GL/gl.h>
#include <GL/freeglut.h>
using namespace std;
int w_width = 800;
int w_height = 500;
string w_title = "Model viewer";
float line_width = 2.0f;
float camera_radius = 100.0f;
float axis_size = 20.0;
SDL_Surface* button1;
GLuint TextureID;

static void prepare_texture(SDL_Surface *button)
{
    glGenTextures(1, &TextureID);
    glBindTexture(GL_TEXTURE_2D, TextureID);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // convert surface to RGB8
    SDL_Surface *rgb = SDL_CreateRGBSurface(0, button->w, button->h, 24, 0xff, 0xff00, 0xff0000, 0);
    SDL_BlitSurface(button, NULL, rgb, NULL);
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, button->w, button->h, GL_RGB, GL_UNSIGNED_BYTE, rgb->pixels);
    SDL_FreeSurface(rgb);
}
static void draw_button()
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    glBindTexture(GL_TEXTURE_2D, TextureID);
    glBegin(GL_QUADS);
        glTexCoord2f(0.0f, 1.0f);
        glVertex2f(0.1f, 0.1f);
        glTexCoord2f(0.0f, 0.0f);
        glVertex2f(0.1f, 0.2f);
        glTexCoord2f(1.0f, 0.0f);
        glVertex2f(0.2f, 0.2f);
        glTexCoord2f(1.0f, 1.0f);
        glVertex2f(0.2f, 0.1f);
    glEnd();
}
void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    const float ratio = (float)glutGet(GLUT_SCREEN_WIDTH) / (float)glutGet(GLUT_SCREEN_HEIGHT);
    static double t = 0.0;
    const float deg2rad = 3.1415926f / 180.0f;
    float cam_x = camera_radius*float(cos(20.0f*deg2rad))*float(cos(0.5235*deg2rad));
    float cam_y = camera_radius*float(sin(20.f*deg2rad))*float(cos(0.5235*deg2rad));
    float cam_z = camera_radius*float(sin(0.5235*deg2rad));
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90, ratio, 0.01, 10000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(cam_x, cam_y, cam_z, 0, 0, 0, 0, 0, 1);
    // sphere
    glPushMatrix();
    glColor3ub(255, 0, 0);
    glTranslated(
            0,
            0,
            0);
    glutSolidSphere(1, 20, 20);
    glPopMatrix();
    draw_button();
    glFlush();
    glutSwapBuffers();
}
void timer_event(int value)
{
    glutPostRedisplay();
    glutTimerFunc(100, timer_event, value);
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutSetOption(GLUT_MULTISAMPLE, 8);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE);
    glutTimerFunc(30, timer_event, 1);
    glutInitWindowSize(w_width, w_height);
    glutInitWindowPosition(10, 10);
    glutCreateWindow(argv[0]);
    glutSetWindowTitle(w_title.c_str());
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

    glutDisplayFunc(display);
    glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
            GLUT_ACTION_GLUTMAINLOOP_RETURNS);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_TEXTURE_2D);
    button1 = SDL_LoadBMP("up.bmp");
    if (button1 == NULL)
    {
        cout << "Image not found" << endl;
        exit(1);
    }
    prepare_texture(button1);
    SDL_FreeSurface(button1);
    glutMainLoop();
    return 0;
}

请注意身份投影,它将屏幕映射到 [-1,1] 范围;您可能需要更像 gluOrtho2D 的东西。