aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2019-06-03 16:45:55 +0200
committerArisotura <thetotalworm@gmail.com>2019-06-03 16:45:55 +0200
commit2b3ca2089f7420bb938c6bdda67ed0f8c04e51d5 (patch)
treef8edd3ff4dcbd16c694ac9c1fa69df1d9b2e916a
parent4a4415fc2ec067fb79881e17e14953b69ef80e0c (diff)
take the OSD shito somewhere
-rw-r--r--src/OpenGLSupport.h1
-rw-r--r--src/libui_sdl/OSD.cpp136
-rw-r--r--src/libui_sdl/main.cpp45
-rw-r--r--src/libui_sdl/main_shaders.h51
4 files changed, 190 insertions, 43 deletions
diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h
index 6130c8e..fbc100c 100644
--- a/src/OpenGLSupport.h
+++ b/src/OpenGLSupport.h
@@ -106,6 +106,7 @@
\
func(GLUNIFORM1I, glUniform1i); \
func(GLUNIFORM1UI, glUniform1ui); \
+ func(GLUNIFORM2I, glUniform2i); \
func(GLUNIFORM4UI, glUniform4ui); \
func(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); \
func(GLGETUNIFORMLOCATION, glGetUniformLocation); \
diff --git a/src/libui_sdl/OSD.cpp b/src/libui_sdl/OSD.cpp
index a13ff44..851f9c5 100644
--- a/src/libui_sdl/OSD.cpp
+++ b/src/libui_sdl/OSD.cpp
@@ -35,7 +35,7 @@ namespace OSD
const u32 kOSDMargin = 6;
-typedef struct
+struct Item
{
Uint32 Timestamp;
char Text[256];
@@ -50,13 +50,45 @@ typedef struct
bool GLTextureLoaded;
GLuint GLTexture;
-} Item;
+};
-std::deque<Item*> ItemQueue;
+std::deque<Item> ItemQueue;
+
+GLint uOSDPos, uOSDSize;
+GLuint OSDVertexArray;
+GLuint OSDVertexBuffer;
+
+volatile bool Rendering;
bool Init(bool opengl)
{
+ if (opengl)
+ {
+ GLuint prog; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&prog);
+ uOSDPos = glGetUniformLocation(prog, "uOSDPos");
+ uOSDSize = glGetUniformLocation(prog, "uOSDSize");
+
+ float vertices[6*2] =
+ {
+ 0, 0,
+ 1, 1,
+ 1, 0,
+ 0, 0,
+ 0, 1,
+ 1, 1
+ };
+
+ glGenBuffers(1, &OSDVertexBuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, OSDVertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+
+ glGenVertexArrays(1, &OSDVertexArray);
+ glBindVertexArray(OSDVertexArray);
+ glEnableVertexAttribArray(0); // position
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0));
+ }
+
return true;
}
@@ -64,15 +96,13 @@ void DeInit(bool opengl)
{
for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
{
- Item* item = *it;
-
- if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
- if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
- if (item->Bitmap) delete[] item->Bitmap;
+ Item& item = *it;
- delete item;
+ if (item.DrawBitmapLoaded && item.DrawBitmap) uiDrawFreeBitmap(item.DrawBitmap);
+ if (item.GLTextureLoaded && opengl) glDeleteTextures(1, &item.GLTexture);
+ if (item.Bitmap) delete[] item.Bitmap;
- ItemQueue.erase(it);
+ it = ItemQueue.erase(it);
}
}
@@ -276,15 +306,17 @@ void RenderText(u32 color, const char* text, Item* item)
void AddMessage(u32 color, const char* text)
{
- Item* item = new Item;
+ while (Rendering);
+
+ Item item;
- item->Timestamp = SDL_GetTicks();
- strncpy(item->Text, text, 255); item->Text[255] = '\0';
- item->Color = color;
- item->Bitmap = NULL;
+ item.Timestamp = SDL_GetTicks();
+ strncpy(item.Text, text, 255); item.Text[255] = '\0';
+ item.Color = color;
+ item.Bitmap = NULL;
- item->DrawBitmapLoaded = false;
- item->GLTextureLoaded = false;
+ item.DrawBitmapLoaded = false;
+ item.GLTextureLoaded = false;
ItemQueue.push_back(item);
}
@@ -293,7 +325,7 @@ void WindowResized(bool opengl)
{
/*for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
{
- Item* item = *it;
+ Item& item = *it;
if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
//if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
@@ -309,53 +341,83 @@ void WindowResized(bool opengl)
void Update(bool opengl, uiAreaDrawParams* params)
{
+ Rendering = true;
+
Uint32 tick_now = SDL_GetTicks();
Uint32 tick_min = tick_now - 2500;
u32 y = kOSDMargin;
+ if (opengl)
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, OSDVertexBuffer);
+ glBindVertexArray(OSDVertexArray);
+
+ glActiveTexture(GL_TEXTURE0);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
{
- Item* item = *it;
+ Item& item = *it;
- if (item->Timestamp < tick_min)
+ if (item.Timestamp < tick_min)
{
- if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
- if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
- if (item->Bitmap) delete[] item->Bitmap;
-
- delete item;
+ if (item.DrawBitmapLoaded && item.DrawBitmap) uiDrawFreeBitmap(item.DrawBitmap);
+ if (item.GLTextureLoaded && opengl) glDeleteTextures(1, &item.GLTexture);
+ if (item.Bitmap) delete[] item.Bitmap;
- ItemQueue.erase(it);
+ it = ItemQueue.erase(it);
continue;
}
- if (!item->Bitmap)
+ if (!item.Bitmap)
{
- RenderText(item->Color, item->Text, item);
+ RenderText(item.Color, item.Text, &item);
}
if (opengl)
{
- //
+ if (!item.GLTextureLoaded)
+ {
+ glGenTextures(1, &item.GLTexture);
+ glBindTexture(GL_TEXTURE_2D, item.GLTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, item.Width, item.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, item.Bitmap);
+
+ item.GLTextureLoaded = true;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, item.GLTexture);
+ glUniform2i(uOSDPos, kOSDMargin, y);
+ glUniform2i(uOSDSize, item.Width, item.Height);
+ glDrawArrays(GL_TRIANGLES, 0, 2*3);
}
else
{
- if (!item->DrawBitmapLoaded)
+ if (!item.DrawBitmapLoaded)
{
- item->DrawBitmap = uiDrawNewBitmap(params->Context, item->Width, item->Height, 1);
- uiDrawBitmapUpdate(item->DrawBitmap, item->Bitmap);
- item->DrawBitmapLoaded = true;
+ item.DrawBitmap = uiDrawNewBitmap(params->Context, item.Width, item.Height, 1);
+ uiDrawBitmapUpdate(item.DrawBitmap, item.Bitmap);
+
+ item.DrawBitmapLoaded = true;
}
- uiRect rc_src = {0, 0, item->Width, item->Height};
- uiRect rc_dst = {kOSDMargin, y, item->Width, item->Height};
+ uiRect rc_src = {0, 0, item.Width, item.Height};
+ uiRect rc_dst = {kOSDMargin, y, item.Width, item.Height};
- uiDrawBitmapDraw(params->Context, item->DrawBitmap, &rc_src, &rc_dst, 0);
+ uiDrawBitmapDraw(params->Context, item.DrawBitmap, &rc_src, &rc_dst, 0);
}
- y += item->Height;
+ y += item.Height;
it++;
}
+
+ Rendering = false;
}
}
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index 5407403..073c8ac 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -112,6 +112,7 @@ uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL};
GLuint GL_ScreenShader[3];
GLuint GL_ScreenShaderAccel[3];
+GLuint GL_ScreenShaderOSD[3];
struct
{
float uScreenSize[2];
@@ -198,6 +199,29 @@ bool GLScreen_InitShader(GLuint* shader, const char* fs)
return true;
}
+bool GLScreen_InitOSDShader(GLuint* shader)
+{
+ if (!OpenGL_BuildShaderProgram(kScreenVS_OSD, kScreenFS_OSD, shader, "ScreenShaderOSD"))
+ return false;
+
+ glBindAttribLocation(shader[2], 0, "vPosition");
+ glBindFragDataLocation(shader[2], 0, "oColor");
+
+ if (!OpenGL_LinkShaderProgram(shader))
+ return false;
+
+ GLuint uni_id;
+
+ uni_id = glGetUniformBlockIndex(shader[2], "uConfig");
+ glUniformBlockBinding(shader[2], uni_id, 16);
+
+ glUseProgram(shader[2]);
+ uni_id = glGetUniformLocation(shader[2], "OSDTex");
+ glUniform1i(uni_id, 0);
+
+ return true;
+}
+
bool GLScreen_Init()
{
// TODO: consider using epoxy?
@@ -213,6 +237,8 @@ bool GLScreen_Init()
return false;
if (!GLScreen_InitShader(GL_ScreenShaderAccel, kScreenFS_Accel))
return false;
+ if (!GLScreen_InitOSDShader(GL_ScreenShaderOSD))
+ return false;
memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig));
@@ -255,6 +281,7 @@ void GLScreen_DeInit()
OpenGL_DeleteShaderProgram(GL_ScreenShader);
OpenGL_DeleteShaderProgram(GL_ScreenShaderAccel);
+ OpenGL_DeleteShaderProgram(GL_ScreenShaderOSD);
}
void GLScreen_DrawScreen()
@@ -396,7 +423,7 @@ void GLScreen_DrawScreen()
else
OpenGL_UseShaderProgram(GL_ScreenShaderAccel);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, uiGLGetFramebuffer(GLContext));
+ glBindFramebuffer(GL_FRAMEBUFFER, uiGLGetFramebuffer(GLContext));
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
@@ -434,6 +461,7 @@ void GLScreen_DrawScreen()
glDrawArrays(GL_TRIANGLES, 0, 4*3);
}
+ OpenGL_UseShaderProgram(GL_ScreenShaderOSD);
OSD::Update(true, NULL);
glFlush();
@@ -947,19 +975,21 @@ int EmuThreadFunc(void* burp)
if (joybuttons) delete[] joybuttons;
+ if (Screen_UseGL) uiGLMakeContextCurrent(GLContext);
+
NDS::DeInit();
Platform::LAN_DeInit();
if (Screen_UseGL)
{
- uiGLMakeContextCurrent(GLContext);
OSD::DeInit(true);
GLScreen_DeInit();
- uiGLMakeContextCurrent(NULL);
}
else
OSD::DeInit(false);
+ if (Screen_UseGL) uiGLMakeContextCurrent(NULL);
+
return 44203;
}
@@ -1128,7 +1158,7 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt)
MicCommand |= 1;
if (evt->Scancode == 0x57) // F11
- OSD::AddMessage(0, "OSD test");
+ OSD::AddMessage(0x00FFFF, "OSD test");
//NDS::debug(0);
}
@@ -2302,6 +2332,11 @@ void CreateMainWindow(bool opengl)
{
uiGLMakeContextCurrent(GLContext);
if (!GLScreen_Init()) opengl_good = false;
+ if (opengl_good)
+ {
+ OpenGL_UseShaderProgram(GL_ScreenShaderOSD);
+ OSD::Init(true);
+ }
uiGLMakeContextCurrent(NULL);
}
@@ -2312,7 +2347,7 @@ void CreateMainWindow(bool opengl)
Screen_UseGL = false;
}
- OSD::Init(opengl);
+ if (!opengl) OSD::Init(false);
}
void DestroyMainWindow()
diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h
index f03931c..6504520 100644
--- a/src/libui_sdl/main_shaders.h
+++ b/src/libui_sdl/main_shaders.h
@@ -36,7 +36,7 @@ smooth out vec2 fTexcoord;
void main()
{
vec4 fpos;
- fpos.xy = ((vPosition.xy * 2.0) / uScreenSize) - 1.0;
+ fpos.xy = ((vPosition * 2.0) / uScreenSize) - 1.0;
fpos.y *= -1;
fpos.z = 0.0;
fpos.w = 1.0;
@@ -198,4 +198,53 @@ void main()
}
)";
+
+const char* kScreenVS_OSD = R"(#version 140
+
+layout(std140) uniform uConfig
+{
+ vec2 uScreenSize;
+ uint u3DScale;
+ uint uFilterMode;
+};
+
+uniform ivec2 uOSDPos;
+uniform ivec2 uOSDSize;
+
+in vec2 vPosition;
+
+smooth out vec2 fTexcoord;
+
+void main()
+{
+ vec4 fpos;
+
+ vec2 osdpos = (vPosition * vec2(uOSDSize));
+ fTexcoord = osdpos;
+ osdpos += uOSDPos;
+
+ fpos.xy = ((osdpos * 2.0) / uScreenSize) - 1.0;
+ fpos.y *= -1;
+ fpos.z = 0.0;
+ fpos.w = 1.0;
+
+ gl_Position = fpos;
+}
+)";
+
+const char* kScreenFS_OSD = R"(#version 140
+
+uniform sampler2D OSDTex;
+
+smooth in vec2 fTexcoord;
+
+out vec4 oColor;
+
+void main()
+{
+ vec4 pixel = texelFetch(OSDTex, ivec2(fTexcoord), 0);
+ oColor = pixel.bgra;
+}
+)";
+
#endif // MAIN_SHADERS_H