diff --git a/Source/Core/Common/GL/GLUtil.cpp b/Source/Core/Common/GL/GLUtil.cpp index ece39e5a61..7f7161aab4 100644 --- a/Source/Core/Common/GL/GLUtil.cpp +++ b/Source/Core/Common/GL/GLUtil.cpp @@ -16,7 +16,7 @@ void InitInterface() GLInterface = HostGL_CreateGLInterface(); } -GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShader) +GLuint OpenGL_CompileProgram(const std::string& vertexShader, const std::string& fragmentShader) { // generate objects GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); @@ -24,7 +24,8 @@ GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShade GLuint programID = glCreateProgram(); // compile vertex shader - glShaderSource(vertexShaderID, 1, &vertexShader, nullptr); + const char* shader = vertexShader.c_str(); + glShaderSource(vertexShaderID, 1, &shader, nullptr); glCompileShader(vertexShaderID); #if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL) GLint Result = GL_FALSE; @@ -35,22 +36,23 @@ GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShade if (Result && stringBufferUsage) { - ERROR_LOG(VIDEO, "GLSL vertex shader warnings:\n%s%s", stringBuffer, vertexShader); + ERROR_LOG(VIDEO, "GLSL vertex shader warnings:\n%s%s", stringBuffer, vertexShader.c_str()); } else if (!Result) { - ERROR_LOG(VIDEO, "GLSL vertex shader error:\n%s%s", stringBuffer, vertexShader); + ERROR_LOG(VIDEO, "GLSL vertex shader error:\n%s%s", stringBuffer, vertexShader.c_str()); } else { - DEBUG_LOG(VIDEO, "GLSL vertex shader compiled:\n%s", vertexShader); + DEBUG_LOG(VIDEO, "GLSL vertex shader compiled:\n%s", vertexShader.c_str()); } bool shader_errors = !Result; #endif // compile fragment shader - glShaderSource(fragmentShaderID, 1, &fragmentShader, nullptr); + shader = fragmentShader.c_str(); + glShaderSource(fragmentShaderID, 1, &shader, nullptr); glCompileShader(fragmentShaderID); #if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL) glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &Result); @@ -58,15 +60,15 @@ GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShade if (Result && stringBufferUsage) { - ERROR_LOG(VIDEO, "GLSL fragment shader warnings:\n%s%s", stringBuffer, fragmentShader); + ERROR_LOG(VIDEO, "GLSL fragment shader warnings:\n%s%s", stringBuffer, fragmentShader.c_str()); } else if (!Result) { - ERROR_LOG(VIDEO, "GLSL fragment shader error:\n%s%s", stringBuffer, fragmentShader); + ERROR_LOG(VIDEO, "GLSL fragment shader error:\n%s%s", stringBuffer, fragmentShader.c_str()); } else { - DEBUG_LOG(VIDEO, "GLSL fragment shader compiled:\n%s", fragmentShader); + DEBUG_LOG(VIDEO, "GLSL fragment shader compiled:\n%s", fragmentShader.c_str()); } shader_errors |= !Result; @@ -82,11 +84,11 @@ GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShade if (Result && stringBufferUsage) { - ERROR_LOG(VIDEO, "GLSL linker warnings:\n%s%s%s", stringBuffer, vertexShader, fragmentShader); + ERROR_LOG(VIDEO, "GLSL linker warnings:\n%s%s%s", stringBuffer, vertexShader.c_str(), fragmentShader.c_str()); } else if (!Result && !shader_errors) { - ERROR_LOG(VIDEO, "GLSL linker error:\n%s%s%s", stringBuffer, vertexShader, fragmentShader); + ERROR_LOG(VIDEO, "GLSL linker error:\n%s%s%s", stringBuffer, vertexShader.c_str(), fragmentShader.c_str()); } #endif diff --git a/Source/Core/Common/GL/GLUtil.h b/Source/Core/Common/GL/GLUtil.h index 1c3a9d8256..718ee225da 100644 --- a/Source/Core/Common/GL/GLUtil.h +++ b/Source/Core/Common/GL/GLUtil.h @@ -4,6 +4,8 @@ #pragma once +#include + #include "Common/GL/GLExtensions/GLExtensions.h" #ifndef _WIN32 @@ -14,7 +16,7 @@ void InitInterface(); // Helpers -GLuint OpenGL_CompileProgram(const char *vertexShader, const char *fragmentShader); +GLuint OpenGL_CompileProgram(const std::string& vertexShader, const std::string& fragmentShader); // Creates and deletes a VAO and VBO suitable for attributeless rendering. // Called by the Renderer. diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp index c3a5d55941..be4ee68e32 100644 --- a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp +++ b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp @@ -14,7 +14,7 @@ void SWOGLWindow::Init(void *window_handle) { InitInterface(); GLInterface->SetMode(GLInterfaceMode::MODE_DETECT); - if (!GLInterface->Create(window_handle, false)) + if (!GLInterface->Create(window_handle)) { INFO_LOG(VIDEO, "GLInterface::Create failed."); } @@ -42,39 +42,47 @@ void SWOGLWindow::Prepare() ERROR_LOG(VIDEO, "GLExtensions::Init failed!Does your video card support OpenGL 2.0?"); return; } + else if (GLExtensions::Version() < 310) + { + ERROR_LOG(VIDEO, "OpenGL Version %d detected, but at least 3.1 is required.", GLExtensions::Version()); + return; + } - static const char *fragShaderText = - "#ifdef GL_ES\n" - "precision highp float;\n" - "#endif\n" - "varying vec2 TexCoordOut;\n" + std::string frag_shader = + "in vec2 TexCoord;\n" + "out vec4 ColorOut;\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" + " ColorOut = texture2D(Texture, TexCoord);\n" "}\n"; - m_image_program = OpenGL_CompileProgram(vertShaderText, fragShaderText); + std::string vertex_shader = + "out vec2 TexCoord;\n" + "void main() {\n" + " vec2 rawpos = vec2(gl_VertexID & 1, (gl_VertexID & 2) >> 1);\n" + " gl_Position = vec4(rawpos * 2.0 - 1.0, 0.0, 1.0);\n" + " TexCoord = vec2(rawpos.x, -rawpos.y);\n" + "}\n"; + + std::string header = + GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL ? + "#version 140\n" + : + "#version 300 es\n" + "precision highp float;\n"; + + m_image_program = OpenGL_CompileProgram(header + vertex_shader, header + frag_shader); 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); + glUniform1i(glGetUniformLocation(m_image_program, "Texture"), 0); glGenTextures(1, &m_image_texture); + glBindTexture(GL_TEXTURE_2D, m_image_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glGenVertexArrays(1, &m_image_vao); } void SWOGLWindow::PrintText(const std::string& text, int x, int y, u32 color) @@ -97,32 +105,13 @@ void SWOGLWindow::ShowImage(u8* data, int stride, int width, int height, float a glBindTexture(GL_TEXTURE_2D, m_image_texture); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment - //glPixelStorei(GL_UNPACK_ROW_LENGTH, stride); + glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / 4); 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); + glBindVertexArray(m_image_vao); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // TODO: implement OSD // for (TextData& text : m_text) diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.h b/Source/Core/VideoBackends/Software/SWOGLWindow.h index 7a38d9b155..8be58c2e66 100644 --- a/Source/Core/VideoBackends/Software/SWOGLWindow.h +++ b/Source/Core/VideoBackends/Software/SWOGLWindow.h @@ -41,6 +41,5 @@ private: bool m_init {false}; - u32 m_image_program, m_image_texture; - int m_attr_pos, m_attr_tex, m_uni_tex; + u32 m_image_program, m_image_texture, m_image_vao; };