zoukankan      html  css  js  c++  java
  • SDL OPENGL 在linux ubuntu示例

    gl画纹理texture


    /*
    * SDL OpenGL Tutorial.
    * (c) Michael Vance, 2000
    * briareos@lokigames.com
    *
    * Distributed under terms of the LGPL.
    */

    #include <SDL/SDL.h>
    #include <GL/gl.h>
    #include <GL/glu.h>

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

    /*******************************************************************
    * *
    * Using SDL With OpenGL *
    * *
    * Tutorial by Kyle Foley (sdw) *
    * *
    * http://gpwiki.org/index.php/SDL:Tutorials:Using_SDL_with_OpenGL *
    * *
    *******************************************************************/

    #include <stdio.h>

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

    // Slightly different SDL initialization
    if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
    printf("Unable to initialize SDL: %s ", SDL_GetError());
    return 1;
    }

    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*

    screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL | SDL_FULLSCREEN ); // *changed*
    if ( !screen ) {
    printf("Unable to set video mode: %s ", SDL_GetError());
    return 1;
    }

    // Set the OpenGL state after creating the context with SDL_SetVideoMode

    glClearColor( 0, 0, 0, 0 );

    glEnable( GL_TEXTURE_2D ); // Need this to display a texture

    glViewport( 0, 0, 640, 480 );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    glOrtho( 0, 640, 480, 0, -1, 1 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    // Load the OpenGL texture

    GLuint texture; // Texture object handle
    SDL_Surface *surface; // Gives us the information to make the texture

    if ( (surface = SDL_LoadBMP("image.bmp")) ) {

    // Check that the image's width is a power of 2
    if ( (surface->w & (surface->w - 1)) != 0 ) {
    printf("warning: image.bmp's width is not a power of 2 ");
    }

    // Also check if the height is a power of 2
    if ( (surface->h & (surface->h - 1)) != 0 ) {
    printf("warning: image.bmp's height is not a power of 2 ");
    }

    // 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, 3, surface->w, surface->h, 0,
    GL_BGR, GL_UNSIGNED_BYTE, surface->pixels );
    }
    else {
    printf("SDL could not load image.bmp: %s ", SDL_GetError());
    SDL_Quit();
    return 1;
    }

    // Free the SDL_Surface only if it was successfully created
    if ( surface ) {
    SDL_FreeSurface( surface );
    }

    // Clear the screen before drawing
    glClear( GL_COLOR_BUFFER_BIT );

    // Bind the texture to which subsequent calls refer to
    glBindTexture( GL_TEXTURE_2D, texture );

    glBegin( GL_QUADS );
    // Top-left vertex (corner)
    glTexCoord2i( 0, 0 );
    glVertex3f( 100, 100, 0 );

    // Bottom-left vertex (corner)
    glTexCoord2i( 1, 0 );
    glVertex3f( 228, 100, 0 );

    // Bottom-right vertex (corner)
    glTexCoord2i( 1, 1 );
    glVertex3f( 228, 228, 0 );

    // Top-right vertex (corner)
    glTexCoord2i( 0, 1 );
    glVertex3f( 100, 228, 0 );
    glEnd();

    SDL_GL_SwapBuffers();

    // Wait for 3 seconds to give us a chance to see the image
    SDL_Delay(30000);

    // Now we can delete the OpenGL texture and close down SDL
    glDeleteTextures( 1, &texture );

    SDL_Quit();

    return 0;
    }



    旋转球
    http://www.libsdl.org/docs/html/guidevideoopengl.html
    /* * SDL OpenGL Tutorial. * (c) Michael Vance, 2000 * briareos@lokigames.com * * Distributed under terms of the LGPL. */ #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <stdio.h> #include <stdlib.h> static GLboolean should_rotate = GL_TRUE; static void quit_tutorial( int code ) { /* * Quit SDL so we can release the fullscreen * mode and restore the previous video settings, * etc. */ SDL_Quit( ); /* Exit program. */ exit( code ); } static void handle_key_down( SDL_keysym* keysym ) { /* * We're only interested if 'Esc' has * been presssed. * * EXERCISE: * Handle the arrow keys and have that change the * viewing position/angle. */ switch( keysym->sym ) { case SDLK_ESCAPE: quit_tutorial( 0 ); break; case SDLK_SPACE: should_rotate = !should_rotate; break; default: break; } } static void process_events( void ) { /* Our SDL event placeholder. */ SDL_Event event; /* Grab all the events off the queue. */ while( SDL_PollEvent( &event ) ) { switch( event.type ) { case SDL_KEYDOWN: /* Handle key presses. */ handle_key_down( &event.key.keysym ); break; case SDL_QUIT: /* Handle quit requests (like Ctrl-c). */ quit_tutorial( 0 ); break; } } } static void draw_screen( void ) { /* Our angle of rotation. */ static float angle = 0.0f; /* * EXERCISE: * Replace this awful mess with vertex * arrays and a call to glDrawElements. * * EXERCISE: * After completing the above, change * it to use compiled vertex arrays. * * EXERCISE: * Verify my windings are correct here ;). */ static GLfloat v0[] = { -1.0f, -1.0f, 1.0f }; static GLfloat v1[] = { 1.0f, -1.0f, 1.0f }; static GLfloat v2[] = { 1.0f, 1.0f, 1.0f }; static GLfloat v3[] = { -1.0f, 1.0f, 1.0f }; static GLfloat v4[] = { -1.0f, -1.0f, -1.0f }; static GLfloat v5[] = { 1.0f, -1.0f, -1.0f }; static GLfloat v6[] = { 1.0f, 1.0f, -1.0f }; static GLfloat v7[] = { -1.0f, 1.0f, -1.0f }; static GLubyte red[] = { 255, 0, 0, 255 }; static GLubyte green[] = { 0, 255, 0, 255 }; static GLubyte blue[] = { 0, 0, 255, 255 }; static GLubyte white[] = { 255, 255, 255, 255 }; static GLubyte yellow[] = { 0, 255, 255, 255 }; static GLubyte black[] = { 0, 0, 0, 255 }; static GLubyte orange[] = { 255, 255, 0, 255 }; static GLubyte purple[] = { 255, 0, 255, 0 }; /* Clear the color and depth buffers. */ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); /* We don't want to modify the projection matrix. */ glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); /* Move down the z-axis. */ glTranslatef( 0.0, 0.0, -5.0 ); /* Rotate. */ glRotatef( angle, 0.0, 1.0, 0.0 ); if( should_rotate ) { if( ++angle > 360.0f ) { angle = 0.0f; } } /* Send our triangle data to the pipeline. */ glBegin( GL_TRIANGLES ); glColor4ubv( red ); glVertex3fv( v0 ); glColor4ubv( green ); glVertex3fv( v1 ); glColor4ubv( blue ); glVertex3fv( v2 ); glColor4ubv( red ); glVertex3fv( v0 ); glColor4ubv( blue ); glVertex3fv( v2 ); glColor4ubv( white ); glVertex3fv( v3 ); glColor4ubv( green ); glVertex3fv( v1 ); glColor4ubv( black ); glVertex3fv( v5 ); glColor4ubv( orange ); glVertex3fv( v6 ); glColor4ubv( green ); glVertex3fv( v1 ); glColor4ubv( orange ); glVertex3fv( v6 ); glColor4ubv( blue ); glVertex3fv( v2 ); glColor4ubv( black ); glVertex3fv( v5 ); glColor4ubv( yellow ); glVertex3fv( v4 ); glColor4ubv( purple ); glVertex3fv( v7 ); glColor4ubv( black ); glVertex3fv( v5 ); glColor4ubv( purple ); glVertex3fv( v7 ); glColor4ubv( orange ); glVertex3fv( v6 ); glColor4ubv( yellow ); glVertex3fv( v4 ); glColor4ubv( red ); glVertex3fv( v0 ); glColor4ubv( white ); glVertex3fv( v3 ); glColor4ubv( yellow ); glVertex3fv( v4 ); glColor4ubv( white ); glVertex3fv( v3 ); glColor4ubv( purple ); glVertex3fv( v7 ); glColor4ubv( white ); glVertex3fv( v3 ); glColor4ubv( blue ); glVertex3fv( v2 ); glColor4ubv( orange ); glVertex3fv( v6 ); glColor4ubv( white ); glVertex3fv( v3 ); glColor4ubv( orange ); glVertex3fv( v6 ); glColor4ubv( purple ); glVertex3fv( v7 ); glColor4ubv( green ); glVertex3fv( v1 ); glColor4ubv( red ); glVertex3fv( v0 ); glColor4ubv( yellow ); glVertex3fv( v4 ); glColor4ubv( green ); glVertex3fv( v1 ); glColor4ubv( yellow ); glVertex3fv( v4 ); glColor4ubv( black ); glVertex3fv( v5 ); glEnd( ); /* * EXERCISE: * Draw text telling the user that 'Spc' * pauses the rotation and 'Esc' quits. * Do it using vetors and textured quads. */ /* * Swap the buffers. This this tells the driver to * render the next frame from the contents of the * back-buffer, and to set all rendering operations * to occur on what was the front-buffer. * * Double buffering prevents nasty visual tearing * from the application drawing on areas of the * screen that are being updated at the same time. */ SDL_GL_SwapBuffers( ); } static void setup_opengl( int width, int height ) { float ratio = (float) width / (float) height; /* Our shading model--Gouraud (smooth). */ glShadeModel( GL_SMOOTH ); /* Culling. */ glCullFace( GL_BACK ); glFrontFace( GL_CCW ); glEnable( GL_CULL_FACE ); /* Set the clear color. */ glClearColor( 0, 0, 0, 0 ); /* Setup our viewport. */ glViewport( 0, 0, width, height ); /* * Change to the projection matrix and set * our viewing volume. */ glMatrixMode( GL_PROJECTION ); glLoadIdentity( ); /* * EXERCISE: * Replace this with a call to glFrustum. */ gluPerspective( 60.0, ratio, 1.0, 1024.0 ); } int main( int argc, char* argv[] ) { /* Information about the current video settings. */ const SDL_VideoInfo* info = NULL; /* Dimensions of our window. */ int width = 0; int height = 0; /* Color depth in bits of our window. */ int bpp = 0; /* Flags we will pass into SDL_SetVideoMode. */ int flags = 0; /* First, initialize SDL's video subsystem. */ if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { /* Failed, exit. */ fprintf( stderr, "Video initialization failed: %s ", SDL_GetError( ) ); quit_tutorial( 1 ); } /* Let's get some video information. */ info = SDL_GetVideoInfo( ); if( !info ) { /* This should probably never happen. */ fprintf( stderr, "Video query failed: %s ", SDL_GetError( ) ); quit_tutorial( 1 ); } /* * Set our width/height to 640/480 (you would * of course let the user decide this in a normal * app). We get the bpp we will request from * the display. On X11, VidMode can't change * resolution, so this is probably being overly * safe. Under Win32, ChangeDisplaySettings * can change the bpp. */ width = 640; height = 480; bpp = info->vfmt->BitsPerPixel; /* * Now, we want to setup our requested * window attributes for our OpenGL window. * We want *at least* 5 bits of red, green * and blue. We also want at least a 16-bit * depth buffer. * * The last thing we do is request a double * buffered window. '1' turns on double * buffering, '0' turns it off. * * Note that we do not use SDL_DOUBLEBUF in * the flags to SDL_SetVideoMode. That does * not affect the GL attribute state, only * the standard 2D blitting setup. */ SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); /* * We want to request that SDL provide us * with an OpenGL window, in a fullscreen * video mode. * * EXERCISE: * Make starting windowed an option, and * handle the resize events properly with * glViewport. */ flags = SDL_OPENGL | SDL_FULLSCREEN; /* * Set the video mode */ if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) { /* * This could happen for a variety of reasons, * including DISPLAY not being set, the specified * resolution not being available, etc. */ fprintf( stderr, "Video mode set failed: %s ", SDL_GetError( ) ); quit_tutorial( 1 ); } /* * At this point, we should have a properly setup * double-buffered window for use with OpenGL. */ setup_opengl( width, height ); /* * Now we want to begin our normal app process-- * an event loop with a lot of redrawing. */ while( 1 ) { /* Process incoming events. */ process_events( ); /* Draw the screen. */ draw_screen( ); } /* * EXERCISE: * Record timings using SDL_GetTicks() and * and print out frames per second at program * end. */ /* Never reached. */ return 0; }

    显示黑屏的例子:

    #include <stdio.h>
    #include <stdlib.h>
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <SDL/SDL.h>

    /* 屏幕宽,高和颜色位数 */
    #define SCREEN_WIDTH 640
    #define SCREEN_HEIGHT 480
    #define SCREEN_BPP 16

    /* 设置布尔值 */
    #define TRUE 1
    #define FALSE 0

    /* SDL表面 */
    SDL_Surface *surface;

    /* 用来释放/销毁程序资源,并返回桌面 */
    void Quit(int returnCode) {
    /* 清除窗口 */
    SDL_Quit();

    /* 退出 */
    exit(returnCode);
    }

    /* 窗口更改后重新设置视点(观察点) */
    int resizeWindow(int width, int height) {
    /* 高与宽的比例 */
    GLfloat ratio;

    /* 防止除零 */
    if (height == 0)
    height = 1;

    ratio = (GLfloat) width / (GLfloat) height;

    /* 设置视点 */
    glViewport(0, 0, (GLint) width, (GLint) height);

    /* 选择投影矩阵 */
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    /* 设置透视 */
    gluPerspective(45.0f, ratio, 0.1f, 100.0f);

    /* 选择模型观察矩阵 */
    glMatrixMode(GL_MODELVIEW);

    /* 重置模型观察矩阵 */
    glLoadIdentity();

    return (TRUE);
    }

    /* 获得键盘按键事件 */
    void handleKeyPress(SDL_keysym *keysym) {
    switch (keysym->sym) {
    case SDLK_ESCAPE:
    /* ESC按下时 */
    Quit(0);
    break;
    case SDLK_F1:
    /* F1按下时
    * 触发全屏模式
    */
    SDL_WM_ToggleFullScreen(surface);
    break;
    default:
    break;
    }

    return;
    }

    /* OpenGL初始化函数 */
    int initGL(void) {

    /* 启用阴影平滑 */
    glShadeModel(GL_SMOOTH);

    /* 设置黑色背景 */
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    /* 设置深度缓存 */
    glClearDepth(1.0f);

    /* 启用深度测试 */
    glEnable(GL_DEPTH_TEST);

    /* 所作深度测试类型 */
    glDepthFunc(GL_LEQUAL);

    /* 告知系统对透视进行修正 */
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    return (TRUE);
    }

    /* 绘制代码 */
    int drawGLScene(void) {
    /* 计算fps */
    static GLint T0 = 0;
    static GLint Frames = 0;

    /* 清除屏幕及深度缓冲 */
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    /* 绘制屏幕 */
    SDL_GL_SwapBuffers();

    /* 自增长桢的计算 */
    Frames++;
    {
    GLint t = SDL_GetTicks();
    if (t - T0 >= 5000) {
    GLfloat seconds = (t - T0) / 1000.0;
    GLfloat fps = Frames / seconds;
    printf("%d frames in %g seconds = %g FPS ", Frames, seconds, fps);
    T0 = t;
    Frames = 0;
    }
    }

    return (TRUE);
    }

    /* 程序主函数 */
    int main(int argc, char **argv) {
    /* 通过SDL_SetVideoMode标志 */
    int videoFlags;
    /* 主循环变量 */
    int done = FALSE;
    /* SDL事件 */
    SDL_Event event;
    /* 显示一些信息在屏幕 */
    const SDL_VideoInfo *videoInfo;
    /* 窗口激活标志 */
    int isActive = TRUE;

    /* 初始化 SDL */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
    fprintf(stderr, "Video initialization failed: %s ", SDL_GetError());
    Quit(1);
    }

    /* 获得视频信息 */
    videoInfo = SDL_GetVideoInfo();

    if (!videoInfo) {
    fprintf(stderr, "Video query failed: %s ", SDL_GetError());
    Quit(1);
    }

    /* 通过SDL_SetVideoMode标志 */
    videoFlags = SDL_OPENGL; /* 在SDL中启用OpenGL */
    videoFlags |= SDL_GL_DOUBLEBUFFER; /* 启用双缓冲 */
    videoFlags |= SDL_HWPALETTE; /* 硬件保存调色板 */
    videoFlags |= SDL_RESIZABLE; /* 窗口可更改 */

    /* 检测表面是否可以保存入内存 */
    if (videoInfo->hw_available){
    printf("===support. ");
    videoFlags |= SDL_HWSURFACE;
    }else{
    printf("===not support. ");
    videoFlags |= SDL_SWSURFACE;
    }

    /* 测试硬件翻转 */
    if (videoInfo->blit_hw)
    videoFlags |= SDL_HWACCEL;

    /* 设置OpenGL双缓冲 */
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    /* 获得SDL表面 */
    surface = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, videoFlags);

    /* 验证表面 */
    if (!surface) {
    fprintf(stderr, "Video mode set failed: %s ", SDL_GetError());
    Quit(1);
    }

    /* 初始化 OpenGL */
    if (initGL() == FALSE) {
    fprintf(stderr, "Could not initialize OpenGL. ");
    Quit(1);
    }

    /* 初始化窗口 */
    resizeWindow(SCREEN_WIDTH, SCREEN_HEIGHT);

    /* 等待事件 */
    while (!done) {
    /* 获得事件队列 */

    while (SDL_PollEvent(&event)) {
    switch (event.type) {
    case SDL_ACTIVEEVENT:
    /* 不在焦点时候或最小化,不需要绘制
    */
    if (event.active.gain == 0)
    isActive = FALSE;
    else
    isActive = TRUE;
    break;
    case SDL_VIDEORESIZE:
    /* 获得改变窗口事件 */
    surface = SDL_SetVideoMode(event.resize.w, event.resize.h, 16, videoFlags);
    if (!surface) {
    fprintf(stderr, "Could not get a surface after resize: %s ", SDL_GetError());
    Quit(1);
    }
    resizeWindow(event.resize.w, event.resize.h);
    break;
    case SDL_KEYDOWN:
    /* 获得键盘按下 */
    handleKeyPress(&event.key.keysym);
    break;
    case SDL_QUIT:
    /* 获得退出请求 */
    done = TRUE;
    break;
    default:
    break;
    }
    }

    /* 绘制场景 */
    if (isActive)
    drawGLScene();
    }

    /* 清除本身并退出 */
    Quit(0);

    /* 不可能执行这里了 */
    return (0);
    }

  • 相关阅读:
    记录一下最近面试的总结
    网络模块相关面试题
    JVM 之类加载器
    一段简单的关于字符串的 Java 代码竟考察了这么多东西
    LeetCode 链表题 ( Java )
    MD5 加盐加密
    SpringMVC 学习笔记
    [redis]dict和rehash
    [redis]SDS和链表
    [go]包和工程管理
  • 原文地址:https://www.cnblogs.com/bigben0123/p/3243166.html
Copyright © 2011-2022 走看看