Flickering background color - opengl

I created an OpenGL window using SDL2 but the background keeps switching between black and yellow.
#include <SDL2/SDL.h>
#include <GL/glew.h>
#define SCREEN_WIDTH 500
#define SCREEN_HEIGHT 500
int main( int argc, char** argv )
{
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
SDL_Window* gWindow = SDL_CreateWindow(
"Title",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_OPENGL);
SDL_GL_CreateContext( gWindow );
glewExperimental = GL_TRUE;
glewInit();
glPointSize(3);
glClearColor(1,1,0,0);
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SetSwapInterval(1);
int quit=0;
SDL_Event event;
while( !quit )
{
while(SDL_PollEvent( &event ))
{
if( event.type == SDL_QUIT )
quit = 1;
}
SDL_GL_SwapWindow( gWindow );
}
SDL_DestroyWindow(gWindow);
return 0;
}
I expect the background to be yellow, as defined with glClearColor(1,1,0,0), without flickering while the program runs. Is there something wrong in the code?

The reason for flickering is that you're using double buffering but do not clear one of the buffers with the yellow color (i.e. note that you're calling glClear only once in your code).
I suggest you call glClear every frame. To fix your code, you can move the call into the loop, just before the SDL_GL_SwapWindow:
while( !quit )
{
while(SDL_PollEvent( &event ))
{
if( event.type == SDL_QUIT )
quit = 1;
}
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow( gWindow );
}

Related

Fastest way to draw filled quad/triangle with the SDL2 renderer?

I have a game written using SDL2, and the SDL2 renderer (hardware accelerated) for drawing. Is there a trick to draw filled quads or triangles?
At the moment I'm filling them by just drawing lots of lines (SDL_Drawlines), but the performance stinks.
I don't want to go into OpenGL.
SDL_RenderGeometry()/SDL_RenderGeometryRaw() were added in SDL 2.0.18:
Added SDL_RenderGeometry() and SDL_RenderGeometryRaw() to allow rendering of arbitrary shapes using the SDL 2D render API
Example:
// g++ main.cpp `pkg-config --cflags --libs sdl2`
#include <SDL.h>
#include <vector>
int main( int argc, char** argv )
{
SDL_Init( SDL_INIT_EVERYTHING );
SDL_Window* window = SDL_CreateWindow("SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN );
SDL_Renderer* renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC );
const std::vector< SDL_Vertex > verts =
{
{ SDL_FPoint{ 400, 150 }, SDL_Color{ 255, 0, 0, 255 }, SDL_FPoint{ 0 }, },
{ SDL_FPoint{ 200, 450 }, SDL_Color{ 0, 0, 255, 255 }, SDL_FPoint{ 0 }, },
{ SDL_FPoint{ 600, 450 }, SDL_Color{ 0, 255, 0, 255 }, SDL_FPoint{ 0 }, },
};
bool running = true;
while( running )
{
SDL_Event ev;
while( SDL_PollEvent( &ev ) )
{
if( ( SDL_QUIT == ev.type ) ||
( SDL_KEYDOWN == ev.type && SDL_SCANCODE_ESCAPE == ev.key.keysym.scancode ) )
{
running = false;
break;
}
}
SDL_SetRenderDrawColor( renderer, 0, 0, 0, SDL_ALPHA_OPAQUE );
SDL_RenderClear( renderer );
SDL_RenderGeometry( renderer, nullptr, verts.data(), verts.size(), nullptr, 0 );
SDL_RenderPresent( renderer );
}
SDL_DestroyRenderer( renderer );
SDL_DestroyWindow( window );
SDL_Quit();
return 0;
}
Note that due to the API lacking a data channel for Z coordinates only affine texturing is achievable.
Not possible. SDL2 does not include a full-fledged rendering engine.
Some options:
You could adopt Skia (the graphics library used in Chrome, among ohters) and then either stick with a software renderer, or instantiate an OpenGL context and use the hardware backend.
You could use another 2D drawing library such as Raylib
Or just bite the bullet and draw your triangles using OpenGL.

SDL Application error: expected unqualified-id before ‘if’

