Update src/RenderDevice.cpp
This commit is contained in:
@@ -1,13 +1,23 @@
|
|||||||
|
/*
|
||||||
|
RenderDevice — Inverse Interactive
|
||||||
|
Homepage: https://dock-it.dev/Inverse-Interactive/RenderDevice
|
||||||
|
License: Creative Commons Attribution-ShareAlike 4.0 International
|
||||||
|
SPDX-License-Identifier: CC-BY-SA-4.0
|
||||||
|
Full License Text: https://dock-it.dev/Inverse-Interactive/RenderDevice/raw/branch/main/LICENSE
|
||||||
|
Copyright (c) Inverse Interactive
|
||||||
|
|
||||||
|
You are free to share and adapt this work under the terms of CC BY-SA 4.0.
|
||||||
|
Provide appropriate credit and distribute derivatives under the same license.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
#include "RenderDevice.h"
|
#include "RenderDevice.h"
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace PF
|
|
||||||
{
|
|
||||||
static GLenum ToGL(RenderDevice::Compare f)
|
static GLenum ToGL(RenderDevice::Compare f)
|
||||||
{
|
{
|
||||||
switch (f)
|
switch (f) {
|
||||||
{
|
|
||||||
case RenderDevice::Compare::Never:
|
case RenderDevice::Compare::Never:
|
||||||
return GL_NEVER;
|
return GL_NEVER;
|
||||||
case RenderDevice::Compare::Less:
|
case RenderDevice::Compare::Less:
|
||||||
@@ -30,8 +40,7 @@ namespace PF
|
|||||||
|
|
||||||
static GLenum ToGL(RenderDevice::CullFace c)
|
static GLenum ToGL(RenderDevice::CullFace c)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
|
||||||
case RenderDevice::CullFace::Back:
|
case RenderDevice::CullFace::Back:
|
||||||
return GL_BACK;
|
return GL_BACK;
|
||||||
case RenderDevice::CullFace::Front:
|
case RenderDevice::CullFace::Front:
|
||||||
@@ -46,7 +55,7 @@ namespace PF
|
|||||||
|
|
||||||
static GLenum ToGL(RenderDevice::IndexType t)
|
static GLenum ToGL(RenderDevice::IndexType t)
|
||||||
{
|
{
|
||||||
using PF::RenderDevice;
|
using CX::RenderDevice;
|
||||||
return (t == RenderDevice::IndexType::U16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
|
return (t == RenderDevice::IndexType::U16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,8 +63,7 @@ namespace PF
|
|||||||
|
|
||||||
static GLenum ToGL(RenderDevice::BlendFactor f)
|
static GLenum ToGL(RenderDevice::BlendFactor f)
|
||||||
{
|
{
|
||||||
switch (f)
|
switch (f) {
|
||||||
{
|
|
||||||
case RenderDevice::BlendFactor::Zero:
|
case RenderDevice::BlendFactor::Zero:
|
||||||
return GL_ZERO;
|
return GL_ZERO;
|
||||||
case RenderDevice::BlendFactor::One:
|
case RenderDevice::BlendFactor::One:
|
||||||
@@ -82,8 +90,7 @@ namespace PF
|
|||||||
|
|
||||||
static GLenum ToGL(RenderDevice::DrawMode m)
|
static GLenum ToGL(RenderDevice::DrawMode m)
|
||||||
{
|
{
|
||||||
switch (m)
|
switch (m) {
|
||||||
{
|
|
||||||
case RenderDevice::DrawMode::Triangles:
|
case RenderDevice::DrawMode::Triangles:
|
||||||
return GL_TRIANGLES;
|
return GL_TRIANGLES;
|
||||||
case RenderDevice::DrawMode::Lines:
|
case RenderDevice::DrawMode::Lines:
|
||||||
@@ -105,8 +112,7 @@ namespace PF
|
|||||||
|
|
||||||
static GLenum ToGL(RenderDevice::Usage u)
|
static GLenum ToGL(RenderDevice::Usage u)
|
||||||
{
|
{
|
||||||
switch (u)
|
switch (u) {
|
||||||
{
|
|
||||||
case RenderDevice::Usage::StreamDraw:
|
case RenderDevice::Usage::StreamDraw:
|
||||||
return GL_STREAM_DRAW;
|
return GL_STREAM_DRAW;
|
||||||
case RenderDevice::Usage::StaticDraw:
|
case RenderDevice::Usage::StaticDraw:
|
||||||
@@ -119,7 +125,6 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::_refreshGPUInfo()
|
void RenderDevice::_refreshGPUInfo()
|
||||||
{
|
{
|
||||||
|
|
||||||
const char *v = reinterpret_cast<const char *>(glGetString(GL_VENDOR));
|
const char *v = reinterpret_cast<const char *>(glGetString(GL_VENDOR));
|
||||||
const char *r = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
|
const char *r = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
|
||||||
const char *ver = reinterpret_cast<const char *>(glGetString(GL_VERSION));
|
const char *ver = reinterpret_cast<const char *>(glGetString(GL_VERSION));
|
||||||
@@ -133,12 +138,10 @@ namespace PF
|
|||||||
GLint major = 0, minor = 0;
|
GLint major = 0, minor = 0;
|
||||||
m_activeDevice->GetIntegerv(PName::MajorVersion, &major);
|
m_activeDevice->GetIntegerv(PName::MajorVersion, &major);
|
||||||
m_activeDevice->GetIntegerv(PName::MinorVersion, &minor);
|
m_activeDevice->GetIntegerv(PName::MinorVersion, &minor);
|
||||||
if (major == 0 && !m_gpu.version.empty())
|
if (major == 0 && !m_gpu.version.empty()) {
|
||||||
{
|
|
||||||
// naive parse: "3.3.0 XXX"
|
// naive parse: "3.3.0 XXX"
|
||||||
int M = 0, m = 0;
|
int M = 0, m = 0;
|
||||||
if (std::sscanf(m_gpu.version.c_str(), "%d.%d", &M, &m) == 2)
|
if (std::sscanf(m_gpu.version.c_str(), "%d.%d", &M, &m) == 2) {
|
||||||
{
|
|
||||||
major = M;
|
major = M;
|
||||||
minor = m;
|
minor = m;
|
||||||
}
|
}
|
||||||
@@ -149,9 +152,7 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::Init()
|
void RenderDevice::Init()
|
||||||
{
|
{
|
||||||
|
if (m_activeDevice) {
|
||||||
if (m_activeDevice)
|
|
||||||
{
|
|
||||||
m_lastError = DeviceErrors::DeviceAlreadyCreated;
|
m_lastError = DeviceErrors::DeviceAlreadyCreated;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -161,10 +162,9 @@ namespace PF
|
|||||||
glewExperimental = true;
|
glewExperimental = true;
|
||||||
GLenum err = glewInit();
|
GLenum err = glewInit();
|
||||||
glGetError();
|
glGetError();
|
||||||
if (err != GLEW_OK)
|
if (err != GLEW_OK) {
|
||||||
{
|
|
||||||
m_lastError = DeviceErrors::glewInitFailed;
|
m_lastError = DeviceErrors::glewInitFailed;
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
@@ -195,8 +195,7 @@ namespace PF
|
|||||||
static bool s_hasTimer = false;
|
static bool s_hasTimer = false;
|
||||||
static bool s_hasTimer64 = false;
|
static bool s_hasTimer64 = false;
|
||||||
|
|
||||||
if (!s_checked)
|
if (!s_checked) {
|
||||||
{
|
|
||||||
s_hasTimer = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query || GLEW_EXT_timer_query);
|
s_hasTimer = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query || GLEW_EXT_timer_query);
|
||||||
s_hasTimer64 = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query);
|
s_hasTimer64 = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query);
|
||||||
s_checked = true;
|
s_checked = true;
|
||||||
@@ -204,15 +203,13 @@ namespace PF
|
|||||||
if (!s_hasTimer)
|
if (!s_hasTimer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_frameTimerQuery == 0)
|
if (m_frameTimerQuery == 0) {
|
||||||
{
|
|
||||||
glGenQueries(1, &m_frameTimerQuery);
|
glGenQueries(1, &m_frameTimerQuery);
|
||||||
if (m_frameTimerQuery == 0)
|
if (m_frameTimerQuery == 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_frameTimerActive)
|
if (!m_frameTimerActive) {
|
||||||
{
|
|
||||||
glBeginQuery(GL_TIME_ELAPSED, m_frameTimerQuery);
|
glBeginQuery(GL_TIME_ELAPSED, m_frameTimerQuery);
|
||||||
m_frameTimerActive = true;
|
m_frameTimerActive = true;
|
||||||
GetStats().gpuTimersIssued++;
|
GetStats().gpuTimersIssued++;
|
||||||
@@ -226,8 +223,7 @@ namespace PF
|
|||||||
static bool s_checked = false;
|
static bool s_checked = false;
|
||||||
static bool s_hasTimer = false;
|
static bool s_hasTimer = false;
|
||||||
static bool s_hasTimer64 = false;
|
static bool s_hasTimer64 = false;
|
||||||
if (!s_checked)
|
if (!s_checked) {
|
||||||
{
|
|
||||||
s_hasTimer = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query || GLEW_EXT_timer_query);
|
s_hasTimer = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query || GLEW_EXT_timer_query);
|
||||||
s_hasTimer64 = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query);
|
s_hasTimer64 = (GLEW_VERSION_3_3 || GLEW_ARB_timer_query);
|
||||||
s_checked = true;
|
s_checked = true;
|
||||||
@@ -244,16 +240,13 @@ namespace PF
|
|||||||
GLint available = 0;
|
GLint available = 0;
|
||||||
glGetQueryObjectiv(m_frameTimerQuery, GL_QUERY_RESULT_AVAILABLE, &available);
|
glGetQueryObjectiv(m_frameTimerQuery, GL_QUERY_RESULT_AVAILABLE, &available);
|
||||||
|
|
||||||
if (s_hasTimer64 && glGetQueryObjectui64v)
|
if (s_hasTimer64 && glGetQueryObjectui64v) {
|
||||||
{
|
|
||||||
GLuint64 ns = 0;
|
GLuint64 ns = 0;
|
||||||
glGetQueryObjectui64v(m_frameTimerQuery,
|
glGetQueryObjectui64v(m_frameTimerQuery,
|
||||||
available ? GL_QUERY_RESULT : GL_QUERY_RESULT,
|
available ? GL_QUERY_RESULT : GL_QUERY_RESULT,
|
||||||
&ns);
|
&ns);
|
||||||
GetStats().gpuTimeNsLastFrame = ns;
|
GetStats().gpuTimeNsLastFrame = ns;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
GLuint ns32 = 0;
|
GLuint ns32 = 0;
|
||||||
glGetQueryObjectuiv(m_frameTimerQuery,
|
glGetQueryObjectuiv(m_frameTimerQuery,
|
||||||
available ? GL_QUERY_RESULT : GL_QUERY_RESULT,
|
available ? GL_QUERY_RESULT : GL_QUERY_RESULT,
|
||||||
@@ -273,10 +266,8 @@ namespace PF
|
|||||||
slot.active = false;
|
slot.active = false;
|
||||||
|
|
||||||
// reuse free slots if any
|
// reuse free slots if any
|
||||||
for (size_t i = 0; i < m_timerPool.size(); ++i)
|
for (size_t i = 0; i < m_timerPool.size(); ++i) {
|
||||||
{
|
if (m_timerPool[i].id == 0) {
|
||||||
if (m_timerPool[i].id == 0)
|
|
||||||
{
|
|
||||||
m_timerPool[i] = slot;
|
m_timerPool[i] = slot;
|
||||||
return static_cast<GpuTimer>(i + 1); // handle 1-based
|
return static_cast<GpuTimer>(i + 1); // handle 1-based
|
||||||
}
|
}
|
||||||
@@ -292,8 +283,7 @@ namespace PF
|
|||||||
size_t idx = static_cast<size_t>(h - 1);
|
size_t idx = static_cast<size_t>(h - 1);
|
||||||
if (idx >= m_timerPool.size())
|
if (idx >= m_timerPool.size())
|
||||||
return;
|
return;
|
||||||
if (m_timerPool[idx].id)
|
if (m_timerPool[idx].id) {
|
||||||
{
|
|
||||||
glDeleteQueries(1, &m_timerPool[idx].id);
|
glDeleteQueries(1, &m_timerPool[idx].id);
|
||||||
}
|
}
|
||||||
m_timerPool[idx] = {}; // mark free
|
m_timerPool[idx] = {}; // mark free
|
||||||
@@ -307,8 +297,7 @@ namespace PF
|
|||||||
if (idx >= m_timerPool.size())
|
if (idx >= m_timerPool.size())
|
||||||
return;
|
return;
|
||||||
auto &ts = m_timerPool[idx];
|
auto &ts = m_timerPool[idx];
|
||||||
if (ts.id && !ts.active)
|
if (ts.id && !ts.active) {
|
||||||
{
|
|
||||||
glBeginQuery(GL_TIME_ELAPSED, ts.id);
|
glBeginQuery(GL_TIME_ELAPSED, ts.id);
|
||||||
ts.active = true;
|
ts.active = true;
|
||||||
GetStats().gpuTimersIssued++;
|
GetStats().gpuTimersIssued++;
|
||||||
@@ -331,8 +320,7 @@ namespace PF
|
|||||||
ts.active = false;
|
ts.active = false;
|
||||||
|
|
||||||
GLint available = 0;
|
GLint available = 0;
|
||||||
if (!wait)
|
if (!wait) {
|
||||||
{
|
|
||||||
glGetQueryObjectiv(ts.id, GL_QUERY_RESULT_AVAILABLE, &available);
|
glGetQueryObjectiv(ts.id, GL_QUERY_RESULT_AVAILABLE, &available);
|
||||||
if (!available)
|
if (!available)
|
||||||
return false; // not ready yet
|
return false; // not ready yet
|
||||||
@@ -352,8 +340,7 @@ namespace PF
|
|||||||
// ==== Existing API ====
|
// ==== Existing API ====
|
||||||
void RenderDevice::Viewport(int x, int y, int w, int h)
|
void RenderDevice::Viewport(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if (m_viewport[0] != x || m_viewport[1] != y || m_viewport[2] != w || m_viewport[3] != h)
|
if (m_viewport[0] != x || m_viewport[1] != y || m_viewport[2] != w || m_viewport[3] != h) {
|
||||||
{
|
|
||||||
glViewport(x, y, w, h);
|
glViewport(x, y, w, h);
|
||||||
m_viewport[0] = x;
|
m_viewport[0] = x;
|
||||||
m_viewport[1] = y;
|
m_viewport[1] = y;
|
||||||
@@ -365,8 +352,7 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::SetClearColor(float r, float g, float b, float a)
|
void RenderDevice::SetClearColor(float r, float g, float b, float a)
|
||||||
{
|
{
|
||||||
if (m_clear[0] != r || m_clear[1] != g || m_clear[2] != b || m_clear[3] != a)
|
if (m_clear[0] != r || m_clear[1] != g || m_clear[2] != b || m_clear[3] != a) {
|
||||||
{
|
|
||||||
glClearColor(r, g, b, a);
|
glClearColor(r, g, b, a);
|
||||||
m_clear[0] = r;
|
m_clear[0] = r;
|
||||||
m_clear[1] = g;
|
m_clear[1] = g;
|
||||||
@@ -391,8 +377,7 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::SetDepthTest(const bool enabled)
|
void RenderDevice::SetDepthTest(const bool enabled)
|
||||||
{
|
{
|
||||||
if (m_depthTest != enabled)
|
if (m_depthTest != enabled) {
|
||||||
{
|
|
||||||
enabled ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
enabled ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
||||||
m_depthTest = enabled;
|
m_depthTest = enabled;
|
||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
@@ -402,8 +387,7 @@ namespace PF
|
|||||||
void RenderDevice::SetDepthFunc(const Compare f)
|
void RenderDevice::SetDepthFunc(const Compare f)
|
||||||
{
|
{
|
||||||
const auto glf = ToGL(f);
|
const auto glf = ToGL(f);
|
||||||
if (m_depthFunc != static_cast<int>(glf))
|
if (m_depthFunc != static_cast<int>(glf)) {
|
||||||
{
|
|
||||||
glDepthFunc(glf);
|
glDepthFunc(glf);
|
||||||
m_depthFunc = static_cast<int>(glf);
|
m_depthFunc = static_cast<int>(glf);
|
||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
@@ -412,8 +396,7 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::SetDepthMask(const bool enableWrite)
|
void RenderDevice::SetDepthMask(const bool enableWrite)
|
||||||
{
|
{
|
||||||
if (m_depthMask != enableWrite)
|
if (m_depthMask != enableWrite) {
|
||||||
{
|
|
||||||
glDepthMask(enableWrite ? GL_TRUE : GL_FALSE);
|
glDepthMask(enableWrite ? GL_TRUE : GL_FALSE);
|
||||||
m_depthMask = enableWrite;
|
m_depthMask = enableWrite;
|
||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
@@ -422,8 +405,7 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::SetColorMask(const bool r, const bool g, const bool b, const bool a)
|
void RenderDevice::SetColorMask(const bool r, const bool g, const bool b, const bool a)
|
||||||
{
|
{
|
||||||
if (m_colorMask[0] != r || m_colorMask[1] != g || m_colorMask[2] != b || m_colorMask[3] != a)
|
if (m_colorMask[0] != r || m_colorMask[1] != g || m_colorMask[2] != b || m_colorMask[3] != a) {
|
||||||
{
|
|
||||||
glColorMask(r, g, b, a);
|
glColorMask(r, g, b, a);
|
||||||
m_colorMask[0] = r;
|
m_colorMask[0] = r;
|
||||||
m_colorMask[1] = g;
|
m_colorMask[1] = g;
|
||||||
@@ -437,23 +419,19 @@ namespace PF
|
|||||||
void RenderDevice::SetCull(const CullFace c)
|
void RenderDevice::SetCull(const CullFace c)
|
||||||
{
|
{
|
||||||
const auto glc = ToGL(c);
|
const auto glc = ToGL(c);
|
||||||
if (c == CullFace::None)
|
if (c == CullFace::None) {
|
||||||
{
|
if (m_cullFace != 0) {
|
||||||
if (m_cullFace != 0)
|
|
||||||
{
|
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
m_cullFace = 0;
|
m_cullFace = 0;
|
||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_cullFace == 0)
|
if (m_cullFace == 0) {
|
||||||
{
|
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
}
|
}
|
||||||
if (m_cullFace != (int)glc)
|
if (m_cullFace != (int) glc) {
|
||||||
{
|
|
||||||
glCullFace(glc);
|
glCullFace(glc);
|
||||||
m_cullFace = (int) glc;
|
m_cullFace = (int) glc;
|
||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
@@ -463,8 +441,7 @@ namespace PF
|
|||||||
void RenderDevice::SetFrontFace(const Winding w)
|
void RenderDevice::SetFrontFace(const Winding w)
|
||||||
{
|
{
|
||||||
const auto glw = ToGL(w);
|
const auto glw = ToGL(w);
|
||||||
if (m_frontFace != (int)glw)
|
if (m_frontFace != (int) glw) {
|
||||||
{
|
|
||||||
glFrontFace(glw);
|
glFrontFace(glw);
|
||||||
m_frontFace = (int) glw;
|
m_frontFace = (int) glw;
|
||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
@@ -473,8 +450,7 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::SetBlend(const bool enabled)
|
void RenderDevice::SetBlend(const bool enabled)
|
||||||
{
|
{
|
||||||
if (m_blend != enabled)
|
if (m_blend != enabled) {
|
||||||
{
|
|
||||||
enabled ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
enabled ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
||||||
m_blend = enabled;
|
m_blend = enabled;
|
||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
@@ -484,8 +460,7 @@ namespace PF
|
|||||||
void RenderDevice::SetBlendFunc(const BlendFactor src, const BlendFactor dst)
|
void RenderDevice::SetBlendFunc(const BlendFactor src, const BlendFactor dst)
|
||||||
{
|
{
|
||||||
const auto gls = ToGL(src), gld = ToGL(dst);
|
const auto gls = ToGL(src), gld = ToGL(dst);
|
||||||
if (m_blendSrc != (int)gls || m_blendDst != (int)gld)
|
if (m_blendSrc != (int) gls || m_blendDst != (int) gld) {
|
||||||
{
|
|
||||||
glBlendFunc(gls, gld);
|
glBlendFunc(gls, gld);
|
||||||
m_blendSrc = (int) gls;
|
m_blendSrc = (int) gls;
|
||||||
m_blendDst = (int) gld;
|
m_blendDst = (int) gld;
|
||||||
@@ -505,8 +480,7 @@ namespace PF
|
|||||||
{
|
{
|
||||||
const unsigned newRGB = (unsigned) rgb;
|
const unsigned newRGB = (unsigned) rgb;
|
||||||
const unsigned newA = (unsigned) a;
|
const unsigned newA = (unsigned) a;
|
||||||
if (m_blendEqRGB != newRGB || m_blendEqA != newA)
|
if (m_blendEqRGB != newRGB || m_blendEqA != newA) {
|
||||||
{
|
|
||||||
if (newRGB == newA)
|
if (newRGB == newA)
|
||||||
glBlendEquation((GLenum) newRGB);
|
glBlendEquation((GLenum) newRGB);
|
||||||
else
|
else
|
||||||
@@ -520,8 +494,7 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::SetStencil(bool enabled)
|
void RenderDevice::SetStencil(bool enabled)
|
||||||
{
|
{
|
||||||
if (m_stencilEnabled != enabled)
|
if (m_stencilEnabled != enabled) {
|
||||||
{
|
|
||||||
enabled ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST);
|
enabled ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST);
|
||||||
m_stencilEnabled = enabled;
|
m_stencilEnabled = enabled;
|
||||||
GetStats().stencilStateChanges++;
|
GetStats().stencilStateChanges++;
|
||||||
@@ -536,17 +509,16 @@ namespace PF
|
|||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderDevice::SetStencilOp(unsigned sfail, unsigned dpfail, unsigned dppass)
|
void RenderDevice::SetStencilOp(unsigned sfail, unsigned dCXail, unsigned dppass)
|
||||||
{
|
{
|
||||||
glStencilOp((GLenum)sfail, (GLenum)dpfail, (GLenum)dppass);
|
glStencilOp((GLenum) sfail, (GLenum) dCXail, (GLenum) dppass);
|
||||||
GetStats().stencilStateChanges++;
|
GetStats().stencilStateChanges++;
|
||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderDevice::SetStencilMask(unsigned mask)
|
void RenderDevice::SetStencilMask(unsigned mask)
|
||||||
{
|
{
|
||||||
if (m_stencilMask != mask)
|
if (m_stencilMask != mask) {
|
||||||
{
|
|
||||||
glStencilMask(mask);
|
glStencilMask(mask);
|
||||||
m_stencilMask = mask;
|
m_stencilMask = mask;
|
||||||
GetStats().stencilStateChanges++;
|
GetStats().stencilStateChanges++;
|
||||||
@@ -556,17 +528,14 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::SetScissor(bool enabled, int x, int y, int w, int h)
|
void RenderDevice::SetScissor(bool enabled, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if (m_scissorEnabled != enabled)
|
if (m_scissorEnabled != enabled) {
|
||||||
{
|
|
||||||
enabled ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST);
|
enabled ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST);
|
||||||
m_scissorEnabled = enabled;
|
m_scissorEnabled = enabled;
|
||||||
GetStats().scissorChanges++;
|
GetStats().scissorChanges++;
|
||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
}
|
}
|
||||||
if (enabled)
|
if (enabled) {
|
||||||
{
|
if (m_scissorBox[0] != x || m_scissorBox[1] != y || m_scissorBox[2] != w || m_scissorBox[3] != h) {
|
||||||
if (m_scissorBox[0] != x || m_scissorBox[1] != y || m_scissorBox[2] != w || m_scissorBox[3] != h)
|
|
||||||
{
|
|
||||||
glScissor(x, y, w, h);
|
glScissor(x, y, w, h);
|
||||||
m_scissorBox[0] = x;
|
m_scissorBox[0] = x;
|
||||||
m_scissorBox[1] = y;
|
m_scissorBox[1] = y;
|
||||||
@@ -586,8 +555,7 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::BindVAO(const VAO &v)
|
void RenderDevice::BindVAO(const VAO &v)
|
||||||
{
|
{
|
||||||
if (m_boundVAO != v.id)
|
if (m_boundVAO != v.id) {
|
||||||
{
|
|
||||||
glBindVertexArray(v.id);
|
glBindVertexArray(v.id);
|
||||||
m_boundVAO = v.id;
|
m_boundVAO = v.id;
|
||||||
GetStats().vaoBinds++;
|
GetStats().vaoBinds++;
|
||||||
@@ -603,7 +571,8 @@ namespace PF
|
|||||||
v = {};
|
v = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderDevice::Buffer RenderDevice::CreateBuffer(BufferTarget target, size_t sizeBytes, const void *data, Usage usage)
|
RenderDevice::Buffer RenderDevice::CreateBuffer(BufferTarget target, size_t sizeBytes, const void *data,
|
||||||
|
Usage usage)
|
||||||
{
|
{
|
||||||
Buffer b{};
|
Buffer b{};
|
||||||
b.target = target;
|
b.target = target;
|
||||||
@@ -618,19 +587,14 @@ namespace PF
|
|||||||
void RenderDevice::BindBuffer(const Buffer &b)
|
void RenderDevice::BindBuffer(const Buffer &b)
|
||||||
{
|
{
|
||||||
const GLenum tgt = ToGL(b.target);
|
const GLenum tgt = ToGL(b.target);
|
||||||
if (b.target == BufferTarget::Array)
|
if (b.target == BufferTarget::Array) {
|
||||||
{
|
if (m_boundArrayBuffer != b.id) {
|
||||||
if (m_boundArrayBuffer != b.id)
|
|
||||||
{
|
|
||||||
glBindBuffer(tgt, b.id);
|
glBindBuffer(tgt, b.id);
|
||||||
m_boundArrayBuffer = b.id;
|
m_boundArrayBuffer = b.id;
|
||||||
GetStats().bufferBinds++;
|
GetStats().bufferBinds++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if (m_boundElementBuffer != b.id) {
|
||||||
{
|
|
||||||
if (m_boundElementBuffer != b.id)
|
|
||||||
{
|
|
||||||
glBindBuffer(tgt, b.id);
|
glBindBuffer(tgt, b.id);
|
||||||
m_boundElementBuffer = b.id;
|
m_boundElementBuffer = b.id;
|
||||||
GetStats().bufferBinds++;
|
GetStats().bufferBinds++;
|
||||||
@@ -753,38 +717,27 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::BindTextureUnit(unsigned unit, const Texture &t)
|
void RenderDevice::BindTextureUnit(unsigned unit, const Texture &t)
|
||||||
{
|
{
|
||||||
if (glBindTextureUnit)
|
if (glBindTextureUnit) {
|
||||||
{
|
|
||||||
// DSA
|
// DSA
|
||||||
if (unit < 32)
|
if (unit < 32) {
|
||||||
{
|
if (m_boundTexUnits[unit] != t.id) {
|
||||||
if (m_boundTexUnits[unit] != t.id)
|
|
||||||
{
|
|
||||||
glBindTextureUnit(unit, t.id);
|
glBindTextureUnit(unit, t.id);
|
||||||
m_boundTexUnits[unit] = t.id;
|
m_boundTexUnits[unit] = t.id;
|
||||||
GetStats().textureBinds++;
|
GetStats().textureBinds++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
glBindTextureUnit(unit, t.id);
|
glBindTextureUnit(unit, t.id);
|
||||||
GetStats().textureBinds++;
|
GetStats().textureBinds++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if (unit < 32) {
|
||||||
{
|
if (m_boundTexUnits[unit] != t.id) {
|
||||||
if (unit < 32)
|
|
||||||
{
|
|
||||||
if (m_boundTexUnits[unit] != t.id)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0 + unit);
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
glBindTexture(t.target, t.id);
|
glBindTexture(t.target, t.id);
|
||||||
m_boundTexUnits[unit] = t.id;
|
m_boundTexUnits[unit] = t.id;
|
||||||
GetStats().textureBinds++;
|
GetStats().textureBinds++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0 + unit);
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
glBindTexture(t.target, t.id);
|
glBindTexture(t.target, t.id);
|
||||||
GetStats().textureBinds++;
|
GetStats().textureBinds++;
|
||||||
@@ -807,14 +760,14 @@ namespace PF
|
|||||||
GetStats().stateChanges++;
|
GetStats().stateChanges++;
|
||||||
}
|
}
|
||||||
|
|
||||||
PF::RenderDevice::Sampler PF::RenderDevice::CreateSampler()
|
CX::RenderDevice::Sampler CX::RenderDevice::CreateSampler()
|
||||||
{
|
{
|
||||||
Sampler s{};
|
Sampler s{};
|
||||||
glGenSamplers(1, &s.id);
|
glGenSamplers(1, &s.id);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PF::RenderDevice::SetSamplerParams(Sampler s, TexFilter minFilter, TexFilter magFilter, TexWrap wrapS,
|
void CX::RenderDevice::SetSamplerParams(Sampler s, TexFilter minFilter, TexFilter magFilter, TexWrap wrapS,
|
||||||
TexWrap wrapT)
|
TexWrap wrapT)
|
||||||
{
|
{
|
||||||
if (!s.id)
|
if (!s.id)
|
||||||
@@ -831,8 +784,7 @@ namespace PF
|
|||||||
return;
|
return;
|
||||||
#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
|
#ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
|
||||||
GLfloat maxAniso = 1.0f;
|
GLfloat maxAniso = 1.0f;
|
||||||
if (glewIsSupported("GL_EXT_texture_filter_anisotropic"))
|
if (glewIsSupported("GL_EXT_texture_filter_anisotropic")) {
|
||||||
{
|
|
||||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
|
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
|
||||||
if (aniso < 1.0f)
|
if (aniso < 1.0f)
|
||||||
aniso = 1.0f;
|
aniso = 1.0f;
|
||||||
@@ -845,17 +797,13 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::BindSampler(unsigned unit, Sampler s)
|
void RenderDevice::BindSampler(unsigned unit, Sampler s)
|
||||||
{
|
{
|
||||||
if (unit < 32)
|
if (unit < 32) {
|
||||||
{
|
if (m_boundSamplers[unit] != s.id) {
|
||||||
if (m_boundSamplers[unit] != s.id)
|
|
||||||
{
|
|
||||||
glBindSampler(unit, s.id);
|
glBindSampler(unit, s.id);
|
||||||
m_boundSamplers[unit] = s.id;
|
m_boundSamplers[unit] = s.id;
|
||||||
GetStats().samplerBinds++;
|
GetStats().samplerBinds++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
glBindSampler(unit, s.id);
|
glBindSampler(unit, s.id);
|
||||||
GetStats().samplerBinds++;
|
GetStats().samplerBinds++;
|
||||||
}
|
}
|
||||||
@@ -863,8 +811,7 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::Destroy(Sampler &s)
|
void RenderDevice::Destroy(Sampler &s)
|
||||||
{
|
{
|
||||||
if (s.id)
|
if (s.id) {
|
||||||
{
|
|
||||||
for (unsigned i = 0; i < 32; ++i)
|
for (unsigned i = 0; i < 32; ++i)
|
||||||
if (m_boundSamplers[i] == s.id)
|
if (m_boundSamplers[i] == s.id)
|
||||||
m_boundSamplers[i] = 0;
|
m_boundSamplers[i] = 0;
|
||||||
@@ -890,8 +837,7 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::BindFramebuffer(const Framebuffer &fb)
|
void RenderDevice::BindFramebuffer(const Framebuffer &fb)
|
||||||
{
|
{
|
||||||
if (m_boundFramebuffer != fb.id)
|
if (m_boundFramebuffer != fb.id) {
|
||||||
{
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fb.id);
|
glBindFramebuffer(GL_FRAMEBUFFER, fb.id);
|
||||||
m_boundFramebuffer = fb.id;
|
m_boundFramebuffer = fb.id;
|
||||||
GetStats().framebufferBinds++;
|
GetStats().framebufferBinds++;
|
||||||
@@ -900,8 +846,7 @@ namespace PF
|
|||||||
|
|
||||||
void RenderDevice::BindDefaultFramebuffer()
|
void RenderDevice::BindDefaultFramebuffer()
|
||||||
{
|
{
|
||||||
if (m_boundFramebuffer != 0)
|
if (m_boundFramebuffer != 0) {
|
||||||
{
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
m_boundFramebuffer = 0;
|
m_boundFramebuffer = 0;
|
||||||
GetStats().framebufferBinds++;
|
GetStats().framebufferBinds++;
|
||||||
@@ -1006,7 +951,8 @@ namespace PF
|
|||||||
GetStats().instancesDrawn += instanceCount;
|
GetStats().instancesDrawn += instanceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderDevice::DrawElementsBaseVertex(DrawMode mode, int count, IndexType type, const void *offset, int baseVertex)
|
void RenderDevice::DrawElementsBaseVertex(DrawMode mode, int count, IndexType type, const void *offset,
|
||||||
|
int baseVertex)
|
||||||
{
|
{
|
||||||
glDrawElementsBaseVertex(ToGL(mode), count, ToGL(type), offset, baseVertex);
|
glDrawElementsBaseVertex(ToGL(mode), count, ToGL(type), offset, baseVertex);
|
||||||
GetStats().indexedDrawCalls++;
|
GetStats().indexedDrawCalls++;
|
||||||
@@ -1016,8 +962,7 @@ namespace PF
|
|||||||
void RenderDevice::SetObjectLabel(unsigned glType, unsigned id, const std::string &name)
|
void RenderDevice::SetObjectLabel(unsigned glType, unsigned id, const std::string &name)
|
||||||
{
|
{
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
if (id && !name.empty() && glObjectLabel)
|
if (id && !name.empty() && glObjectLabel) {
|
||||||
{
|
|
||||||
glObjectLabel(glType, id, (GLsizei) name.size(), name.c_str());
|
glObjectLabel(glType, id, (GLsizei) name.size(), name.c_str());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1035,10 +980,8 @@ namespace PF
|
|||||||
glBindTexture(GL_TEXTURE_2D, t.id);
|
glBindTexture(GL_TEXTURE_2D, t.id);
|
||||||
GetStats().textureBinds++;
|
GetStats().textureBinds++;
|
||||||
|
|
||||||
// allocate immutable storage
|
|
||||||
glTexStorage2D(GL_TEXTURE_2D, t.levels, static_cast<GLenum>(internalFmt), w, h);
|
glTexStorage2D(GL_TEXTURE_2D, t.levels, static_cast<GLenum>(internalFmt), w, h);
|
||||||
|
|
||||||
// sensible defaults
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (t.levels > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (t.levels > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
@@ -1077,4 +1020,3 @@ namespace PF
|
|||||||
m_boundTexUnits[unit] = 0;
|
m_boundTexUnits[unit] = 0;
|
||||||
GetStats().textureBinds++;
|
GetStats().textureBinds++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user