mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 21:57:57 +03:00
390 lines
No EOL
12 KiB
C++
390 lines
No EOL
12 KiB
C++
#if !defined(GLES_COMPATIBILITY)
|
|
#include "GSH_OpenGLQt_Framedebugger.h"
|
|
#endif
|
|
|
|
#include <QWindow>
|
|
#include <QOpenGLContext>
|
|
|
|
#if defined(GLES_COMPATIBILITY)
|
|
#include "GSH_OpenGLQt_Framedebugger.h"
|
|
#endif
|
|
|
|
#include <assert.h>
|
|
#include <sstream>
|
|
|
|
#ifdef GLES_COMPATIBILITY
|
|
#define GLSL_VERSION "#version 300 es"
|
|
#else
|
|
#define GLSL_VERSION "#version 150"
|
|
#endif
|
|
|
|
CGSH_OpenGLFramedebugger::CGSH_OpenGLFramedebugger(QWindow* renderWindow)
|
|
: m_renderWindow(renderWindow)
|
|
{
|
|
}
|
|
|
|
void CGSH_OpenGLFramedebugger::InitializeImpl()
|
|
{
|
|
m_context = new QOpenGLContext();
|
|
m_context->setFormat(m_renderWindow->requestedFormat());
|
|
|
|
bool succeeded = m_context->create();
|
|
Q_ASSERT(succeeded);
|
|
|
|
succeeded = m_context->makeCurrent(m_renderWindow);
|
|
Q_ASSERT(succeeded);
|
|
|
|
#ifdef USE_GLEW
|
|
glewExperimental = GL_TRUE;
|
|
auto result = glewInit();
|
|
Q_ASSERT(result == GLEW_OK);
|
|
//Clear any error that might rise from GLEW getting function pointers
|
|
#endif
|
|
glGetError();
|
|
|
|
#ifdef __WIN32__
|
|
if(wglSwapIntervalEXT)
|
|
{
|
|
wglSwapIntervalEXT(-1);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void CGSH_OpenGLFramedebugger::ReleaseImpl()
|
|
{
|
|
delete m_context;
|
|
}
|
|
|
|
void CGSH_OpenGLFramedebugger::Begin()
|
|
{
|
|
m_context->makeCurrent(m_renderWindow);
|
|
}
|
|
|
|
void CGSH_OpenGLFramedebugger::PresentBackbuffer()
|
|
{
|
|
if(m_renderWindow->isExposed())
|
|
{
|
|
m_context->swapBuffers(m_renderWindow);
|
|
m_context->makeCurrent(m_renderWindow);
|
|
}
|
|
}
|
|
|
|
void CGSH_OpenGLFramedebugger::PrepareFramedebugger()
|
|
{
|
|
|
|
m_vertexArray = GenerateVertexArray();
|
|
m_vertexBufferFramedebugger = GenerateVertexBuffer();
|
|
|
|
m_checkerboardProgram = GenerateCheckerboardProgram();
|
|
{
|
|
glEnableVertexAttribArray(0);
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, reinterpret_cast<const GLvoid*>(0)); // POSITON
|
|
|
|
m_checkerboardScreenSizeUniform = glGetUniformLocation(*m_checkerboardProgram, "g_screenSize");
|
|
}
|
|
|
|
m_pixelBufferViewProgram = GeneratePixelBufferViewProgram();
|
|
{
|
|
glEnableVertexAttribArray(0);
|
|
glEnableVertexAttribArray(1);
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, reinterpret_cast<const GLvoid*>(0)); // POSITON
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, reinterpret_cast<const GLvoid*>(sizeof(float) * 3)); // texCoord
|
|
|
|
m_pixelBufferViewScreenSizeUniform = glGetUniformLocation(*m_pixelBufferViewProgram, "g_screenSize");
|
|
m_pixelBufferViewBufferSizeUniform = glGetUniformLocation(*m_pixelBufferViewProgram, "g_bufferSize");
|
|
m_pixelBufferViewPanOffsetUniform = glGetUniformLocation(*m_pixelBufferViewProgram, "g_panOffset");
|
|
m_pixelBufferViewZoomFactorUniform = glGetUniformLocation(*m_pixelBufferViewProgram, "g_zoomFactor");
|
|
m_pixelBufferViewtextureUniform = glGetUniformLocation(*m_pixelBufferViewProgram, "g_bufferTextureSampler");
|
|
}
|
|
}
|
|
|
|
Framework::OpenGl::CVertexArray CGSH_OpenGLFramedebugger::GenerateVertexArray()
|
|
{
|
|
auto vertexArray = Framework::OpenGl::CVertexArray::Create();
|
|
glBindVertexArray(vertexArray);
|
|
|
|
CHECKGLERROR();
|
|
|
|
return vertexArray;
|
|
}
|
|
|
|
Framework::OpenGl::CBuffer CGSH_OpenGLFramedebugger::GenerateVertexBuffer()
|
|
{
|
|
auto buffer = Framework::OpenGl::CBuffer::Create();
|
|
|
|
// clang-format off
|
|
static float vertices[] =
|
|
{
|
|
1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
|
1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
|
|
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
|
|
|
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
|
-1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
|
|
1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
|
|
|
};
|
|
// clang-format on
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
|
|
|
CHECKGLERROR();
|
|
|
|
return buffer;
|
|
}
|
|
|
|
Framework::OpenGl::ProgramPtr CGSH_OpenGLFramedebugger::GenerateCheckerboardProgram()
|
|
{
|
|
auto vertexShader = GenerateCheckerboardVertexShader();
|
|
auto fragmentShader = GenerateCheckerboardFragmentShader();
|
|
|
|
auto result = std::make_shared<Framework::OpenGl::CProgram>();
|
|
|
|
result->AttachShader(vertexShader);
|
|
result->AttachShader(fragmentShader);
|
|
|
|
FRAMEWORK_MAYBE_UNUSED bool linkResult = result->Link();
|
|
assert(linkResult);
|
|
|
|
CHECKGLERROR();
|
|
|
|
return result;
|
|
}
|
|
|
|
Framework::OpenGl::CShader CGSH_OpenGLFramedebugger::GenerateCheckerboardVertexShader()
|
|
{
|
|
|
|
std::stringstream shaderBuilder;
|
|
shaderBuilder << GLSL_VERSION << std::endl;
|
|
shaderBuilder << "#extension GL_ARB_explicit_attrib_location : enable" << std::endl
|
|
<< std::endl;
|
|
|
|
shaderBuilder << "layout (location = 0) in vec3 g_position;" << std::endl;
|
|
shaderBuilder << "out vec2 a_texCoord;" << std::endl;
|
|
shaderBuilder << "uniform vec2 g_screenSize;" << std::endl;
|
|
|
|
shaderBuilder << "void main()" << std::endl;
|
|
shaderBuilder << "{" << std::endl;
|
|
shaderBuilder << " gl_Position = vec4(g_position, 1.0);" << std::endl;
|
|
shaderBuilder << " a_texCoord = ((g_position.xy + 1.0f) / 2.0f) * g_screenSize / 10.f;" << std::endl;
|
|
shaderBuilder << "}" << std::endl;
|
|
|
|
auto shaderSource = shaderBuilder.str();
|
|
|
|
Framework::OpenGl::CShader result(GL_VERTEX_SHADER);
|
|
result.SetSource(shaderSource.c_str(), shaderSource.size());
|
|
FRAMEWORK_MAYBE_UNUSED bool compilationResult = result.Compile();
|
|
assert(compilationResult);
|
|
|
|
CHECKGLERROR();
|
|
|
|
return result;
|
|
}
|
|
|
|
Framework::OpenGl::CShader CGSH_OpenGLFramedebugger::GenerateCheckerboardFragmentShader()
|
|
{
|
|
std::stringstream shaderBuilder;
|
|
|
|
shaderBuilder << GLSL_VERSION << std::endl
|
|
<< std::endl;
|
|
|
|
shaderBuilder << "precision mediump float;" << std::endl;
|
|
|
|
shaderBuilder << "out vec4 fragColor;" << std::endl;
|
|
shaderBuilder << "in vec2 a_texCoord;" << std::endl;
|
|
|
|
shaderBuilder << "float fmod(float x, float y) { return x - y * trunc(x/y); }" << std::endl;
|
|
shaderBuilder << "void main()" << std::endl;
|
|
shaderBuilder << "{" << std::endl;
|
|
|
|
shaderBuilder << " if(fmod(floor(a_texCoord.x) + floor(a_texCoord.y), 2.0) < 1.0)" << std::endl;
|
|
shaderBuilder << " {" << std::endl;
|
|
shaderBuilder << " fragColor = vec4(1, 1, 1, 1);" << std::endl;
|
|
shaderBuilder << " }" << std::endl;
|
|
shaderBuilder << " else" << std::endl;
|
|
shaderBuilder << " {" << std::endl;
|
|
shaderBuilder << " fragColor = vec4(0.75, 0.75, 0.75, 1.0);" << std::endl;
|
|
shaderBuilder << " }" << std::endl;
|
|
|
|
shaderBuilder << "}" << std::endl;
|
|
|
|
auto shaderSource = shaderBuilder.str();
|
|
|
|
Framework::OpenGl::CShader result(GL_FRAGMENT_SHADER);
|
|
result.SetSource(shaderSource.c_str(), shaderSource.size());
|
|
FRAMEWORK_MAYBE_UNUSED bool compilationResult = result.Compile();
|
|
assert(compilationResult);
|
|
|
|
CHECKGLERROR();
|
|
|
|
return result;
|
|
}
|
|
|
|
void CGSH_OpenGLFramedebugger::DrawCheckerboard(float* dim)
|
|
{
|
|
glViewport(0, 0, dim[0], dim[1]);
|
|
|
|
glUseProgram(*m_checkerboardProgram);
|
|
|
|
glBindVertexArray(m_vertexArray);
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferFramedebugger);
|
|
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
glUniform2f(m_checkerboardScreenSizeUniform, dim[0], dim[1]);
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
}
|
|
|
|
Framework::OpenGl::ProgramPtr CGSH_OpenGLFramedebugger::GeneratePixelBufferViewProgram()
|
|
{
|
|
auto vertexShader = GeneratePixelBufferViewVertexShader();
|
|
auto fragmentShader = GeneratePixelBufferViewFragmentShader();
|
|
|
|
auto result = std::make_shared<Framework::OpenGl::CProgram>();
|
|
|
|
result->AttachShader(vertexShader);
|
|
result->AttachShader(fragmentShader);
|
|
|
|
FRAMEWORK_MAYBE_UNUSED bool linkResult = result->Link();
|
|
assert(linkResult);
|
|
|
|
CHECKGLERROR();
|
|
|
|
return result;
|
|
}
|
|
|
|
Framework::OpenGl::CShader CGSH_OpenGLFramedebugger::GeneratePixelBufferViewVertexShader()
|
|
{
|
|
|
|
std::stringstream shaderBuilder;
|
|
shaderBuilder << GLSL_VERSION << std::endl
|
|
<< std::endl;
|
|
shaderBuilder << "#extension GL_ARB_explicit_attrib_location : enable" << std::endl
|
|
<< std::endl;
|
|
|
|
shaderBuilder << "layout (location = 0) in vec3 g_position;" << std::endl;
|
|
shaderBuilder << "layout (location = 1) in vec2 g_texCoord;" << std::endl;
|
|
shaderBuilder << "uniform vec2 g_screenSize;" << std::endl;
|
|
shaderBuilder << "uniform vec2 g_bufferSize;" << std::endl;
|
|
shaderBuilder << "uniform vec2 g_panOffset;" << std::endl;
|
|
shaderBuilder << "uniform float g_zoomFactor;" << std::endl;
|
|
shaderBuilder << "out vec2 a_texCoord;" << std::endl;
|
|
shaderBuilder << "" << std::endl;
|
|
shaderBuilder << "void main()" << std::endl;
|
|
shaderBuilder << "{" << std::endl;
|
|
shaderBuilder << " gl_Position = ((vec4(g_position, 1.0) * vec4(g_bufferSize / g_screenSize, 0, 1)) + vec4(g_panOffset, 0, 0)) * vec4(g_zoomFactor, g_zoomFactor, 0, 1);" << std::endl;
|
|
shaderBuilder << " a_texCoord = g_texCoord;" << std::endl;
|
|
shaderBuilder << "}" << std::endl;
|
|
|
|
auto shaderSource = shaderBuilder.str();
|
|
|
|
Framework::OpenGl::CShader result(GL_VERTEX_SHADER);
|
|
result.SetSource(shaderSource.c_str(), shaderSource.size());
|
|
FRAMEWORK_MAYBE_UNUSED bool compilationResult = result.Compile();
|
|
assert(compilationResult);
|
|
|
|
CHECKGLERROR();
|
|
|
|
return result;
|
|
}
|
|
|
|
Framework::OpenGl::CShader CGSH_OpenGLFramedebugger::GeneratePixelBufferViewFragmentShader()
|
|
{
|
|
std::stringstream shaderBuilder;
|
|
|
|
shaderBuilder << GLSL_VERSION << std::endl
|
|
<< std::endl;
|
|
|
|
shaderBuilder << "precision mediump float;" << std::endl;
|
|
|
|
shaderBuilder << "uniform sampler2D g_bufferTextureSampler;" << std::endl;
|
|
shaderBuilder << "in vec2 a_texCoord;" << std::endl;
|
|
shaderBuilder << "out vec4 fragColor;" << std::endl;
|
|
|
|
shaderBuilder << "void main()" << std::endl;
|
|
shaderBuilder << "{" << std::endl;
|
|
shaderBuilder << " fragColor = texture(g_bufferTextureSampler, a_texCoord);" << std::endl;
|
|
shaderBuilder << "}" << std::endl;
|
|
|
|
auto shaderSource = shaderBuilder.str();
|
|
|
|
Framework::OpenGl::CShader result(GL_FRAGMENT_SHADER);
|
|
result.SetSource(shaderSource.c_str(), shaderSource.size());
|
|
FRAMEWORK_MAYBE_UNUSED bool compilationResult = result.Compile();
|
|
assert(compilationResult);
|
|
|
|
CHECKGLERROR();
|
|
|
|
return result;
|
|
}
|
|
|
|
void CGSH_OpenGLFramedebugger::DrawPixelBuffer(float* screenSizeVector, float* bufferSizeVector, float panX, float panY, float zoomFactor)
|
|
{
|
|
if(m_activeTexture == -1)
|
|
return;
|
|
|
|
float panOffsetVector[2] = {panX, panY};
|
|
|
|
glUseProgram(*m_pixelBufferViewProgram);
|
|
glBindVertexArray(m_vertexArray);
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferFramedebugger);
|
|
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
glUniform2f(m_pixelBufferViewScreenSizeUniform, screenSizeVector[0], screenSizeVector[1]);
|
|
|
|
glUniform2f(m_pixelBufferViewBufferSizeUniform, bufferSizeVector[0], bufferSizeVector[1]);
|
|
glUniform2f(m_pixelBufferViewPanOffsetUniform, panOffsetVector[0], panOffsetVector[1]);
|
|
glUniform1f(m_pixelBufferViewZoomFactorUniform, zoomFactor);
|
|
|
|
glActiveTexture(GL_TEXTURE0 + 4);
|
|
glBindTexture(GL_TEXTURE_2D, m_activeTexture);
|
|
glUniform1i(m_pixelBufferViewtextureUniform, 4);
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
}
|
|
|
|
void CGSH_OpenGLFramedebugger::LoadTextureFromBitmap(const Framework::CBitmap& bitmap)
|
|
{
|
|
if(!bitmap.IsEmpty())
|
|
{
|
|
std::vector<GLint> textureFormat =
|
|
[bitmap]() -> std::vector<GLint> {
|
|
switch(bitmap.GetBitsPerPixel())
|
|
{
|
|
case 8:
|
|
return {GL_R8, GL_RED};
|
|
case 16:
|
|
return {GL_RGB5_A1, GL_BGRA};
|
|
case 32:
|
|
default:
|
|
return {GL_RGBA8, GL_BGRA};
|
|
}
|
|
}();
|
|
|
|
auto type = GL_UNSIGNED_BYTE;
|
|
if(bitmap.GetBitsPerPixel() == 16)
|
|
{
|
|
type = GL_UNSIGNED_SHORT_5_5_5_1;
|
|
}
|
|
glActiveTexture(GL_TEXTURE0 + 4);
|
|
glGenTextures(1, &m_activeTexture);
|
|
glBindTexture(GL_TEXTURE_2D, m_activeTexture);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, textureFormat[0], bitmap.GetWidth(), bitmap.GetHeight(), 0, textureFormat[1], type, bitmap.GetPixels());
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
if(bitmap.GetBitsPerPixel() == 8)
|
|
{
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
|
|
}
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
CHECKGLERROR();
|
|
}
|
|
} |