Skip to content

Instantly share code, notes, and snippets.

@arkenidar
Created May 30, 2022 12:25
Show Gist options
  • Save arkenidar/010d24281e2bd5792ae323b4f93e28c6 to your computer and use it in GitHub Desktop.
Save arkenidar/010d24281e2bd5792ae323b4f93e28c6 to your computer and use it in GitHub Desktop.
SDL2 with OpenGL for 3D (OpenGL with "windowing" requires SDL2 (or SDL1) or e.g. freeGLUT (GLUT implementation) )
// sdl2-gl.c (filename)
// SDL2 with OpenGL for 3D (OpenGL with "windowing" requires SDL2 (or SDL1) or e.g. freeGLUT (GLUT implementation) )
/* gcc sdl2-gl.c `sdl2-config --cflags --libs` -lopengl32 -lglu32 && ./a */
/*
https://www.libsdl.org/release/SDL-1.2.15/docs/html/guidevideoopengl.html ||
SDL_Delay( 30 ); // added ||
ported from SDL1 to SDL2
https://wiki.libsdl.org/MigrationGuide
OpenGL: If you were already using OpenGL directly, your migration is pretty simple. Change your SDL_SetVideoMode() call to SDL_CreateWindow() followed by SDL_GL_CreateContext(), and your SDL_GL_SwapBuffers() call to SDL_GL_SwapWindow(window). All the actual calls into the GL are exactly the same.
https://stackoverflow.com/questions/49585857/error-with-sdl-window
compiled with MSYS2/MinGW64 (provides pacman) ||
pacman -Fy sdl2-config ||
pacman -S --needed mingw-w64-x86_64-SDL2 # SDL2 : sdl2-config . not : (SDL1/SDL : sdl-config)
*/
/*
* SDL OpenGL Tutorial.
* (c) Michael Vance, 2000
* briareos@lokigames.com
*
* Distributed under terms of the LGPL.
*/
#include <SDL2/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
static GLboolean should_rotate = GL_TRUE;
SDL_Window* window;
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( ); // SDL1
// SDL2:
SDL_GL_SwapWindow(window);
/*
ported from SDL1 to SDL2
https://wiki.libsdl.org/MigrationGuide
OpenGL: If you were already using OpenGL directly, your migration is pretty simple. Change your SDL_SetVideoMode() call to SDL_CreateWindow() followed by SDL_GL_CreateContext(), and your SDL_GL_SwapBuffers() call to SDL_GL_SwapWindow(window). All the actual calls into the GL are exactly the same.
*/
}
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; // SDL1
/* Dimensions of our window. */
int width = 0;
int height = 0;
/* Color depth in bits of our window. */
///int bpp = 0; // SDL1
/* Flags we will pass into SDL_SetVideoMode. */
///int flags = 0; // SDL1
/* 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; // SDL1
/*
* 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 );
/*
ported from SDL1 to SDL2
https://wiki.libsdl.org/MigrationGuide
OpenGL: If you were already using OpenGL directly, your migration is pretty simple. Change your SDL_SetVideoMode() call to SDL_CreateWindow() followed by SDL_GL_CreateContext(), and your SDL_GL_SwapBuffers() call to SDL_GL_SwapWindow(window). All the actual calls into the GL are exactly the same.
*/
window = SDL_CreateWindow("Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
SDL_GL_CreateContext(window);
/*
* 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; // SDL1
/*
* 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( );
///////--------------------- MY ADD
SDL_Delay( 30 );
}
/*
* EXERCISE:
* Record timings using SDL_GetTicks() and
* and print out frames per second at program
* end.
*/
/* Never reached. */
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment