take the OSD shito somewhere
This commit is contained in:
parent
4a4415fc2e
commit
2b3ca2089f
|
@ -106,6 +106,7 @@
|
||||||
\
|
\
|
||||||
func(GLUNIFORM1I, glUniform1i); \
|
func(GLUNIFORM1I, glUniform1i); \
|
||||||
func(GLUNIFORM1UI, glUniform1ui); \
|
func(GLUNIFORM1UI, glUniform1ui); \
|
||||||
|
func(GLUNIFORM2I, glUniform2i); \
|
||||||
func(GLUNIFORM4UI, glUniform4ui); \
|
func(GLUNIFORM4UI, glUniform4ui); \
|
||||||
func(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); \
|
func(GLUNIFORMBLOCKBINDING, glUniformBlockBinding); \
|
||||||
func(GLGETUNIFORMLOCATION, glGetUniformLocation); \
|
func(GLGETUNIFORMLOCATION, glGetUniformLocation); \
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace OSD
|
||||||
|
|
||||||
const u32 kOSDMargin = 6;
|
const u32 kOSDMargin = 6;
|
||||||
|
|
||||||
typedef struct
|
struct Item
|
||||||
{
|
{
|
||||||
Uint32 Timestamp;
|
Uint32 Timestamp;
|
||||||
char Text[256];
|
char Text[256];
|
||||||
|
@ -50,13 +50,45 @@ typedef struct
|
||||||
bool GLTextureLoaded;
|
bool GLTextureLoaded;
|
||||||
GLuint GLTexture;
|
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)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,15 +96,13 @@ void DeInit(bool opengl)
|
||||||
{
|
{
|
||||||
for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
|
for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
|
||||||
{
|
{
|
||||||
Item* item = *it;
|
Item& item = *it;
|
||||||
|
|
||||||
if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
|
if (item.DrawBitmapLoaded && item.DrawBitmap) uiDrawFreeBitmap(item.DrawBitmap);
|
||||||
if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
|
if (item.GLTextureLoaded && opengl) glDeleteTextures(1, &item.GLTexture);
|
||||||
if (item->Bitmap) delete[] item->Bitmap;
|
if (item.Bitmap) delete[] item.Bitmap;
|
||||||
|
|
||||||
delete item;
|
it = ItemQueue.erase(it);
|
||||||
|
|
||||||
ItemQueue.erase(it);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,15 +306,17 @@ void RenderText(u32 color, const char* text, Item* item)
|
||||||
|
|
||||||
void AddMessage(u32 color, const char* text)
|
void AddMessage(u32 color, const char* text)
|
||||||
{
|
{
|
||||||
Item* item = new Item;
|
while (Rendering);
|
||||||
|
|
||||||
item->Timestamp = SDL_GetTicks();
|
Item item;
|
||||||
strncpy(item->Text, text, 255); item->Text[255] = '\0';
|
|
||||||
item->Color = color;
|
|
||||||
item->Bitmap = NULL;
|
|
||||||
|
|
||||||
item->DrawBitmapLoaded = false;
|
item.Timestamp = SDL_GetTicks();
|
||||||
item->GLTextureLoaded = false;
|
strncpy(item.Text, text, 255); item.Text[255] = '\0';
|
||||||
|
item.Color = color;
|
||||||
|
item.Bitmap = NULL;
|
||||||
|
|
||||||
|
item.DrawBitmapLoaded = false;
|
||||||
|
item.GLTextureLoaded = false;
|
||||||
|
|
||||||
ItemQueue.push_back(item);
|
ItemQueue.push_back(item);
|
||||||
}
|
}
|
||||||
|
@ -293,7 +325,7 @@ void WindowResized(bool opengl)
|
||||||
{
|
{
|
||||||
/*for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
|
/*for (auto it = ItemQueue.begin(); it != ItemQueue.end(); )
|
||||||
{
|
{
|
||||||
Item* item = *it;
|
Item& item = *it;
|
||||||
|
|
||||||
if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
|
if (item->DrawBitmapLoaded && item->DrawBitmap) uiDrawFreeBitmap(item->DrawBitmap);
|
||||||
//if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
|
//if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
|
||||||
|
@ -309,53 +341,83 @@ void WindowResized(bool opengl)
|
||||||
|
|
||||||
void Update(bool opengl, uiAreaDrawParams* params)
|
void Update(bool opengl, uiAreaDrawParams* params)
|
||||||
{
|
{
|
||||||
|
Rendering = true;
|
||||||
|
|
||||||
Uint32 tick_now = SDL_GetTicks();
|
Uint32 tick_now = SDL_GetTicks();
|
||||||
Uint32 tick_min = tick_now - 2500;
|
Uint32 tick_min = tick_now - 2500;
|
||||||
u32 y = kOSDMargin;
|
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(); )
|
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.DrawBitmapLoaded && item.DrawBitmap) uiDrawFreeBitmap(item.DrawBitmap);
|
||||||
if (item->GLTextureLoaded && opengl) glDeleteTextures(1, &item->GLTexture);
|
if (item.GLTextureLoaded && opengl) glDeleteTextures(1, &item.GLTexture);
|
||||||
if (item->Bitmap) delete[] item->Bitmap;
|
if (item.Bitmap) delete[] item.Bitmap;
|
||||||
|
|
||||||
delete item;
|
it = ItemQueue.erase(it);
|
||||||
|
|
||||||
ItemQueue.erase(it);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item->Bitmap)
|
if (!item.Bitmap)
|
||||||
{
|
{
|
||||||
RenderText(item->Color, item->Text, item);
|
RenderText(item.Color, item.Text, &item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opengl)
|
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
|
else
|
||||||
{
|
{
|
||||||
if (!item->DrawBitmapLoaded)
|
if (!item.DrawBitmapLoaded)
|
||||||
{
|
{
|
||||||
item->DrawBitmap = uiDrawNewBitmap(params->Context, item->Width, item->Height, 1);
|
item.DrawBitmap = uiDrawNewBitmap(params->Context, item.Width, item.Height, 1);
|
||||||
uiDrawBitmapUpdate(item->DrawBitmap, item->Bitmap);
|
uiDrawBitmapUpdate(item.DrawBitmap, item.Bitmap);
|
||||||
item->DrawBitmapLoaded = true;
|
|
||||||
|
item.DrawBitmapLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uiRect rc_src = {0, 0, item->Width, item->Height};
|
uiRect rc_src = {0, 0, item.Width, item.Height};
|
||||||
uiRect rc_dst = {kOSDMargin, y, 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++;
|
it++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rendering = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,7 @@ uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL};
|
||||||
|
|
||||||
GLuint GL_ScreenShader[3];
|
GLuint GL_ScreenShader[3];
|
||||||
GLuint GL_ScreenShaderAccel[3];
|
GLuint GL_ScreenShaderAccel[3];
|
||||||
|
GLuint GL_ScreenShaderOSD[3];
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
float uScreenSize[2];
|
float uScreenSize[2];
|
||||||
|
@ -198,6 +199,29 @@ bool GLScreen_InitShader(GLuint* shader, const char* fs)
|
||||||
return true;
|
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()
|
bool GLScreen_Init()
|
||||||
{
|
{
|
||||||
// TODO: consider using epoxy?
|
// TODO: consider using epoxy?
|
||||||
|
@ -213,6 +237,8 @@ bool GLScreen_Init()
|
||||||
return false;
|
return false;
|
||||||
if (!GLScreen_InitShader(GL_ScreenShaderAccel, kScreenFS_Accel))
|
if (!GLScreen_InitShader(GL_ScreenShaderAccel, kScreenFS_Accel))
|
||||||
return false;
|
return false;
|
||||||
|
if (!GLScreen_InitOSDShader(GL_ScreenShaderOSD))
|
||||||
|
return false;
|
||||||
|
|
||||||
memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig));
|
memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig));
|
||||||
|
|
||||||
|
@ -255,6 +281,7 @@ void GLScreen_DeInit()
|
||||||
|
|
||||||
OpenGL_DeleteShaderProgram(GL_ScreenShader);
|
OpenGL_DeleteShaderProgram(GL_ScreenShader);
|
||||||
OpenGL_DeleteShaderProgram(GL_ScreenShaderAccel);
|
OpenGL_DeleteShaderProgram(GL_ScreenShaderAccel);
|
||||||
|
OpenGL_DeleteShaderProgram(GL_ScreenShaderOSD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLScreen_DrawScreen()
|
void GLScreen_DrawScreen()
|
||||||
|
@ -396,7 +423,7 @@ void GLScreen_DrawScreen()
|
||||||
else
|
else
|
||||||
OpenGL_UseShaderProgram(GL_ScreenShaderAccel);
|
OpenGL_UseShaderProgram(GL_ScreenShaderAccel);
|
||||||
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, uiGLGetFramebuffer(GLContext));
|
glBindFramebuffer(GL_FRAMEBUFFER, uiGLGetFramebuffer(GLContext));
|
||||||
|
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
@ -434,6 +461,7 @@ void GLScreen_DrawScreen()
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 4*3);
|
glDrawArrays(GL_TRIANGLES, 0, 4*3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OpenGL_UseShaderProgram(GL_ScreenShaderOSD);
|
||||||
OSD::Update(true, NULL);
|
OSD::Update(true, NULL);
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
|
@ -947,19 +975,21 @@ int EmuThreadFunc(void* burp)
|
||||||
|
|
||||||
if (joybuttons) delete[] joybuttons;
|
if (joybuttons) delete[] joybuttons;
|
||||||
|
|
||||||
|
if (Screen_UseGL) uiGLMakeContextCurrent(GLContext);
|
||||||
|
|
||||||
NDS::DeInit();
|
NDS::DeInit();
|
||||||
Platform::LAN_DeInit();
|
Platform::LAN_DeInit();
|
||||||
|
|
||||||
if (Screen_UseGL)
|
if (Screen_UseGL)
|
||||||
{
|
{
|
||||||
uiGLMakeContextCurrent(GLContext);
|
|
||||||
OSD::DeInit(true);
|
OSD::DeInit(true);
|
||||||
GLScreen_DeInit();
|
GLScreen_DeInit();
|
||||||
uiGLMakeContextCurrent(NULL);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
OSD::DeInit(false);
|
OSD::DeInit(false);
|
||||||
|
|
||||||
|
if (Screen_UseGL) uiGLMakeContextCurrent(NULL);
|
||||||
|
|
||||||
return 44203;
|
return 44203;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1128,7 +1158,7 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt)
|
||||||
MicCommand |= 1;
|
MicCommand |= 1;
|
||||||
|
|
||||||
if (evt->Scancode == 0x57) // F11
|
if (evt->Scancode == 0x57) // F11
|
||||||
OSD::AddMessage(0, "OSD test");
|
OSD::AddMessage(0x00FFFF, "OSD test");
|
||||||
//NDS::debug(0);
|
//NDS::debug(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2302,6 +2332,11 @@ void CreateMainWindow(bool opengl)
|
||||||
{
|
{
|
||||||
uiGLMakeContextCurrent(GLContext);
|
uiGLMakeContextCurrent(GLContext);
|
||||||
if (!GLScreen_Init()) opengl_good = false;
|
if (!GLScreen_Init()) opengl_good = false;
|
||||||
|
if (opengl_good)
|
||||||
|
{
|
||||||
|
OpenGL_UseShaderProgram(GL_ScreenShaderOSD);
|
||||||
|
OSD::Init(true);
|
||||||
|
}
|
||||||
uiGLMakeContextCurrent(NULL);
|
uiGLMakeContextCurrent(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2312,7 +2347,7 @@ void CreateMainWindow(bool opengl)
|
||||||
Screen_UseGL = false;
|
Screen_UseGL = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSD::Init(opengl);
|
if (!opengl) OSD::Init(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestroyMainWindow()
|
void DestroyMainWindow()
|
||||||
|
|
|
@ -36,7 +36,7 @@ smooth out vec2 fTexcoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 fpos;
|
vec4 fpos;
|
||||||
fpos.xy = ((vPosition.xy * 2.0) / uScreenSize) - 1.0;
|
fpos.xy = ((vPosition * 2.0) / uScreenSize) - 1.0;
|
||||||
fpos.y *= -1;
|
fpos.y *= -1;
|
||||||
fpos.z = 0.0;
|
fpos.z = 0.0;
|
||||||
fpos.w = 1.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
|
#endif // MAIN_SHADERS_H
|
||||||
|
|
Loading…
Reference in New Issue