Emscripten call to SDL_Init freezes Browser Textinput - sdl

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;

Related

Drawing antialiased primitives to bitmap Allegro 5

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

SDL_Renderer: OpenGL texture just won't stick [duplicate]

I have been learning about SDL 2D programming for a while and now I wanted to create a program using SDL and OpenGL combined. I set it up like this:
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("SDL and OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
context = SDL_GL_CreateContext(window);
The program is for now just a black window with a white line displayed using OpenGl. Here is the code for the rendering:
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2d(1, 0);
glVertex2d(-1, 0);
glEnd();
SDL_GL_SwapWindow(window);
So the thing is, I would like to render textures additionally using pure SDL and a SDL_Renderer object, as I did before without OpenGL. I tried that out but it didn't work. Is it even possible to do that and how? What I did is creating a SDL_Renderer and then after drawing OpenGL stuff doing this:
SDL_Rect fillRect;
fillRect.w = 50;
fillRect.h = 50;
fillRect.x = 0;
fillRect.y = 0;
SDL_SetRenderDrawColor(renderer, 100, 200, 100, 0);
SDL_RenderFillRect(renderer, &fillRect);
SDL_RenderPresent(renderer);
But this does not work. The rectangle is not shown, although for some milliseconds it appears slightly. I feel like the OpenGL rendering is overwriting it.
SDL uses OpenGL (or in some cases Direct3D) and OpenGL has internal state which affects the GL calls in your program. The current version of SDL does not clearly indicate which states it changes or depends upon for any call and it does not include functions to reset to a known state. That means you should not mix SDL_Renderer with OpenGL yet.
However, if you really want this functionality now, you can try SDL_gpu (note: I'm the author). It does support mixing with OpenGL calls and custom shaders. You would want to specify which version of the OpenGL API you need (e.g. with GPU_InitRenderer(GPU_RENDERER_OPENGL_1, ...)) and reset the GL state that SDL_gpu uses each frame (GPU_ResetRendererState()). Check out the 3d demo in the SDL_gpu source repository for more.
https://github.com/grimfang4/sdl-gpu/blob/master/demos/3d/main.c
You can render to an SDL_Surface with SDL, and then convert it to a texture & upload it to the GPU using OpenGL.
Example code: http://www.sdltutorials.com/sdl-tip-sdl-surface-to-opengl-texture

LPDIRECT3DDEVICE9 clear alpha not working in multi-script project

I've created a Direct3D Device and have a render loop that starts with clearing the window to transparent red using the following code:
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(100, 255, 0, 0), 1.0f, 0);
This works perfectly, but only when it's created in the entry point script for some reason. When trying to do the exact same thing in a different script and creating the Direct3D window inside a function called by my entry point script's WinMain, the alpha channel of the Direct3D fails and it shows plain red. The WindowProc functions are both the same for the single-script Direct3D window and the multiple-scripts one.
I hope there are some thing I could check without the need of posting the code here, but if needed I am able to create minimal versions of the two to post.
Any help is very much appreciated!

Fullscreening a window in SDL2 with openGL

My program starts with a loading window while it is compiling shaders, loading textures etc. I then want to be able to launch a fullscreen application and use these resources. My understanding is that the openGL context must be the same before and after. I tried two methods for this: first of all I tried making a second window which was fullscreen, and used the SDL_GL_makecurrent command on this window to 'transfer' the context across (couldn't find where I read about this method), and secondly tried just fullscreening the loading window. Both of these methods resulted in the loading screen being moved to the top left corner of the screen. However opengl commands no longer ran properly in fullscreen, including clearing buffers which meant that the window contained the contents of my desktop/background applications.
Is there a proper way of doing this? Or is this a strange bug in sdl/opengl drivers?
Code to fullscreen original window:
//opengl commands work fine up to here
//now to fullscreen
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL_SetWindowSize(window, 1366, 768); //tried this on either side of line above and without either line
glViewport(0, 0, 1366, 768); //update viewport
glClearColor(1, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
//window should be whited, other draw commands tried and all fail or distort
SDL_GL_SwapWindow(window);
Creating a new window and using previous context:
//Fine up to here
window2 = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1366, 768, SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_SHOWN);
SDL_GL_MakeCurrent(window2, glContext); //created with SDL_GL_CreateContext(oldwindow);
//draw commands dont work
PS: running ubuntu
Update: In the second code, reusing the context in a new window, it returns an error saying 'invalid window' when it fails, which is most of the time but not always. When it fails, the screen ends up completely corrupted(black with weird white squares and patterns), ending the program will not clear the screen of this (although screenshots are perfectly fine?), but it can be restored by ctrl+f1 to terminal then ctrl+f7 back
I dont really know if its a bug. I experienced the same issue with sdl2 and opengl.
Create an regular window
attach to opengl context.
fullscreen
BOOM. black screen and crashed window.
I only noticed that issue in ubuntu.
Trought some tests i found a quick way to fix it:
Uint32 flags = 0;
flags |= SDL_WINDOW_RESIZABLE;
//bla bla bla your tags
flags |= SDL_WINDOW_OPENGL;
m_window = SDL_CreateWindow( "hello gl", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_screen.x, m_screen.y,flags);
m_glContext = SDL_GL_CreateContext(m_window);
//Set right the way the screen to fullscrene false
SDL_SetWindowFullscreen(m_window, SDL_FALSE);
Now the fullscreen seems to work without problem.

Allegro bitmap commands return black screen

I am a beginner at allegro and c++. I am trying to use the bitmap commands. I used this simple program to test it:
#include <allegro.h>
BITMAP *red;
int main(){
allegro_init();
install_keyboard();
set_color_depth(32);
set_gfx_mode( GFX_AUTODETECT, 640, 480, 0, 0);
red = load_bitmap( "frago.png", NULL);
acquire_screen();
blit(red, screen, 0, 0, 0, 0, 480, 360);
release_screen();
readkey();
destroy_bitmap(red);
return 0;
}
END_OF_MAIN();
The file "frago.png" in question is located on my desktop and is a big red rectangle. The color is supported in color depth 32. I am using Xcode 4 on a Mac. Can someone help me?
Allegro library cannot read .png files by default. You must use some other libraries/addons (libpng, zlib, loadpng). loadpng is bundled with Allegro from version 4.3.10, but you need libpng and zlib installed in your compiler.
You must use register_png_file_type() before load_bitmap().
The loadpng addon of Allegro 4.4 is included in its source code:
https://alleg.svn.sourceforge.net/svnroot/alleg/allegro/branches/4.4/addons/loadpng/
If the PNG is 8bpp image, remember to load its color palette:
PALETTE palette;
BITMAP* red = load_bitmap("frago.png", palette);
select_palette(palette);
blit(red, screen, 0, 0, 0, 0, red->w, red->h);
unselect_palette();
Anyway I think Allegro should convert your image to 32bpp automatically, try using set_color_conversion before load_bitmap() just in case:
set_color_conversion(COLORCONV_TOTAL);
Finally you could try to use load_png() function directly (replace load_bitmap with load_png).
If the program is not running in the same folder as the image, it will not find the image.
For example, if the program is running in c:\temp\MyProgram\, the image should be located in this same folder.
Also, some IDEs allow you to specify the folder that the program will run when running or debugging from the IDE, you can set this path to your desktop or copy the image to the program folder.
Another option is to specify the full image path in the load_bitmap call, but this is the worst solution in my opinion, because the program will only works when the image is exactly in this location.
Also I suggest adding a check for null:
red = load_bitmap("frago.png", NULL);
if(red == NULL)
{
printf("Cannot load frago.png\n");
return 0;
}