c++:我如何使用 sdl 将位图加载到 opengl 中的多维数据集中?

发布于 2024-08-27 19:08:38 字数 7823 浏览 8 评论 0原文

我正在学习 OpenGL 和 SDL,到目前为止,我已经能够正确绘制和旋转 3d 多边形(对我来说是的!:))

如何使用 SDL 加载图像文件并将该纹理加载到我绘制的 3d 形状上使用 OpenGL 在屏幕上显示。

谢谢!!!

更新

我尝试使用以下代码绘制一个立方体,旋转它并添加位图,但我看不到位图可见。有什么想法吗?

#ifdef WIN32

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#endif
#if defined(__APPLE__) && defined(__MACH__)
#include <OpenGL/gl.h>  // Header File For The OpenGL32 Library    
#include <OpenGL/glu.h> // Header File For The GLu32 Library
#else
#include <GL/gl.h>  // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
#endif
#include "SDL.h"
#include <stdio.h>
#include <unistd.h>

SDL_Surface *screen=NULL;

GLfloat     rtri;                       // Angle For The Triangle ( NEW )
GLfloat     rquad;                      // Angle For The Quad     ( NEW )

GLuint texture;         // This is a handle to our texture object
SDL_Surface *surface;   // This surface will tell us the details of the image
GLenum texture_format;
GLint  nOfColors;


bool InitGL(int Width, int Height)          // We call this right after our OpenGL window is created.
{
glViewport(0, 0, Width, Height);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);       // This Will Clear The Background Color To Black
glClearDepth(1.0);              // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS);               // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST);            // Enables Depth Testing
glShadeModel(GL_SMOOTH);            // Enables Smooth Color Shading

glMatrixMode(GL_PROJECTION);
glLoadIdentity();               // Reset The Projection Matrix

gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);   // Calculate The Aspect Ratio Of The Window

glMatrixMode(GL_MODELVIEW);

if ( (surface = SDL_LoadBMP("icon.bmp")) ) { 
    
    // Check that the image's width is a power of 2
    if ( (surface->w & (surface->w - 1)) != 0 ) {
        printf("error: image.bmp's width is not a power of 2\n");
        return false;
    }
    
    // Also check if the height is a power of 2
    if ( (surface->h & (surface->h - 1)) != 0 ) {
        printf("error: image.bmp's height is not a power of 2\n");
        return false;
    }
    
    // get the number of channels in the SDL surface
    nOfColors = surface->format->BytesPerPixel;
    if (nOfColors == 4)     // contains an alpha channel
    {
        if (surface->format->Rmask == 0x000000ff)
            texture_format = GL_RGBA;
        else
            texture_format = GL_BGRA;
    } else if (nOfColors == 3)     // no alpha channel
    {
        if (surface->format->Rmask == 0x000000ff)
            texture_format = GL_RGB;
        else
            texture_format = GL_BGR;
    } else {
        printf("error: the image is not truecolor..  this will probably break\n");
        return false;
        // this error should not go unhandled
    }
    
    // Have OpenGL generate a texture object handle for us
    glGenTextures( 1, &texture );
    
    // Bind the texture object
    glBindTexture( GL_TEXTURE_2D, texture );
    
    // Set the texture's stretching properties
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    
    // Edit the texture object's image data using the information SDL_Surface gives us
    glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
                 texture_format, GL_UNSIGNED_BYTE, surface->pixels     );
} 
else {
    printf("SDL could not load image.bmp: %s\n", SDL_GetError());
    SDL_Quit();
    return false;
}    
return true;
}

/* The main drawing function. */
int DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     // Clear The Screen And The Depth Buffer
glLoadIdentity();               // Reset The View

glTranslatef(-1.5f,0.0f,-6.0f);     // Move Left 1.5 Units And Into The Screen 6.0
glRotatef(rtri,0.0f,1.0f,0.0f);             // Rotate The Triangle On The Y axis ( NEW )    

glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);  // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);  // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);  // Top Left Of The Texture and Quad
// Back Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);  // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);  // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);  // Bottom Left Of The Texture and Quad
// Top Face
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);  // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);  // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);  // Top Right Of The Texture and Quad
// Bottom Face
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);  // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);  // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);  // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);  // Bottom Right Of The Texture and Quad
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);  // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);  // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);  // Bottom Left Of The Texture and Quad
// Left Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);  // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);  // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);  // Top Left Of The Texture and Quad
glEnd();


