SDL OPENGL 在linux ubuntu示例

时间:2023-03-09 17:09:53
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\n", 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\n", 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\n");
}

// 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\n");
}

// 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\n", 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\n",
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\n",
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\n",
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\n", 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\n", SDL_GetError());
Quit(1);
}

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

if (!videoInfo) {
fprintf(stderr, "Video query failed: %s\n", 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.\n");
videoFlags |= SDL_HWSURFACE;
}else{
printf("===not support.\n");
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\n", SDL_GetError());
Quit(1);
}

/* 初始化 OpenGL */
if (initGL() == FALSE) {
fprintf(stderr, "Could not initialize OpenGL.\n");
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\n", 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);
}