When I want to draw a line by using al_draw_line(100,100,400,400,al_map_rgb(255,255,0),5);, my ALLEGRO_DISPLAY gets closed automatically and statements after this line does not execute. My program just halts
#include<allegro5/allegro.h>
#include<allegro5/allegro_primitives.h>
int main(){
ALLEGRO_DISPLAY *display=NULL;
if(!al_init()){
return -1;
}
if(!al_init_primitives_addon()){
return -1;
}
display=al_create_display(600,600);
al_draw_line(100,100,400,400,al_map_rgb(0,0,0),3);
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
al_rest(20.0);
al_destroy_display(display);
return 0;
}
You don't check for the return value of al_create_display, that can fail. Anyway: I don't know why your program apparently crashes (your code doesn't do anything that should crash, aside from not checking the display) but you won't see anything because you:
A) draw the line and background in the same color (black)
B) clear the background color after drawing the line (thus overdrawing it).
Your code after making some changes:
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include <stdio.h>
int main(){
ALLEGRO_DISPLAY *display=NULL;
if(!al_init()){
fprintf(stderr,"Couldn't initialize allegro!\n");
return -1;
}
if(!al_init_primitives_addon()){
fprintf(stderr,"Couldn't initialize primitives addon!\n");
return -1;
}
display=al_create_display(600,600);
if(!display) {
fprintf(stderr,"Couldn't create allegro display!\n");
return -1;
}
al_clear_to_color(al_map_rgb(0,0,0));
al_draw_line(100,100,400,400,al_map_rgb(255,0,0),3);
al_flip_display();
al_rest(1.0);
al_destroy_display(display);
return 0;
}
If it's actually your display that's broken, you should at least get an error message now. This works for me though, and I don't see why it shouldn't for you (unless you try to create this in fullscreen mode, which won't work).
al_draw_line(100,100,400,400,al_map_rgb(0,0,0),3);
al_clear_to_color(al_map_rgb(0,0,0));
These two lines are backwards. You're clearing (wiping) your display AFTER you are drawing your line. So you are never actually seeing the line.
Related
Am trying to load an image with SFML using Xcode, but everytime I run the program, the window (which has been created using the code) flashes and disappears...
Here's the code I am using:
#include <SFML/Graphics.hpp>
#include <iostream>
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 1024
int main()
{
sf::RenderWindow window(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "Orsome Game");
while(window.isOpen())
{
sf::Event e;
while(window.pollEvent(e))
{
switch (e.type)
{
case sf::Event::Closed:
window.close();
break;
}
}
sf::Image image;
if(!image.loadFromFile("sprite.png")){
return -1;
}
window.clear(sf::Color(255,255,255));
window.display();
}
return EXIT_SUCCESS;
}
Have also put the image file where the c++ file is, but it still doesn't work!
I would put an sf::Style::Default in the RenderWindow arguments, straight after "Orsome Game" window name. Because you are using the pollEvent, that would allow you to exit the window by pressing the x button in the top right corner, like a default application layout.
Is the picture in the same directory as your solution file? Or your main.cpp?
It should be, of course.
And, maybe, try loading your image with Texture and Sprite, like this:
sf::Texture texture;
texture.loadFromFile("picturename.png");
sf::Sprite sprite;
sprite.setTexture(texture);
inside the while window is open loop.
To draw it:
// after window.clear() ...
//... your code
window.draw(sprite);
//... other things to draw
// and then, your window.display();
But, probably, your sf::Image should also work. Tell me how it goes
EDIT:
Try this code and see if the window opens.
Otherwise, that might be the problem of setting up the SFML on your computer and you will have to find some good tutorial on how to set it up properly! But let's see:
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf;
int main()
{
RenderWindow window(VideoMode(640, 640), "Test", Style::Default);
while (window.isOpen()) {
Event _event;
while (window.pollEvent(_event)) {
switch (_event.type) {
case Event::Closed:
window.close();
break;
}
}
window.clear();
// draw
// ...
window.display();
}
return 0;
}
I have set up my allegro 5.0.7 project in MSVC 2010 properly and the code executes. I am able to compile and run programs that will display an error dialog or something. However, whenever I run a program that draws a window, the window is not shown on my screen. I see it minimized with a broken file icon. The code runs with no errors, however. Here is an example of some code that gives me this problem. Thanks!
#include <stdio.h>
#include <allegro5/allegro.h>
int main(int argc, char **argv){
ALLEGRO_DISPLAY *display = NULL;
if(!al_init()) {
fprintf(stderr, "failed to initialize allegro!\n");
return -1;
}
display = al_create_display(640, 480);
if(!display) {
fprintf(stderr, "failed to create display!\n");
return -1;
}
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
al_rest(10.0);
al_destroy_display(display);
return 0;
}
This code even exits after 10 seconds, as it should. The only problem is that the window is not drawn to the screen. It is only minimized, with a broken file icon. I have Windows 7 64-bit.
This is a known bug affecting certain configurations that may be fixed in a more recent version.
Use al_set_window_position() to move the window onscreen.
I think I have a bug in my program. I use SDL and OpenGL to render an animation. The program also measures the average FPS. Tipically, when I run the program, it will run at around 550 FPS.
However, if I start a second instance of the program, the FPS drops for both at around half (220 FPS). The strange thing is that if I close the first instance, the second one will still run at only 220 FPS. This leads me to believe that my cleanup code is somehow flawed.
Sometimes, even if I run a single instance, it will run at only 220 FPS, probably due to a previous instance that failed to clean up properly. Is there something wrong with my approach below?
I use a screen class which has the following *tors:
namespace gfx
{
screen::screen(const settings& vs) : dbl_buf_(false), sdl_surface_(0)
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
throw util::exception(::std::string("Unable to initialize SDL video: ") + SDL_GetError());
if (!set(vs))
{
SDL_Quit();
throw util::exception("Unable to setup initial video mode.");
}
glewInit();
}
screen::~screen()
{
SDL_Quit();
}
bool screen::set(const settings& vs)
{
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
Uint32 flags = SDL_HWSURFACE | SDL_OPENGL;
if (vs.full_screen) flags |= SDL_FULLSCREEN;
sdl_surface_ = SDL_SetVideoMode(vs.size_x, vs.size_y, vs.bpp, flags);
if (!sdl_surface_) return false;
settings_ = vs;
int db_flag = 0;
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &db_flag);
dbl_buf_ = (db_flag == 1);
return true;
}
// ...
}
Also:
int main()
{
try
{
gfx::settings vs = {800, 600, 32, false};
gfx::screen scr(vs);
// main app loop, render animation using OpenGL calls
// loop runs while running_ variable is true (see below)
}
// catch, etc.
return 0;
}
If it makes any difference, I use Linux and an ATI card.
Update: Event handling code:
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
running_ = false;
break;
case SDL_QUIT:
running_ = false;
break;
default:
world_.process_event(event);
break;
}
}
When a process terminates all the resources it used are freed automatically. That includes OpenGL. What may happen is, that you don't terminate your process but only hide the window by clicking the close button.
I wish to have a semi-transparent SDL background (nothing to do with sub-surfaces or images), such that instead of having a black background it is actually transparent, but the other things I draw are not. My current code is a slightly modified copy of Code::Blocks' SDL project, similar to how various applications have rounded borders or odd shapes besides rectangles.
#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#ifdef __APPLE__
#include <SDL/SDL.h>
#else
#include <SDL.h>
#endif
int main ( int argc, char** argv )
{
putenv("SDL_VIDEO_WINDOW_POS");
putenv("SDL_VIDEO_CENTERED=1");
// initialize SDL video
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "Unable to init SDL: %s\n", SDL_GetError() );
return 1;
}
// make sure SDL cleans up before exit
atexit(SDL_Quit);
// create a new window
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16,
SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_NOFRAME);
if ( !screen )
{
printf("Unable to set 640x480 video: %s\n", SDL_GetError());
return 1;
}
// load an image
SDL_Surface* bmp = SDL_LoadBMP("cb.bmp");
if (!bmp)
{
printf("Unable to load bitmap: %s\n", SDL_GetError());
return 1;
}
// centre the bitmap on screen
SDL_Rect dstrect;
dstrect.x = (screen->w - bmp->w) / 2;
dstrect.y = (screen->h - bmp->h) / 2;
// program main loop
bool done = false;
while (!done)
{
// message processing loop
SDL_Event event;
while (SDL_PollEvent(&event))
{
// check for messages
switch (event.type)
{
// exit if the window is closed
case SDL_QUIT:
done = true;
break;
// check for keypresses
case SDL_KEYDOWN:
{
// exit if ESCAPE is pressed
if (event.key.keysym.sym == SDLK_ESCAPE)
done = true;
break;
}
} // end switch
} // end of message processing
// DRAWING STARTS HERE
// clear screen
SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
// draw bitmap
SDL_BlitSurface(bmp, 0, screen, &dstrect);
// DRAWING ENDS HERE
// finally, update the screen :)
SDL_Flip(screen);
} // end main loop
// free loaded bitmap
SDL_FreeSurface(bmp);
// all is well ;)
printf("Exited cleanly\n");
return 0;
}
I think what you're trying to do is in fact a shaped window (parts of the window are transparent depending on a mask that you provide). It seems there's no way to do that with SDL 1.2, however there is a SDL_SetWindowShape function just for this in SDL 1.3 for which you can find a pre-release snapshot here but it's not even in beta yet so I suggest waiting until it's officialy released :)
this is a link to a pretty neat article about development of an older application for Mac OS 9, which did not have support for shaped windows, either.
It's actually a neat article in general about software development.
But the idea seems pretty smart, and I wonder if you might be able to get it working here, too. Instead of trying to make a transparent background, they actually take a screen-shot of the computer right where their window is going to go, and then use that screen shot for their background. When the user drags the window around on the screen, they continue to update the background with new screen-shots. I think this might be more complicated than you were hoping for, but it's certainly an interesting idea.
I read a few tutorials about OpenGL and now I'm trying to use it with SDL. The thing is that when I use SDL_GL_SwapBuffers() in a while loop the window just freezes. Here's some code:
#include "SDL.h"
#include "system.h"
#include "SDL_opengl.h"
System Sys(800, 600, 32);
SDL_Event kpress;
int main( int argc, char* args[] )
{
Sys.init();
bool quit = false;
while (!quit)
{
while (SDL_PollEvent(&kpress)) if(kpress.type == SDL_QUIT) quit = true;
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapBuffers();
}
SDL_Quit();
return 0;
}
------------------------------These are in system.h, class System----------------
bool System::init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
errorCode = 1;
return false;
}
if (SDL_SetVideoMode(screen_h, screen_w, bpp, SDL_OPENGL) == 0)
{
errorCode = 2;
return false;
}
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
if (!init_GL())
{
errorCode = 3;
return false;
}
SDL_WM_SetCaption("Engine", 0);
return true;
}
bool System::init_GL()
{
glClearColor(1, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, screen_h, screen_w, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (glGetError() != GL_NO_ERROR) return false;
return true;
}
If I draw some shapes or use a timer for limiting FPS - nothing changes.
Do you have any ideas?
My first advice: Get rid of that bogus System class: So far all the tasks it does are purely sequential/procedural and that should be reflected in the programs outline. People tend to put everything into classes just becase they're taught see everything in terms of object models. But this System class would have to follow the singleton pattern, which, in my opinion, is an anti-pattern.
All the stuff you placed in init_GL belong into the rendering loop. OpenGL initialization ends after creating a render context. OpenGL state is not initialized it is set on demand. OpenGL objects are initialized, but also on demand.
Also you're using glGetError not correctly. It needs to be called in a loop until no more errors are reported. It thus also makes little sense to bail out if a GL error is reported. OpenGL errors should be considered diagnostic.
SDL_GL_SetAttribute must be set before calling SDL_SetVideoMode so you're probably not double buffering.
Hey, you aren't calling the function which initializes OpenGL: init_GL()
youre not checking the result from system::init - it might be failing somewhere in that function and not setting up your initial state correctly
SDL #defines main() to be SDL_main() to allow it to do some extra initialization before program start. Which you seem to be bypassing via the statically initialized class.
Try constructing your System object in main().