When I compile this SDL code I get this error:
SDL_DEV.cpp:60:2: error: expected unqualified-id before ‘if’
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
^
SDL_DEV.cpp:64:2: error: expected unqualified-id before ‘else’
else
^
Makefile:21: recipe for target 'all' failed
make: *** [all] Error 1
(I am compiling this with g++ in Linux mint with SDL 2.0.5 installed)
Here is the full source code
#include <SDL2/SDL.h>
#include <stdio.h>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
int main( int argc, char* args[] )
{
SDL_Window* window = NULL;
SDL_Surface* screenSurface = NULL;
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
}
else
{
window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if( window == NULL )
{
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
}
else
{
screenSurface = SDL_GetWindowSurface( window );
SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0xFF, 0xFF ) );
SDL_UpdateWindowSurface( window );
SDL_Delay( 2000 );
}
}
SDL_DestroyWindow( window );
SDL_Quit();
return 0;
}
SDL_Window* window = NULL;
SDL_Surface* screenSurface = NULL;
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
}
else
{
window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if( window == NULL )
{
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
}
else
{
screenSurface = SDL_GetWindowSurface( window );
SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0xFF, 0xFF ) );
SDL_UpdateWindowSurface( window );
SDL_Delay( 2000 );
}
}
SDL_DestroyWindow( window );
SDL_Quit();
return 0;
}
I don't understand why I am getting this error, because I have compiled it before on a different machine. I would be very happy if someone could help me figure this problem out. Thank you.
Problem solved, I guess I just didn't see the extra code when I copied it over from my windows platform.

Auto redraw window possible in SDL-2?

Here is a minimal SDL-1.2 text output example (stripped from the lazyfoo tutorial for ttf):
#include <SDL.h>
#include <SDL_ttf.h>
#include <string>
SDL_Surface *message = NULL;
SDL_Surface *screen = NULL;
SDL_Event event;
TTF_Font *font = NULL;
SDL_Color color = { 255, 255, 255 };
int main( int argc, char* args[] )
{
SDL_Init( SDL_INIT_EVERYTHING );
screen = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE );
TTF_Init();
SDL_WM_SetCaption( "Test message", NULL );
font = TTF_OpenFont( "anyttffont.ttf", 20 );
message = TTF_RenderText_Solid(
font, "My test message", color );
SDL_Rect offset;
offset.x = 0;
offset.y = 150;
SDL_BlitSurface( message, NULL, screen, &offset );
SDL_Flip( screen );
bool quit = false;
while( quit == false )
while( SDL_PollEvent( &event ) )
if( event.type == SDL_QUIT )
quit = true;
SDL_FreeSurface( message );
TTF_CloseFont( font );
TTF_Quit();
SDL_Quit();
return 0;
}
The resulting executable redraws the window automatically after re-exposing it (after minimizing or obscuring).
Is it possible to do something like this in SDL-2?
I tried the equivalent tutorial from lazyfoo for SDL-2, but this has code to constantly re-render the text in the event loop. It stops re-drawing when the render code is moved in front of the loop. I also tried rewriting it using the window surface directly and then using SDL_UpdateWindowSurface(gWindow);, but this behaves the same way.

Inconsistent "undefined reference to..." errors when building SDL with MinGW/Code::Blocks