rtri+=0.02f;                        // Increase The Rotation Variable For The Triangle ( NEW )
rquad-=0.015f;                      // Decrease The Rotation Variable For The Quad     ( NEW )


// swap buffers to display, since we're double buffered.
SDL_GL_SwapBuffers();
return true;
}


int main(int argc,char* argv[])
{


int done;
/*variable to hold the file name of the image to be loaded
 *In real world error handling code would precede this
 */

/* Initialize SDL for video output */
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
    exit(1);
}

atexit(SDL_Quit);

/* Create a 640x480 OpenGL screen */
if ( SDL_SetVideoMode(640, 480, 0, SDL_OPENGL) == NULL ) {
    fprintf(stderr, "Unable to create OpenGL screen: %s\n", SDL_GetError());
    SDL_Quit();
    exit(2);
}
SDL_WM_SetCaption("another example",NULL);  
InitGL(640,480);
done=0;
while (! done) {
    DrawGLScene();
    SDL_Event event;
    while ( SDL_PollEvent(&event) ) {
        if ( event.type == SDL_QUIT ) {
            done = 1;
        }
        if ( event.type == SDL_KEYDOWN ) {
            if ( event.key.keysym.sym == SDLK_ESCAPE ) {
                done = 1;
            }
        }
    }         
}
return 1;
}

I'm learning OpenGL and SDL and so far I've been able to properly draw and rotate 3d polygons ( yay for me! :) )

how can I load an image file using SDL and load that texture on the 3d shapes that i draw on screen using OpenGL.

thanks!!!

update

I tried the following code that draw a cube, rotates it and adds a bitmap, but I don't see the bitmap visible. any ideas ?

#ifdef WIN32

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#endif
#if defined(__APPLE__) && defined(__MACH__)
#include <OpenGL/gl.h>  // Header File For The OpenGL32 Library    
#include <OpenGL/glu.h> // Header File For The GLu32 Library
#else
#include <GL/gl.h>  // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
#endif
#include "SDL.h"
#include <stdio.h>
#include <unistd.h>

SDL_Surface *screen=NULL;

GLfloat     rtri;                       // Angle For The Triangle ( NEW )
GLfloat     rquad;                      // Angle For The Quad     ( NEW )

GLuint texture;         // This is a handle to our texture object
SDL_Surface *surface;   // This surface will tell us the details of the image
GLenum texture_format;
GLint  nOfColors;


bool InitGL(int Width, int Height)          // We call this right after our OpenGL window is created.
{
glViewport(0, 0, Width, Height);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);       // This Will Clear The Background Color To Black
glClearDepth(1.0);              // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS);               // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST);            // Enables Depth Testing
glShadeModel(GL_SMOOTH);            // Enables Smooth Color Shading

glMatrixMode(GL_PROJECTION);
glLoadIdentity();               // Reset The Projection Matrix

gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);   // Calculate The Aspect Ratio Of The Window

glMatrixMode(GL_MODELVIEW);

if ( (surface = SDL_LoadBMP("icon.bmp")) ) { 
    
    // Check that the image's width is a power of 2
    if ( (surface->w & (surface->w - 1)) != 0 ) {
        printf("error: image.bmp's width is not a power of 2\n");
        return false;
    }
    
    // Also check if the height is a power of 2
    if ( (surface->h & (surface->h - 1)) != 0 ) {
        printf("error: image.bmp's height is not a power of 2\n");
        return false;
    }
    
    // get the number of channels in the SDL surface
    nOfColors = surface->format->BytesPerPixel;
    if (nOfColors == 4)     // contains an alpha channel
    {
        if (surface->format->Rmask == 0x000000ff)
            texture_format = GL_RGBA;
        else
            texture_format = GL_BGRA;
    } else if (nOfColors == 3)     // no alpha channel
    {
        if (surface->format->Rmask == 0x000000ff)
            texture_format = GL_RGB;
        else
            texture_format = GL_BGR;
    } else {
        printf("error: the image is not truecolor..  this will probably break\n");
        return false;
        // this error should not go unhandled
    }
    
    // Have OpenGL generate a texture object handle for us
    glGenTextures( 1, &texture );
    
    // Bind the texture object
    glBindTexture( GL_TEXTURE_2D, texture );
    
    // Set the texture's stretching properties
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    
    // Edit the texture object's image data using the information SDL_Surface gives us
    glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
                 texture_format, GL_UNSIGNED_BYTE, surface->pixels     );
} 
else {
    printf("SDL could not load image.bmp: %s\n", SDL_GetError());
    SDL_Quit();
    return false;
}    
return true;
}

