summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Software/SWOGLWindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/Software/SWOGLWindow.cpp')
-rw-r--r--Source/Core/VideoBackends/Software/SWOGLWindow.cpp141
1 files changed, 141 insertions, 0 deletions
diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp
new file mode 100644
index 0000000000..c3a5d55941
--- /dev/null
+++ b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp
@@ -0,0 +1,141 @@
+// Copyright 2015 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Common/GL/GLInterfaceBase.h"
+#include "Common/GL/GLUtil.h"
+#include "Common/Logging/Log.h"
+
+#include "VideoBackends/Software/SWOGLWindow.h"
+
+std::unique_ptr<SWOGLWindow> SWOGLWindow::s_instance;
+
+void SWOGLWindow::Init(void *window_handle)
+{
+ InitInterface();
+ GLInterface->SetMode(GLInterfaceMode::MODE_DETECT);
+ if (!GLInterface->Create(window_handle, false))
+ {
+ INFO_LOG(VIDEO, "GLInterface::Create failed.");
+ }
+
+ s_instance.reset(new SWOGLWindow());
+}
+
+void SWOGLWindow::Shutdown()
+{
+ GLInterface->Shutdown();
+ delete GLInterface;
+ GLInterface = nullptr;
+
+ SWOGLWindow::s_instance.release();
+}
+
+void SWOGLWindow::Prepare()
+{
+ if (m_init) return;
+ m_init = true;
+
+ // Init extension support.
+ if (!GLExtensions::Init())
+ {
+ ERROR_LOG(VIDEO, "GLExtensions::Init failed!Does your video card support OpenGL 2.0?");
+ return;
+ }
+
+ static const char *fragShaderText =
+ "#ifdef GL_ES\n"
+ "precision highp float;\n"
+ "#endif\n"
+ "varying vec2 TexCoordOut;\n"
+ "uniform sampler2D Texture;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(Texture, TexCoordOut);\n"
+ "}\n";
+ static const char *vertShaderText =
+ "#ifdef GL_ES\n"
+ "precision highp float;\n"
+ "#endif\n"
+ "attribute vec4 pos;\n"
+ "attribute vec2 TexCoordIn;\n "
+ "varying vec2 TexCoordOut;\n "
+ "void main() {\n"
+ " gl_Position = pos;\n"
+ " TexCoordOut = TexCoordIn;\n"
+ "}\n";
+
+ m_image_program = OpenGL_CompileProgram(vertShaderText, fragShaderText);
+
+ glUseProgram(m_image_program);
+
+ m_uni_tex = glGetUniformLocation(m_image_program, "Texture");
+ m_attr_pos = glGetAttribLocation(m_image_program, "pos");
+ m_attr_tex = glGetAttribLocation(m_image_program, "TexCoordIn");
+
+ glUniform1i(m_uni_tex, 0);
+
+ glGenTextures(1, &m_image_texture);
+}
+
+void SWOGLWindow::PrintText(const std::string& text, int x, int y, u32 color)
+{
+ TextData data{text, x, y, color};
+ m_text.emplace_back(data);
+}
+
+void SWOGLWindow::ShowImage(u8* data, int stride, int width, int height, float aspect)
+{
+ GLInterface->MakeCurrent();
+ GLInterface->Update();
+ Prepare();
+
+ GLsizei glWidth = (GLsizei)GLInterface->GetBackBufferWidth();
+ GLsizei glHeight = (GLsizei)GLInterface->GetBackBufferHeight();
+
+ glViewport(0, 0, glWidth, glHeight);
+
+ glBindTexture(GL_TEXTURE_2D, m_image_texture);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment
+ //glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ glUseProgram(m_image_program);
+ static const GLfloat verts[4][2] = {
+ { -1, -1}, // Left top
+ { -1, 1}, // left bottom
+ { 1, 1}, // right bottom
+ { 1, -1} // right top
+ };
+ static const GLfloat texverts[4][2] = {
+ {0, 1},
+ {0, 0},
+ {1, 0},
+ {1, 1}
+ };
+
+ glVertexAttribPointer(m_attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts);
+ glVertexAttribPointer(m_attr_tex, 2, GL_FLOAT, GL_FALSE, 0, texverts);
+ glEnableVertexAttribArray(m_attr_pos);
+ glEnableVertexAttribArray(m_attr_tex);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ glDisableVertexAttribArray(m_attr_pos);
+ glDisableVertexAttribArray(m_attr_tex);
+
+// TODO: implement OSD
+// for (TextData& text : m_text)
+// {
+// }
+ m_text.clear();
+
+ GLInterface->Swap();
+ GLInterface->ClearCurrent();
+}
+
+int SWOGLWindow::PeekMessages()
+{
+ return GLInterface->PeekMessages();
+}
+