Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions project/Build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
<set name="tvos" value="1" if="appletv" />

<set name="LIME_CAIRO" value="1" />
<set name="LIME_CURL" value="1" unless="winrt" />
<set name="LIME_EFSW" value="1" if="windows || mac || linux" unless="winrt" />
<set name="LIME_CURL" value="1" unless="emscripten || winrt" />
<set name="LIME_EFSW" value="1" if="windows || mac || linux" unless="emscripten || winrt" />
<set name="LIME_JPEG" value="1" />
<!-- <set name="LIME_FAUDIO" value="1" /> -->
<set name="LIME_FREETYPE" value="1" />
Expand Down
82 changes: 82 additions & 0 deletions project/src/graphics/opengl/OpenGLBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,55 @@
#include <SDL.h>
#endif

#ifdef EMSCRIPTEN
#include <stdlib.h>
#include <string.h>
#endif


namespace lime {


#ifdef EMSCRIPTEN
#define LIME_GL_BGRA_EXT 0x80E1

static unsigned char* sRBSwapBuffer = NULL;
static size_t sRBSwapBufferSize = 0;

static const void* lime_gl_swap_rb (const void* src, size_t pixelCount) {

size_t bytes = pixelCount * 4;
if (bytes > sRBSwapBufferSize) {
free (sRBSwapBuffer);
sRBSwapBuffer = (unsigned char*) malloc (bytes);
sRBSwapBufferSize = bytes;
}
const unsigned char* s = (const unsigned char*) src;
unsigned char* d = sRBSwapBuffer;
for (size_t i = 0; i < bytes; i += 4) {
d[i] = s[i + 2];
d[i + 1] = s[i + 1];
d[i + 2] = s[i];
d[i + 3] = s[i + 3];
}
return sRBSwapBuffer;

}

static void lime_gl_swap_rb_in_place (void* dest, size_t pixelCount) {

unsigned char* d = (unsigned char*) dest;
size_t bytes = pixelCount * 4;
for (size_t i = 0; i < bytes; i += 4) {
unsigned char tmp = d[i];
d[i] = d[i + 2];
d[i + 2] = tmp;
}

}
#endif


bool OpenGLBindings::initialized = false;

int OpenGLBindings::defaultFramebuffer = 0;
Expand Down Expand Up @@ -4004,6 +4049,17 @@ namespace lime {

void lime_gl_read_pixels (int x, int y, int width, int height, int format, int type, double pixels) {

#ifdef EMSCRIPTEN
if (format == LIME_GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) {
void* dest = (void*) (uintptr_t) pixels;
if (dest != NULL && width > 0 && height > 0) {
glReadPixels (x, y, width, height, GL_RGBA, type, dest);
lime_gl_swap_rb_in_place (dest, (size_t) width * (size_t) height);
return;
}
}
#endif

glReadPixels (x, y, width, height, format, type, (void*)(uintptr_t)pixels);

}
Expand Down Expand Up @@ -4281,6 +4337,21 @@ namespace lime {

void lime_gl_tex_image_2d (int target, int level, int internalformat, int width, int height, int border, int format, int type, double data) {

#ifdef EMSCRIPTEN
if (format == LIME_GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) {
const void* src = (const void*) (uintptr_t) data;
GLint internalRGBA = (internalformat == LIME_GL_BGRA_EXT) ? GL_RGBA : internalformat;
if (src != NULL && width > 0 && height > 0) {
const void* swapped = lime_gl_swap_rb (src, (size_t) width * (size_t) height);
glTexImage2D (target, level, internalRGBA, width, height, border, GL_RGBA, type, swapped);
} else {
glTexImage2D (target, level, internalRGBA, width, height, border, GL_RGBA, type, NULL);
}
return;
}
if (internalformat == LIME_GL_BGRA_EXT) internalformat = GL_RGBA;
#endif

glTexImage2D (target, level, internalformat, width, height, border, format, type, (void*)(uintptr_t)data);

}
Expand Down Expand Up @@ -4377,6 +4448,17 @@ namespace lime {

void lime_gl_tex_sub_image_2d (int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, double data) {

#ifdef EMSCRIPTEN
if (format == LIME_GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) {
const void* src = (const void*) (uintptr_t) data;
if (src != NULL && width > 0 && height > 0) {
const void* swapped = lime_gl_swap_rb (src, (size_t) width * (size_t) height);
glTexSubImage2D (target, level, xoffset, yoffset, width, height, GL_RGBA, type, swapped);
return;
}
}
#endif

glTexSubImage2D (target, level, xoffset, yoffset, width, height, format, type, (void*)(uintptr_t)data);

}
Expand Down
50 changes: 50 additions & 0 deletions src/lime/_internal/backend/emscripten/EmscriptenFetch.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package lime._internal.backend.emscripten;

#if emscripten
import cpp.Star;
import cpp.Pointer;
import cpp.ConstCharStar;

@:include("emscripten/fetch.h")
@:native
extern class EmscriptenFetch {

@:native("emscripten_fetch_attr_init")
public static function emscripten_fetch_attr_init(attr:Pointer<EmscriptenFetchAttrType>):Void;

@:native("emscripten_fetch")
public static function emscripten_fetch(attr:Pointer<EmscriptenFetchAttrType>, url:ConstCharStar):Pointer<EmscriptenFetchType>;

@:native("emscripten_fetch_close")
public static function emscripten_fetch_close(fetch:Pointer<EmscriptenFetchType>):Void;
}

@:include("emscripten/fetch.h")
@:native("emscripten_fetch_attr_t")
@:structAccess
@:unreflective
extern class EmscriptenFetchAttrType {
public var requestMethod:ConstCharStar;
public var onsuccess:Star<EmscriptenFetchType>->Void;
public var onprogress:Star<EmscriptenFetchType>->Void;
public var onerror:Star<EmscriptenFetchType>->Void;
public var attributes:Int;
public var userData:Star<cpp.Void>;
}

@:include("emscripten/fetch.h")
@:native("emscripten_fetch_t")
@:structAccess
extern class EmscriptenFetchType {
public var id:Int;
public var numBytes:Int;
public var dataOffset:Int;
public var totalBytes:Int;
public var url:ConstCharStar;
public var readyState:Int;
public var status:Int;
public var statusText:ConstCharStar;
public var data:Pointer<cpp.UInt8>;
public var userData:Star<cpp.Void>;
}
#end
Loading
Loading