I'm working on a nice open-source project that I hope to release, however I'm having some trouble with a child window not redrawing after being damaged. Please see this image for details:
Here is the code I'm using to display this:
void showMessageWindow (std::string strMessage, std::string strTitle)
{
Fl_Window* msgWin = new Fl_Window(400, 255, NULL);
if (strTitle == "")
msgWin->label("Window Title");
msgWin->box(FL_BORDER_FRAME);
msgWin->set_non_modal();
Fl_PNG_Image* img = new Fl_PNG_Image("/home/obaker/Pictures/info-icon.png");
Fl_Box* ibox = new Fl_Box(20, 20, 48, 48);
ibox->image(img);
Fl_Multiline_Output* mOut = new Fl_Multiline_Output(90, 20, 275, 175, NULL);
mOut->box(FL_NO_BOX);
mOut->wrap(true);
mOut->readonly(true);
mOut->cursor_color(FL_BACKGROUND_COLOR);
mOut->value(strdup(strMessage.c_str()));
Fl_Button* btn = new Fl_Button(150, 210, 100, 35, "OK");
btn->box(FL_GTK_UP_BOX);
btn->shortcut(FL_Enter);
btn->callback(msgBoxClose, msgWin);
msgWin->add(ibox);
msgWin->add(mOut);
msgWin->add(btn);
msgWin->show();
}
I have tried using Fl_Double_Window instead of Fl_Window and it looks even worse:
As 'edgy' and 'cool' as that might look, it's not appropriate for my project. :-)
I'm developing and testing on Debian Linux 8, 64-bit, AMD Radeon HD 6670 video card, 8 GB RAM. The Debian-provided version of FLTK is 1.3 (1.3.2-6).
The parent window is an Fl_Double_Window and it redraws itself just fine.
Is there anything anyone could recommend to force this child window to redraw itself when it's damaged?
Thank you in advance! :-)
After guidance from Chris on the FLTK forums, I was able to resolve this issue.
The changes necessary are:
msgWin->box(FL_BORDER_BOX)
instead of
msgWin->box(FL_BORDER_FRAME)
"FL_NO_BOX for output may also lead to drawing artifacts. Better
set the outputs background color to the windows background color:"
mOut->box(FL_FLAT_BOX);
mOut->color(msgWin->color());
Thank you for all of your help! :-)
Related
I'm working on a little project using C++ and Allegro 5, my question is
Is there a way to draw antialiased primitives to a bitmap using Allegro 5?
I mean I'm using this function
void draw_to_gameBuffer(ALLEGRO_BITMAP *&gameBuffer, ALLEGRO_DISPLAY *&display)
{
static float x = 0;
al_set_target_bitmap(gameBuffer);
al_draw_filled_rectangle(0,0, 350, 622, al_map_rgb(130, 80, 120));
al_draw_filled_circle(x, 200, 100, al_map_rgb(12, 138, 129));
al_draw_filled_triangle(0, 0, 100, 0, 50, 100, al_map_rgb(12, 138, 129));
x += 2.7;
if(x > 350 + 100)
x = -250;
al_set_target_backbuffer(display);
}
to draw a cicle and a triangle (testing purposes) over a target bitmap as shown, on the project display options I have
al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 4, ALLEGRO_SUGGEST);
al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);
to enable antialiasing, the problem is that all primitives rendered on the gameBuffer have jaggies but the primitives rendered outside the gameBuffer are perfectly smooth, how can I solve that? Or is there a way to do what I'm trying to do and get smooth primitives drawn on the gameBuffer?
It seems that Allegro 5 has some experimental features that can be enabled defining this macro (before defining any allegro header):
#define ALLEGRO_UNSTABLE
With this macro enabled we are able to create a bitmap to draw anything we want and do whatever we want with the bitmap, yes we can do this without enabling the ALLEGRO_UNSTABLE macro but there's this new procedure called:
al_set_new_bitmap_samples(int numberOfSamplesDesired);
that defines how many samples we want in a newly created bitmap, "the downside" of this implementation is that it's only going to work with OpenGl so... we need to force OpenGl (Windows only) to see this new feature working and, how do we put this together and draw antialiased primitives over bitmaps?
first of all, we need to define the ALLEGRO_UNSTABLE macro
#define ALLEGRO_UNSTABLE
then we need to add some allegro headers (the ones we need)
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
after this we need to define a bitmap
ALLEGRO_BITMAP *buffer = nullptr;
now we enable OpenGl and the flags we want and the display options
al_set_new_display_flags(ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE | ALLEGRO_OPENGL);
al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 2, ALLEGRO_SUGGEST); //antialias stuff
al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); //antialias stuff
to create our bitmap we first call the experimental procedure then create our bitmap
al_set_new_bitmap_samples(4);
buffer = al_create_bitmap(bufferWidth, bufferHeight);
4 samples as an example (lol), to draw to the bitmap we use a procedure like this
void draw_to_buffer(ALLEGRO_BITMAP *&buffer, ALLEGRO_DISPLAY *&display)
{
al_set_target_bitmap(buffer);
al_clear_to_color(al_map_rgb(0, 0, 0));
//anything you want to draw to the bitmap
al_set_target_backbuffer(display);
}
now we just need to draw our bitmap the way we usually draw bitmaps on screen
al_draw_bitmap(buffer, 0, 0, 0);
and that's pretty much it, if you have issues or questions with this implementation, yo can look at my post in the Allegro forums where I got the help of many lovely allegro users that taught me a lot without knowing.
my post in the Allegro forum
I'd like to draw to the desktop wallpaper area with directX 9 in particular. Under the icons and text above the wallpaper.
Similar to Okozo or one of VLC's modes, or Dreamscene.
So there's a lot of similar questions to this but no working examples or tutorials.This A simmilar question but different approach seems pretty useful. A few years ago I was searching and found this site and code.
It's perfect aside from one big issue the icon text gets blocky even with alpha blending. I tried a few fixes but I wasn't able to find any helpful documentation maybe I just wasn't using the right words for searching, maybe it's proprietary. I think I fixed that with a call to invalidate the desktop area but I can't really tell as in the process I messed up the alpha values for the text so it doesn't properly draw the font color. So how do I alter the text for proper alpha blending?
Pouet's links are all dead
I know I should post a snippet but I can't pin down where the problem is as it's more an unexpected feature.
I've been searching for this code for too long.
I'd like to write a Dreamscene like app witch can render dynamic contents other than just video files, and this one may be the most hopful solution.
I compiled your code in VS2010 Win7x64 and found:
Desktop icon text become transparent just like Dreamscene do when the window is like:
0x00150138 "Program Manager" Progman
0x000605D6 "" SHELLDLL_DefView
0x000C05BA "FolderView" SysListView32
Desktop icon text become normal but not clear enough when the window is like:
0x000B007C "" WorkerW
0x000605D6 "" SHELLDLL_DefView
0x000C05BA "FolderView" SysListView32
0x000C05BA "FolderView" SysListView32
0x000511E2 "" WorkerW
0x00150138 "Program Manager" Progman
I tried this method Draw Behind Desktop Icons in Windows 8 to make the window status always be like the second condition; and tried to draw on WorkerW window above Progman window with D3D, but got nothing rendered out.
So far there's nothing helpful, dumping the bitmap used by memoryDC may help, which I'll try latter.
If you got any further approach, please let me know.
It has been long time since I last use English, Sorry for my mistake if any.
Update:Clear Icon Text got!
add this under d3ddev->BeginScene();
d3ddev->SetSamplerState(0,D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
d3ddev->SetSamplerState(0,D3DSAMP_MAGFILTER, D3DTEXF_GAUSSIANQUAD);
and this:
HWND desktop = GetDesktopWindow();
HWND explorer = FindWindowEx(desktop, 0, _T("Progman"), _T("Program Manager"));
SendMessageTimeout(explorer, 0x052C, 0, 0, SMTO_NORMAL, 3000, NULL);
HWND defView = 0;
HWND worker = 0;
while(!defView) {
worker = FindWindowEx(desktop, worker, _T("WorkerW"), 0);
if(worker) {
defView = FindWindowEx(worker, 0, _T("SHELLDLL_DefView"), 0);
}
else break;
}
if (!worker){ /*DBG("First WorkerW failed");*/ return 0;}
worker = FindWindowEx(desktop, (HWND)worker, _T("WorkerW"), 0); //find the next WorkerW
if (!worker){ /*DBG("Created WorkerW not found");*/ return 0;}
Still drawing on the listView, but worker window must exist. This code runs with Aero Theme enabled only.
I'm new to allegro 5. I'm currently writing a simple 2D game in C++.
I used to use Allegro 4 but there was no major support for .PNG images so I changed it. The problem is that in Allegro 4 I could easily create a double buffer for my sprites so they do not flicker nor blink while moving. In allegro 5 there is just "al_draw_bitmap" function which does not let us give any buffer for an argument.
This part of my code looks like this:
al_draw_bitmap(image[0],poz_x,poz_y,0);
al_draw_bitmap(platf, 0, 400, 0);
al_draw_bitmap(p1, poz_p1x, poz_p1y, 0);
al_draw_bitmap(chmurka, 50, 50, 0);
al_flip_display();
al_clear_to_color(al_map_rgb(0,0,0));
I can't find any solution on the internet.
I would be really pleased if you could help me.
I am currently crosscompiling a Sprite Engine under mingw.
Therefore i have 2 Questions.
The behavior of SDL is Emulated by Emscripten through the WebGL Layer.
i don't even have to link the SDL libraries when compiling with emcc.
Question is:
If i initalize my App Like this:
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) == -1)return -1;
SDL_Surface *screen= SDL_SetVideoMode(640, 480, 24, SDL_SWSURFACE);
SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 255, 0, 0));
SDL_Flip(screen);
then i am NOT able to put text into a textfield of the Browser, but i am getting the SDL_Events.
All other Browser Inputs like checkboxes or selectboxes are working.
If initialize my App like this (Emscripten works also without SDL_Init!):
SDL_Surface *screen= SDL_SetVideoMode(640, 480, 24, SDL_HWSURFACE);
SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 255, 0, 0));
SDL_Flip(screen);
then i am able to put tet into the browser textfield but i am not getting SDL_Events.
Is there a workaround to get the Browser Text Input Fields and SDL_Events working?
Question
This line of code compiled on my WIN32 System fills the screen blue
SDL_FillRect(screen,NULL, SDL_MapRGB(screen->format, 255, 0, 0));
the same line compiled with Emscripten fills the screen red.
Is there a way to switch the SDL colors in Emscripten or in the SDL headers?
From your native code, add this before the SDL_CreateWindow call:
SDL_SetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT, "#canvas");
More info here: https://wiki.libsdl.org/SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT
Emscripten, by default, captures all user events to the page. This makes sense for a fullscreen game for example. In your use case, you probably want to modify Emscripten's SDL_Init to not listen to key events, or change its receiveEvent return value.
Had the same problem. For me, doing this fixed it:
Module['doNotCaptureKeyboard'] = true;
I'm trying to create an SDL drawing canvas inside of a simple QT4 window, following the information provided in the SDL wiki and in another question on this site. The project is an NES emulator using QT and SDL that a friend and I decided we wanted to try creating.
Currently, I have a main_window class that will contain the SDL widget, menus that I set up, and probably other stuff as the project develops. The SDL widget I'm creating is called rom_canvas and inherits from QWidget. So far, I'm able to set the SDL_WINDOWID environment variable and I seem to be able to interact with the widget in that I can set and get its geometry and see that it is in fact "visible", but nothing actually shows up in the window.
I don't have any experience with QT4 and SDL until now and don't have a ton of C++ experience, so I could be missing something obvious.
Here's the rom_canvas class:
#include "rom_canvas.hpp"
#include <iostream>
#include <cstdlib>
#include <QString>
rom_canvas::rom_canvas(QWidget *parent)
: QWidget(parent)
{
parent->setAttribute(Qt::WA_PaintOnScreen);
parent->setAttribute(Qt::WA_OpaquePaintEvent);
// setAttribute(Qt::WA_PaintOnScreen);
// setAttribute(Qt::WA_OpaquePaintEvent);
setUpdatesEnabled(false);
// a hack I found online to get the SDL surface to appear in our own window
QString id;
id.setNum(parent->winId());
setenv("SDL_WINDOWID", id.toAscii().data(), 1);
SDL_InitSubSystem(SDL_INIT_VIDEO);
resize(320, 240);
// change constants later
sdl_screen = SDL_SetVideoMode(320, 240, DEFAULT_BPP, SDL_SWSURFACE);
if(!sdl_screen)
std::cout << "couldn't create screen" << std::endl;
SDL_LockSurface(sdl_screen);
SDL_FillRect(sdl_screen, NULL, 0x00FF0000);
SDL_UnlockSurface(sdl_screen);
SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
}
rom_canvas::~rom_canvas()
{
// do NOT release sdl_screen here; that's done when SDL_Quit() is called in main().
}
// this method is a protected slot
void rom_canvas::test()
{
std::cout << "rom_canvas test" << std::endl;
SDL_LockSurface(sdl_screen);
SDL_FillRect(sdl_screen, NULL, 0x00FF0000);
SDL_UnlockSurface(sdl_screen);
SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
}
And here's the main_window constructor:
main_window::main_window(QWidget *parent)
: QMainWindow(parent)
{
canvas = new rom_canvas(this);
setCentralWidget(canvas);
canvas->setGeometry(100, 100, 100, 100);
canvas->show();
canvas->update();
// Add File Menu
open_action = new QAction(tr("&Open..."), this);
open_action->setShortcuts(QKeySequence::Open);
open_action->setStatusTip(tr("Open a new ROM"));
connect(open_action, SIGNAL(triggered()), this, SLOT(select_rom()));
exit_action = new QAction(tr("E&xit"), this);
exit_action->setStatusTip(tr("Exit nesT"));
connect(exit_action, SIGNAL(triggered()), /*QApplication::instance()*/canvas, SLOT(/*quit()*/test()));
// Remember to change this back!!
file_menu = menuBar()->addMenu(tr("&File"));
file_menu->addAction(open_action);
file_menu->addAction(exit_action);
rom_dir = QDir::homePath();
}
The code's a bit messy since I've been trying things to get this to work. Any help is of course greatly appreciated.
I guess you already know, but the SDL_WINDOWID trick probably isn't portable - I am pretty sure it won't work on Mac. I am curious what you want SDL for, in this scenario - if you simply want a pixel-addressable image buffer (or several), use QPixmap / QImage and stick to pure Qt. Or if you want the SDL sprite features, I'd suggest having SDL composite to an in-memory buffer attached to a QImage, and then draw that to a Qt widget. (Or use QImages as sprites, and use the OpenGL QPainter backend)
Internally, Qt works pretty hard to use platform-native code to do image format conversion, so even though this sounds fairly copy-heavy, I think it will be sufficiently fast, and much more robust and portable than the SDL_WINDOWID trick.
So I think I got it to at least display something. After playing with the code for a little bit, I ended up commenting out the setAttribute methods at the top of the file and it seems to be working. Also, the setUpdatesEnabled method didn't seem to have an impact, so I removed that since I only had it in there when trying to get this to work.
Below is a picture of it in action. I don't yet have code to refresh the surface, so I have to select a menu option to draw it for now. It does appear that the menu bar is cutting top of the surface off, so I'll have to figure out how to reposition it later.
Hopefully, this helps someone.
SDL canvas http://img18.imageshack.us/img18/3453/nestsdl.png