I have a
timer = TTF_RenderText_Solid( tfont, timeStr.str().c_str(), txtColor );
applySurface(500, 30, timer, screen);
and on the 'screen' surface I have also applied my character, and my wall. But for some reason I can't seem to see the timer unless I have already NULL the 'floorsurface' and the 'charsurface'. Am I doing something wrong?
Try putting timerUpdate() before SDL_Flip(screen). You are calling SDL_Flip, then you call timerUpdate(). So you think, OK, that's fine, next time the screen is flipped, I'll see the text. But what is happening is that you are blitting more surfaces on top before the screen is flipped again, and then you can't see the text because you blitted surfaces on top of it. All you need to do is change the order, so
timerUpdate();
if (SDL_Flip(screen) == -1) return 1; //Instead of the other way round
should work.
Related
I have a problem with adding a background in my game. My code looks like that:
while (true)
{
al_draw_bitmap(background, 0, 0, NULL);
al_flip_display();
some code(...);
al_draw_bitmap(snake,0,0,NULL);
/*drawing my snake's tail*/
al_clear_to_color(al_map_rgb(0,0,0));
al_draw_bitmap(apple,0,0,NULL);
al_flip_display();
}
And I have visible an apple and a black screen most of the time.
I've been changing order of some lines in code and none of these combination worked (best case was when I had visible snake and background but there was no apple).
Before adding a background, my snake's tail sometimes disappered, but it wasn't very visible, and except that, everything seemed to be okay.
Anyone knows how to add a background properly?
Or maybe it's fault of my computer?
Once per draw loop, you should:
clear the display
draw your background
draw bitmaps on top of the background
flip the display
For example:
al_clear_to_color(al_map_rgb(0,0,0));
al_draw_bitmap(background, 0, 0, NULL);
al_draw_bitmap(apple,0,0,NULL);
al_draw_bitmap(snake,0,0,NULL);
al_flip_display();
Note that you should only call al_flip_display once per draw loop, after you have drawn everything for that loop. al_clear_to_color should be called first as it will wipe out everything you have drawn. In the example you gave, you are drawing your apple and snake to the same location, so I wouldn't be suprised if one is blocking part of the other.
Also, you probably don't want to stick your draw loop in a while(true) as the framerate will be unconstrained. That is, it will run as fast as it is allowed, and the framerate won't be consistent. The typical approach is to use an event-driven draw loop.
I am trying to make simple square where you could paint with mouse. Problem is, whenever draw signal is happens, cairo surface seems to be cleared entirely. I understand this because after first queue_draw() white background is gone and I see my GTK theme color (which is grey).
I thought I could save surface or context, but you can't just create empty surface in cairo, and I can't create it using this->get_window()->create_cairo_surface() (where this is object of class inherited from Gtk::DrawingArea) because when constructor is called, widget isn't attached to any window yet, so it is a null pointer. I mean, I could create some public function called you_are_added_to_window_create_cairo_surface() but I'd really like not to do this.
So I really don't know what to do and what I don't understand about cairo.
How do I preserve, or save 'canvas' current state, so whatever is actually being drawn is just applied on existing drawing?
Here is callback function of my class:
bool MyDrawingArea::on_draw(const Cairo::RefPtr<Cairo::Context> & cr) {
/* clear and fill background with white in the beginning */
if (first_draw) {
cr->save();
cr->set_source_rgb(255.0, 255.0, 255.0);
cr->paint();
cr->restore();
first_draw = false;
}
cr->save();
cr->set_source_rgb(0.0, 0.0, 0.0);
cr->begin_new_path();
while (!dots_queue.empty()) {
auto dot = dots_queue.front();
cr->line_to(dot.first, dot.second);
dots_queue.pop();
}
cr->close_path();
cr->stroke();
cr->restore();
return false;
}
Remove first_draw and instead of dots_queue.pop(), just iterate over the dots_queue and redraw all of them each time.
The draw function is not meant for "I want to add some drawing". Instead, it is "hey, the windowing system has no idea what should be drawn here, please fill this with content". That's why the cairo surface is cleared.
So while storing all actions works, it's really not ok if you are trying to have your program save your drawings, you will have to use second surface to save everything on.
My solution combines both answers of Uli Schlachter.
First, I have structure, in which I store last drawing action, since last Button Press, and until Button Release. This allows me to show things such as lines in real time, while keeping canvas clean of it.
Second, I store everything drawn on canvas on a surface, which is created like that:
// this - is object of class, derived from DrawingArea
auto allocation = this->get_allocation();
this->surface = Cairo::ImageSurface::create(
Cairo::Format::FORMAT_ARGB32,
allocation.get_width(),
allocation.get_height()
);
Then, on each draw signal, I restore it like that:
cr->save();
cr->set_source(surface, 0.0, 0.0);
cr->paint();
cr->restore();
Whenever I want to save surface, i.e. apply drawing on to canvas, I do the following:
Cairo::RefPtr<Cairo::Context> t_context = Cairo::Context::create(surface);
t_context->set_source(cr->get_target(), -allocation.get_x(), -allocation.get_y());
t_context->paint();
Here is the important moment. Without adjusting for the allocation coordinates, your canvas is going to slide away on each surface save and restore.
With that, I can easily keep my drawings on canvas, load canvas from file (because I am using ImageSurface), or save it to the file.
i need help with drawing cube by the keyboardup method , For example if i clicked 'a' then a cube must be displayed.
what i have reached so far
void KeyUp(unsigned char key, int x, int y) {
if (key == 'a') {glutSolidCube(5);}
glutPostRedisplay();
}
but nothing appear in the opengl.
want to let you know that when i put glutSolidCube(5); in the display method it works.
Toggle a "display cube" Boolean in your keyboard callback (and keep the glutPostRedisplay()) and (selectively) draw the cube in your display callback.
but nothing appear in the opengl.
Because after drawing glutSolidCube(5) in keyboard method, you clear the viewport in the display method. Thus everything drawn is wiped out.
when i put glutSolidCube(5); in the display method it works.
It is working there because you are probably drawing at the right location (i.e.) after clearing the viewport and before posting.
Declare a global boolean and set it true at key callback method.
Use the boolean to decide if you have to draw the cube or not in your display mathod.
I'm hoping someone can help me out, I'm using SFML 2.1 and when I draw my renderWindow it just keeps flickering, now I know SFML uses two buffers so i'm sure one is not getting drawn at all but I can't understand why.
Here is my loop
while(!quit)
{
rs.Canvas.pollEvent(gameEvent);
colour += 1;
rs.Update(colour);
if(gameEvent.type == sf::Event::Closed)
quit = true;
rs.Canvas.clear( sf::Color(colour,0,0) );
rs.Canvas.draw( sprite );
rs.Canvas.display();
if(colour >= 300)
quit = true;
}
the rs.Canvas has these set
Canvas.setVerticalSyncEnabled(true);
Canvas.setFramerateLimit(60);
Can anyone see why my renderWindow would flicker?
From the SFML 2.0 tutorial, under the section Controlling the framerate:
Never use both setVerticalSyncEnabled and setFramerateLimit at the same time! They would badly mix and make things worse.
http://www.sfml-dev.org/tutorials/2.0/window-window.php#controlling-the-framerate
In the comments of your post, you state that you were calling clear twice on the window. This would effectively treat your window as if it were single buffered. I understand that the effect of this could create some screen tearing, but on my end I am not getting a glaring flicker effect. Make sure to remove your a call to either setting the framerate or to using the vertical sync, just to be sure.
Basically I was calling
rs.Canvas.clear
twice. I removed the second call and everything then worked fine
I have written program which has a delay between each drawn circle, but when i put for example SDL_Delay(2) everything is black for like 5 seconds and then i see everything already drawn, but i need to see everything from begining so that it would seem like an animation.
Here is my code:
while (t<tk){
l.a = l.a + (l.b - l.a) * t;
a=l.a;
Circle cir1(a,o);
draw_circle(cir1, canvas);
SDL_Delay(2);
t=t+0.001;
}
The thing is after each draw_circle you actually have to update the screen. Draw functions in almost all graphical engines write to a buffer and don't update the screen until you tell them to!
I don't know how this works with SDL that doesn't use OpenGL, but with double buffer OpenGL windows you should write SDL_GL_SwapBuffers() and then after it, start clearing the screen etc as if you are drawing the screen anew!
If it is a single buffer window, you should flush the buffer to update the screen. I never used SDL by itself (without OpenGL) so I don't know the function names, but with this hint you know why your code doesn't work and you should be able to find the functions you need from SDL documentation.