I have 3 independent files, two are .c files, one is .cpp.
When I try to build/run in Code::Blocks one of the .c files I get an "undefined reference to `SDL_main'" build error.
first file (let's call it SDLtest1.c) builds and runs:
//-----< includes >-----//
// Using SDL and standard IO
#include "SDL.h"
#include <stdio.h>
//-----< globals and constants >-----//
//screen dimension constants
typedef enum {
SCREEN_WIDTH = 640,
SCREEN_HEIGHT = 480,
}SCREEN_DIMENSIONS;
//-----< main >-----//
int main(int argc, char* argv[]) {
// The window we'll be rendering to
SDL_Window* window = NULL;
// The surface contained by the window
SDL_Surface* screenSurface = NULL;
// Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
printf( "SDL could not be initialized! SDL_Error: %s\n", SDL_GetError() );
}
else {
// Create Window
window = SDL_CreateWindow("SDL Tutorial",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
if( window == NULL ){
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
} else {
// Get window surface
screenSurface = SDL_GetWindowSurface( window );
// Fill the surface white
SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0xFF, 0xFF) );
// Update the surface
SDL_UpdateWindowSurface( window );
// Wait two seconds
SDL_Delay( 2000 );
}
}
// Destroy Window
SDL_DestroyWindow( window );
// Quit SDL subsystems
SDL_Quit();
return 0;
}
I also have a .cpp file (lets call it SDLexample.cpp) that builds and runs:
//Using SDL and standard IO
#include <SDL.h>
#include <stdio.h>
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
//Starts up SDL and creates window
bool init();
//Loads media
bool loadMedia();
//Frees media and shuts down SDL
void close();
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//The image we will load and show on the screen
SDL_Surface* gHelloWorld = NULL;
bool init()
{
//Initialization flag
bool success = true;
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Create window
gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if( gWindow == NULL )
{
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Get window surface
gScreenSurface = SDL_GetWindowSurface( gWindow );
}
}
return success;
}
bool loadMedia()
{
//Loading success flag
bool success = true;
//Load splash image
gHelloWorld = SDL_LoadBMP( "02_getting_an_image_on_the_screen/hello_world.bmp" );
if( gHelloWorld == NULL )
{
printf( "Unable to load image %s! SDL Error: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError() );
success = false;
}
return success;
}
void close()
{
//Deallocate surface
SDL_FreeSurface( gHelloWorld );
gHelloWorld = NULL;
//Destroy window
SDL_DestroyWindow( gWindow );
gWindow = NULL;
//Quit SDL subsystems
SDL_Quit();
}
int main( int argc, char* args[] )
{
//Start up SDL and create window
if( !init() )
{
printf( "Failed to initialize!\n" );
}
else
{
//Load media
if( !loadMedia() )
{
printf( "Failed to load media!\n" );
}
else
{
//Apply the image
SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );
//Update the surface
SDL_UpdateWindowSurface( gWindow );
//Wait two seconds
SDL_Delay( 2000 );
}
}
//Free resources and close SDL
close();
return 0;
}
But this third file (SDLtest2.c) fails to build as follows:
C:\MinGW\lib\libSDL2main.a(SDL_windows_main.o):SDL_windows_main.c|| undefined reference to `SDL_main'|
||=== Build finished: 1 errors, 0 warnings (0 minutes, 0 seconds) ===|
third file:
//-----< includes >-----//
#include "SDL.h"
#include <stdio.h>
//-----< preprocessor directives >-----//
#define TRUE 1
#define FALSE 0
typedef int BOOLEAN;
//-----< globals and constants >-----//
typedef enum {
SCREEN_WIDTH = 640,
SCREEN_HEIGHT = 480
}SCREEN_DIMENSION;
// The window we'll be rendering to
SDL_Window* gWindow = NULL;
// The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
// The image we will load and show on the screen
SDL_Surface* gHelloWorld = NULL;
//-----< forward declarations >-----//
// Starts up SDL and creates window
BOOLEAN init();
// Loads media
BOOLEAN loadMedia();
// Frees media and shuts down SDL
void close();
//-----< main >-----//
int main(int argc, char* args[]) {
// Start up SDL and create window
if( !init() ) {
printf( "Failed to initialize!\n" );
}
else
{
// Load media
if( !loadMedia() ) {
printf( "Failed to load media!\n" );
}
else
{
// Apply the image
SDL_BlitSurface( gHelloWorld, NULL, gScreenSurface, NULL );
// Update the surface
SDL_UpdateWindowSurface( gWindow );
// Wait two seconds
SDL_Delay( 2000 );
}
}
// Free resources and close SDL
close();
return 0;
}
//-----< function definitions >-----//
BOOLEAN init() {
// Initialization flag
BOOLEAN success = TRUE;
// Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
success = FALSE;
}
else
{
// Create a window
gWindow = SDL_CreateWindow( "SDL Tutorial",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
if( gWindow == NULL ) {
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetEror() );
success = FALSE;
}
else
{
//Get window surface
gScreenSurface = SDL_GetWindowSurface( gWindow );
}
return success;
}
BOOLEAN loadMedia() {
// Loading success flag
BOOLEAN success = TRUE;
// Load splash image
gHelloWorld = SDL_LoadBMP( "02_getting_an_image_on_the_screen/hello_world.bmp" );
if( gHelloWorld == NULL ) {
printf( "Unable to load image %s! SDL Error: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError() );
success = FALSE;
}
return success;
}
void close() {
// Deallocate surface
SDL_FreeSurface( gHelloWorld );
gHelloWorld = NULL;
// Destroy window
SDL_DestroyWindow( gWindow );
gWindow = NULL;
//Quit SDL subsystems
SDL_Quit();
}
I've looked over and over the third file for typos that could cause the build error and haven't found any (although I surely could have missed one). I have looked over similar forum questions but nothing has been an exact match and the fact that the other two files build and run successfully suggests to me that the problem isn't with my Code::Blocks or SDL set-up.
I know this is all a lot to look over and appreciate any help anyone can provide.

Horde3D not rendering to GLFW window in OS X

I'm an experienced programmer but totally new to C++. I'm using GLFW 3 and Horde3D in Xcode 5 on OS X 10.5.
I've followed the basic tutorials of GLFW and Horde3D. I'm able to create a window, make it the current context, and apparently a simple game loop is running fine, including h3dRender( cam ). But all I get is a black window. Any insight as to the step (or entire concept) I'm missing?
Thank you! (code below)
#include <iostream>
#include <GLFW/glfw3.h>
#include <Horde3D.h>
#include <Horde3DUtils.h>
GLFWwindow* window;
H3DNode model = 0, cam = 0;
int winWidth = 640, winHeight = 480;
float fps = 24;
static float t = 0;
bool running = false;
bool initWindow();
bool initGame();
void gameLoop();
void errorListener( int, const char* );
void windowCloseListener( GLFWwindow* );
int main(void)
{
glfwSetErrorCallback( errorListener );
if ( !initWindow() ) return -1;
if ( !initGame() ) return -1;
running = true;
while ( running )
{
gameLoop();
}
h3dRelease();
glfwDestroyWindow( window );
glfwTerminate();
exit( EXIT_SUCCESS );
}
bool initWindow()
{
if ( !glfwInit() ) return -1;
window = glfwCreateWindow( winWidth, winHeight, "Hello World", NULL, NULL );
if ( !window )
{
glfwTerminate();
exit( EXIT_FAILURE );
}
glfwSetWindowCloseCallback( window, windowCloseListener );
glfwMakeContextCurrent( window );
glfwSwapInterval( 0 );
return true;
}
bool initGame()
{
if ( !h3dInit() ) return false;
H3DRes pipeRes = h3dAddResource( H3DResTypes::Pipeline, "standard.pipeline", 0 );
H3DRes modelRes = h3dAddResource( H3DResTypes::SceneGraph, "character.scene.xml", 0 );
H3DRes animRes = h3dAddResource( H3DResTypes::Animation, "walk.anim.xml", 0 );
h3dutLoadResourcesFromDisk( "" );
model = h3dAddNodes( H3DRootNode, modelRes );
h3dSetupModelAnimStage( model, 0, animRes, 0, "", false );
H3DNode light = h3dAddLightNode( H3DRootNode, "Light 1", 0, "LIGHTING", "SHADOWMAP" );
h3dSetNodeTransform( light, 0, 20, 0, 0, 0, 0, 1, 1, 1 );
h3dSetNodeParamF( light, H3DLight::RadiusF, 0, 50.0f );
cam = h3dAddCameraNode( H3DRootNode, "Camera", pipeRes );
h3dSetNodeParamI( cam, H3DCamera::ViewportXI, 0 );
h3dSetNodeParamI( cam, H3DCamera::ViewportYI, 0 );
h3dSetNodeParamI( cam, H3DCamera::ViewportWidthI, winWidth );
h3dSetNodeParamI( cam, H3DCamera::ViewportHeightI, winHeight );
h3dSetupCameraView( cam, 45.0f, ( float ) winWidth / winHeight, 0.5f, 2048.0f );
h3dResizePipelineBuffers( pipeRes, winWidth, winHeight );
return true;
}
void gameLoop ()
{
t = t + 10.f * ( 1/ fps );
h3dSetModelAnimParams( model, 0, t, 1.0f );
h3dSetNodeTransform( model, t * 10, 0, 0, 0, 0, 0, 1, 1, 1 );
h3dRender( cam );
h3dFinalizeFrame();
glfwSwapBuffers( window );
glfwPollEvents();
}
void errorListener( int error, const char* description )
{
fputs( description, stderr );
}
void windowCloseListener( GLFWwindow* window )
{
running = false;
}
You are not able to view anything because the resources have not been loaded for your application. You need to specify the directory path which holds the resources(resources like character.scene.xml, walk.anim.xml etc.) as the an argument to the h3dutLoadResourcesFromDisk()