/* The main drawing function. */
int DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     // Clear The Screen And The Depth Buffer
glLoadIdentity();               // Reset The View

glTranslatef(-1.5f,0.0f,-6.0f);     // Move Left 1.5 Units And Into The Screen 6.0
glRotatef(rtri,0.0f,1.0f,0.0f);             // Rotate The Triangle On The Y axis ( NEW )    

glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);  // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);  // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);  // Top Left Of The Texture and Quad
// Back Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);  // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);  // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);  // Bottom Left Of The Texture and Quad
// Top Face
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);  // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);  // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);  // Top Right Of The Texture and Quad
// Bottom Face
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);  // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);  // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);  // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);  // Bottom Right Of The Texture and Quad
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);  // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);  // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);  // Bottom Left Of The Texture and Quad
// Left Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);  // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);  // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);  // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);  // Top Left Of The Texture and Quad
glEnd();


rtri+=0.02f;                        // Increase The Rotation Variable For The Triangle ( NEW )
rquad-=0.015f;                      // Decrease The Rotation Variable For The Quad     ( NEW )


// swap buffers to display, since we're double buffered.
SDL_GL_SwapBuffers();
return true;
}


int main(int argc,char* argv[])
{


int done;
/*variable to hold the file name of the image to be loaded
 *In real world error handling code would precede this
 */

/* Initialize SDL for video output */
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
    exit(1);
}

atexit(SDL_Quit);

/* Create a 640x480 OpenGL screen */
if ( SDL_SetVideoMode(640, 480, 0, SDL_OPENGL) == NULL ) {
    fprintf(stderr, "Unable to create OpenGL screen: %s\n", SDL_GetError());
    SDL_Quit();
    exit(2);
}
SDL_WM_SetCaption("another example",NULL);  
InitGL(640,480);
done=0;
while (! done) {
    DrawGLScene();
    SDL_Event event;
    while ( SDL_PollEvent(&event) ) {
        if ( event.type == SDL_QUIT ) {
            done = 1;
        }
        if ( event.type == SDL_KEYDOWN ) {
            if ( event.key.keysym.sym == SDLK_ESCAPE ) {
                done = 1;
            }
        }
    }         
}
return 1;
}

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

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

发布评论

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

评论(2

溺深海 2024-09-03 19:08:38

我使用 sdl 和 opengl,建议您使用 lib DevIl 来加载图像,

这是一个创建图像的函数与魔鬼的纹理:

ilInit();
iluInit();
GLuint  texture;


ILuint texid;
ilGenImages(1, &texid);
ilBindImage(texid);
ilLoadImage("tex.png");
iluFlipImage();
ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);

glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

gluBuild2DMipmaps(GL_TEXTURE_2D, 4, ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), ilGetInteger(IL_IMAGE_FORMAT),
                  GL_UNSIGNED_BYTE, ilGetData());


ilDeleteImage(texid);

:)

I use sdl and opengl and i recomend you to use the lib DevIl to load images

here a function to create a texture with devIl:

ilInit();
iluInit();
GLuint  texture;


ILuint texid;
ilGenImages(1, &texid);
ilBindImage(texid);
ilLoadImage("tex.png");
iluFlipImage();
ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);

glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

gluBuild2DMipmaps(GL_TEXTURE_2D, 4, ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), ilGetInteger(IL_IMAGE_FORMAT),
                  GL_UNSIGNED_BYTE, ilGetData());


ilDeleteImage(texid);

:)

眼藏柔 2024-09-03 19:08:38

我并不是真正的 SDL 人员,但这可能会对您有所帮助: http:// /gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL#How_To_Load_an_OpenGL_Texture_from_an_SDL_Surface

编辑:我编译了您的代码,这就是您缺少的内容:

  • glEnable( GL_TEXTURE_2D ); 放入你的 initGL 函数。 glShadeMode(GL_SMOOTH)

    之后

  • 确保你的位图是 24 位(我尝试了 8 位 BMP,它给出了需要它为“真彩色”的警告)

I'm not really an SDL person, but this might help you: http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL#How_To_Load_an_OpenGL_Texture_from_an_SDL_Surface

EDIT: I compiled your code and here's what you were missing:

  • Put glEnable( GL_TEXTURE_2D ); in your initGL function. I put it right after glShadeMode(GL_SMOOTH)

  • Make sure your bitmap is 24 bit (I tried an 8 bit BMP and it gave a warning about needing it to be "truecolor")

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