Skip to content

Commit ea60209

Browse files
committed
GPU Display: Add shaders for smooth lines and points for OpenGL and Vulkan
1 parent 4f25fcb commit ea60209

13 files changed

Lines changed: 285 additions & 36 deletions

‎GPU/GPUTracking/Definitions/GPUSettingsList.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ AddOption(camYUp, bool, false, "", 0, "Orient the camera such that the y-axis is
500500
AddOption(cameraMode, int32_t, 0, "", 0, "Camera mode")
501501
AddOption(fullScreen, bool, false, "", 0, "Full Screen")
502502
AddOption(maximized, bool, true, "", 0, "Maximized window")
503-
AddOption(openGLCore, bool, false, "", 0, "Use renderer path for OpenGL core profile")
503+
AddOption(rendererCompatSmoothing, bool, false, "", 0, "Use compat smoothing (if available) of instad of shader for smooth lines / points")
504504
AddOption(drawQualityMSAA, int32_t, 0, "", 0, "MultiSample Anti Aliasing")
505505
AddOption(drawQualityDownsampleFSAA, int32_t, 0, "", 0, "Downsampling Anti Aliasing")
506506
AddOption(drawQualityVSync, bool, true, "", 0, "Enable Vertical Sync")

‎GPU/GPUTracking/display/CMakeLists.txt‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,13 @@ if(GPUCA_EVENT_DISPLAY_VULKAN OR GPUCA_EVENT_DISPLAY_OPENGL)
257257
include(shaders.cmake)
258258
set(SHADERS shaders/vertex.vert
259259
shaders/vertexPoint.vert
260+
shaders/vertexSmoothPoint.vert
260261
shaders/vertexTexture.vert
261262
shaders/vertexPassthrough.vert
262263
shaders/fragment.frag
264+
shaders/fragmentSmoothPoint.frag
265+
shaders/vertexSmoothLine.vert
266+
shaders/fragmentSmoothLine.frag
263267
shaders/fragmentText.frag
264268
shaders/fragmentTexture.frag
265269
shaders/field.geom)

‎GPU/GPUTracking/display/GPUDisplay.cxx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ GPUDisplay::GPUDisplay(GPUDisplayFrontend* frontend, GPUChainTracking* chain, GP
7575
mBackend->mDisplay = this;
7676
frontend->mDisplay = this;
7777
frontend->mBackend = mBackend.get();
78-
mCfgR.openGLCore = mBackend->CoreProfile();
78+
mCfgR.rendererCompatSmoothing &= !mBackend->CoreProfile();
7979
}
8080

8181
void GPUDisplay::calcXYZ(const float* matrix)

‎GPU/GPUTracking/display/backend/GPUDisplayBackend.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ class GPUDisplayBackend
120120
bool mFrontendCompatTextDraw = false;
121121
std::vector<char> mScreenshotPixels;
122122

123+
static constexpr float SMOOTH_POINT_EXTRA_SIZE = 0.6f;
124+
static constexpr float SMOOTH_LINE_EXTRA_WIDTH = 0.8f;
123125
int32_t mDownsampleFactor = 1;
124126

125127
uint32_t mRenderWidth = 0;

‎GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx‎

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,12 @@ uint32_t GPUDisplayBackendOpenGL::drawVertices(const vboList& v, const drawType
180180
}
181181

182182
if (mDisplay->useMultiVBO()) {
183-
if (mDisplay->cfgR().openGLCore) {
183+
if (!mDisplay->cfgR().rendererCompatSmoothing) { // TODO: Remove OpenGL compat profile completely
184184
CHKERR(glBindVertexArray(mVertexArray));
185185
}
186186
CHKERR(glBindBuffer(GL_ARRAY_BUFFER, mVBOId[iSector]));
187187
#ifndef GPUCA_DISPLAY_OPENGL_CORE
188-
if (!mDisplay->cfgR().openGLCore) {
188+
if (mDisplay->cfgR().rendererCompatSmoothing) {
189189
CHKERR(glVertexPointer(3, GL_FLOAT, 0, nullptr));
190190
} else
191191
#endif
@@ -195,6 +195,10 @@ uint32_t GPUDisplayBackendOpenGL::drawVertices(const vboList& v, const drawType
195195
}
196196
}
197197

198+
const uint32_t smoothProgram = tt == POINTS ? (mUseSmoothPointShader ? mShaderProgramSmoothPoint : 0) : (mUseSmoothLineShader ? mShaderProgramSmoothLine : 0);
199+
if (smoothProgram) {
200+
CHKERR(glUseProgram(smoothProgram));
201+
}
198202
if (mDisplay->cfgR().useGLIndirectDraw) {
199203
CHKERR(glMultiDrawArraysIndirect(t, (void*)(size_t)((mIndirectSectorOffset[iSector] + first) * sizeof(DrawArraysIndirectCommand)), count, 0));
200204
} else if (OPENGL_EMULATE_MULTI_DRAW) {
@@ -205,18 +209,27 @@ uint32_t GPUDisplayBackendOpenGL::drawVertices(const vboList& v, const drawType
205209
static_assert(sizeof(GLsizei) == sizeof(*mDisplay->vertexBufferCount()[iSector].data()), "Invalid counter size does not match GLsizei");
206210
CHKERR(glMultiDrawArrays(t, mDisplay->vertexBufferStart()[iSector].data() + first, ((const GLsizei*)mDisplay->vertexBufferCount()[iSector].data()) + first, count));
207211
}
212+
if (smoothProgram) {
213+
CHKERR(glUseProgram(mShaderProgram));
214+
}
208215
return count;
209216
}
210217

211218
void GPUDisplayBackendOpenGL::ActivateColor(std::array<float, 4>& color)
212219
{
213220
#ifndef GPUCA_DISPLAY_OPENGL_CORE
214-
if (!mDisplay->cfgR().openGLCore) {
221+
if (mDisplay->cfgR().rendererCompatSmoothing) {
215222
glColor4f(color[0], color[1], color[2], color[3]);
216223
} else
217224
#endif
218225
{
219226
CHKERR(glUniform4fv(UNIFORM_LOCATION_COLOR, 1, &color[0]));
227+
if (mUseSmoothPointShader) {
228+
CHKERR(glProgramUniform4fv(mShaderProgramSmoothPoint, UNIFORM_LOCATION_COLOR, 1, &color[0]));
229+
}
230+
if (mUseSmoothLineShader) {
231+
CHKERR(glProgramUniform4fv(mShaderProgramSmoothLine, UNIFORM_LOCATION_COLOR, 1, &color[0]));
232+
}
220233
}
221234
}
222235

@@ -312,7 +325,11 @@ int32_t GPUDisplayBackendOpenGL::InitBackendA()
312325
CHKERR(mVertexShaderTexture = loadShader(GL_VERTEX_SHADER, _binary_opengl_vertexTexture_vert_spv_start, _binary_opengl_vertexTexture_vert_spv_len));
313326
CHKERR(mFragmentShaderTexture = loadShader(GL_FRAGMENT_SHADER, _binary_opengl_fragmentTexture_frag_spv_start, _binary_opengl_fragmentTexture_frag_spv_len));
314327
CHKERR(mFragmentShaderText = loadShader(GL_FRAGMENT_SHADER, _binary_opengl_fragmentText_frag_spv_start, _binary_opengl_fragmentText_frag_spv_len));
315-
if (checkShaderStatus(mVertexShader) || checkShaderStatus(mFragmentShader) || checkShaderStatus(mVertexShaderTexture) || checkShaderStatus(mFragmentShaderTexture) || checkShaderStatus(mFragmentShaderText)) {
328+
CHKERR(mVertexShaderSmoothPoint = loadShader(GL_VERTEX_SHADER, _binary_opengl_vertexSmoothPoint_vert_spv_start, _binary_opengl_vertexSmoothPoint_vert_spv_len));
329+
CHKERR(mFragmentShaderSmoothPoint = loadShader(GL_FRAGMENT_SHADER, _binary_opengl_fragmentSmoothPoint_frag_spv_start, _binary_opengl_fragmentSmoothPoint_frag_spv_len));
330+
CHKERR(mVertexShaderSmoothLine = loadShader(GL_VERTEX_SHADER, _binary_opengl_vertexSmoothLine_vert_spv_start, _binary_opengl_vertexSmoothLine_vert_spv_len));
331+
CHKERR(mFragmentShaderSmoothLine = loadShader(GL_FRAGMENT_SHADER, _binary_opengl_fragmentSmoothLine_frag_spv_start, _binary_opengl_fragmentSmoothLine_frag_spv_len));
332+
if (checkShaderStatus(mVertexShader) || checkShaderStatus(mFragmentShader) || checkShaderStatus(mVertexShaderSmoothPoint) || checkShaderStatus(mFragmentShaderSmoothPoint) || checkShaderStatus(mVertexShaderSmoothLine) || checkShaderStatus(mFragmentShaderSmoothLine) || checkShaderStatus(mVertexShaderTexture) || checkShaderStatus(mFragmentShaderTexture) || checkShaderStatus(mFragmentShaderText)) {
316333
return 1;
317334
}
318335
CHKERR(mShaderProgram = glCreateProgram());
@@ -322,6 +339,20 @@ int32_t GPUDisplayBackendOpenGL::InitBackendA()
322339
if (checkProgramStatus(mShaderProgram)) {
323340
return 1;
324341
}
342+
CHKERR(mShaderProgramSmoothPoint = glCreateProgram());
343+
CHKERR(glAttachShader(mShaderProgramSmoothPoint, mVertexShaderSmoothPoint));
344+
CHKERR(glAttachShader(mShaderProgramSmoothPoint, mFragmentShaderSmoothPoint));
345+
CHKERR(glLinkProgram(mShaderProgramSmoothPoint));
346+
if (checkProgramStatus(mShaderProgramSmoothPoint)) {
347+
return 1;
348+
}
349+
CHKERR(mShaderProgramSmoothLine = glCreateProgram());
350+
CHKERR(glAttachShader(mShaderProgramSmoothLine, mVertexShaderSmoothLine));
351+
CHKERR(glAttachShader(mShaderProgramSmoothLine, mFragmentShaderSmoothLine));
352+
CHKERR(glLinkProgram(mShaderProgramSmoothLine));
353+
if (checkProgramStatus(mShaderProgramSmoothLine)) {
354+
return 1;
355+
}
325356
CHKERR(mShaderProgramText = glCreateProgram());
326357
CHKERR(glAttachShader(mShaderProgramText, mVertexShaderTexture));
327358
CHKERR(glAttachShader(mShaderProgramText, mFragmentShaderText));
@@ -359,6 +390,12 @@ void GPUDisplayBackendOpenGL::ExitBackendA()
359390
CHKERR(glDeleteProgram(mShaderProgram));
360391
CHKERR(glDeleteShader(mVertexShader));
361392
CHKERR(glDeleteShader(mFragmentShader));
393+
CHKERR(glDeleteProgram(mShaderProgramSmoothPoint));
394+
CHKERR(glDeleteShader(mVertexShaderSmoothPoint));
395+
CHKERR(glDeleteShader(mFragmentShaderSmoothPoint));
396+
CHKERR(glDeleteProgram(mShaderProgramSmoothLine));
397+
CHKERR(glDeleteShader(mVertexShaderSmoothLine));
398+
CHKERR(glDeleteShader(mFragmentShaderSmoothLine));
362399
CHKERR(glDeleteProgram(mShaderProgramText));
363400
CHKERR(glDeleteShader(mFragmentShaderText));
364401
CHKERR(glDeleteProgram(mShaderProgramTexture));
@@ -432,13 +469,20 @@ void GPUDisplayBackendOpenGL::prepareDraw(const hmm_mat4& proj, const hmm_mat4&
432469
setFrameBuffer(0);
433470
}
434471
clearScreen();
472+
mUseSmoothPointShader = mDisplay->cfgL().smoothPoints && !mDisplay->cfgR().rendererCompatSmoothing; // The compat profile uses GL_POINT_SMOOTH / GL_LINE_SMOOTH
473+
mUseSmoothLineShader = mDisplay->cfgL().smoothLines && !mDisplay->cfgR().rendererCompatSmoothing;
435474
#ifndef GPUCA_DISPLAY_OPENGL_CORE
436-
if (mDisplay->cfgL().smoothPoints && !mDisplay->cfgR().openGLCore) {
475+
if (mUseSmoothPointShader) { // Compatibility context: gl_PointCoord is only defined with point sprites
476+
CHKERR(glEnable(GL_POINT_SPRITE));
477+
} else {
478+
CHKERR(glDisable(GL_POINT_SPRITE));
479+
}
480+
if (mDisplay->cfgL().smoothPoints && mDisplay->cfgR().rendererCompatSmoothing) {
437481
CHKERR(glEnable(GL_POINT_SMOOTH));
438482
} else {
439483
CHKERR(glDisable(GL_POINT_SMOOTH));
440484
}
441-
if (mDisplay->cfgL().smoothLines && !mDisplay->cfgR().openGLCore) {
485+
if (mDisplay->cfgL().smoothLines && mDisplay->cfgR().rendererCompatSmoothing) {
442486
CHKERR(glEnable(GL_LINE_SMOOTH));
443487
} else {
444488
CHKERR(glDisable(GL_LINE_SMOOTH));
@@ -449,7 +493,7 @@ void GPUDisplayBackendOpenGL::prepareDraw(const hmm_mat4& proj, const hmm_mat4&
449493

450494
glViewport(0, 0, mRenderWidth, mRenderHeight);
451495
#ifndef GPUCA_DISPLAY_OPENGL_CORE
452-
if (!mDisplay->cfgR().openGLCore) {
496+
if (mDisplay->cfgR().rendererCompatSmoothing) {
453497
CHKERR(glEnableClientState(GL_VERTEX_ARRAY));
454498
CHKERR(glVertexPointer(3, GL_FLOAT, 0, nullptr));
455499
} else
@@ -461,7 +505,7 @@ void GPUDisplayBackendOpenGL::prepareDraw(const hmm_mat4& proj, const hmm_mat4&
461505
CHKERR(glEnableVertexAttribArray(0));
462506
}
463507
#ifndef GPUCA_DISPLAY_OPENGL_CORE
464-
if (!mDisplay->cfgR().openGLCore) {
508+
if (mDisplay->cfgR().rendererCompatSmoothing) {
465509
CHKERR(glMatrixMode(GL_PROJECTION));
466510
CHKERR(glLoadMatrixf(&proj.Elements[0][0]));
467511
CHKERR(glMatrixMode(GL_MODELVIEW));
@@ -471,6 +515,13 @@ void GPUDisplayBackendOpenGL::prepareDraw(const hmm_mat4& proj, const hmm_mat4&
471515
{
472516
const hmm_mat4 modelViewProj = proj * view;
473517
CHKERR(glUniformMatrix4fv(UNIFORM_LOCATION_MATRIX, 1, GL_FALSE, &modelViewProj.Elements[0][0]));
518+
if (mUseSmoothPointShader) {
519+
CHKERR(glProgramUniformMatrix4fv(mShaderProgramSmoothPoint, UNIFORM_LOCATION_MATRIX, 1, GL_FALSE, &modelViewProj.Elements[0][0]));
520+
}
521+
if (mUseSmoothLineShader) {
522+
CHKERR(glProgramUniformMatrix4fv(mShaderProgramSmoothLine, UNIFORM_LOCATION_MATRIX, 1, GL_FALSE, &modelViewProj.Elements[0][0]));
523+
CHKERR(glProgramUniform2f(mShaderProgramSmoothLine, UNIFORM_LOCATION_VIEWPORT, mRenderWidth, mRenderHeight));
524+
}
474525
if (mMagneticFieldVisualization) {
475526
CHKERR(glNamedBufferSubData(mFieldModelViewBuffer, 0, sizeof(modelViewProj), &modelViewProj));
476527
}
@@ -480,7 +531,7 @@ void GPUDisplayBackendOpenGL::prepareDraw(const hmm_mat4& proj, const hmm_mat4&
480531
void GPUDisplayBackendOpenGL::finishDraw(bool doScreenshot, bool toMixBuffer, float includeMixImage)
481532
{
482533
#ifndef GPUCA_DISPLAY_OPENGL_CORE
483-
if (!mDisplay->cfgR().openGLCore) {
534+
if (mDisplay->cfgR().rendererCompatSmoothing) {
484535
CHKERR(glDisableClientState(GL_VERTEX_ARRAY));
485536
} else
486537
#endif
@@ -565,7 +616,7 @@ void GPUDisplayBackendOpenGL::mixImages(float mixSlaveImage)
565616
hmm_mat4 proj = HMM_Orthographic(0.f, mRenderWidth, 0.f, mRenderHeight, -1.f, 1.f);
566617
glDisable(GL_DEPTH_TEST);
567618
#ifndef GPUCA_DISPLAY_OPENGL_CORE
568-
if (!mDisplay->cfgR().openGLCore) {
619+
if (mDisplay->cfgR().rendererCompatSmoothing) {
569620
glMatrixMode(GL_MODELVIEW);
570621
glLoadIdentity();
571622
glMatrixMode(GL_PROJECTION);
@@ -584,7 +635,7 @@ void GPUDisplayBackendOpenGL::mixImages(float mixSlaveImage)
584635
CHKERR(glBindTexture(GL_TEXTURE_2D, mMixBuffer.fbCol_id));
585636

586637
#ifndef GPUCA_DISPLAY_OPENGL_CORE
587-
if (!mDisplay->cfgR().openGLCore) {
638+
if (mDisplay->cfgR().rendererCompatSmoothing) {
588639
glColor4f(1, 1, 1, mixSlaveImage);
589640
glBegin(GL_QUADS);
590641
glTexCoord2f(0, 0);
@@ -611,12 +662,22 @@ void GPUDisplayBackendOpenGL::mixImages(float mixSlaveImage)
611662

612663
void GPUDisplayBackendOpenGL::pointSizeFactor(float factor)
613664
{
614-
CHKERR(glPointSize(mDisplay->cfgL().pointSize * mDownsampleFactor * factor));
665+
const float size = mDisplay->cfgL().pointSize * mDownsampleFactor * factor + (mUseSmoothPointShader ? SMOOTH_POINT_EXTRA_SIZE : 0.f);
666+
if (mUseSmoothPointShader) {
667+
CHKERR(glProgramUniform1f(mShaderProgramSmoothPoint, UNIFORM_LOCATION_POINT_SIZE, size));
668+
}
669+
CHKERR(glPointSize(size));
615670
}
616671

617672
void GPUDisplayBackendOpenGL::lineWidthFactor(float factor)
618673
{
619-
CHKERR(glLineWidth(mDisplay->cfgL().lineWidth * mDownsampleFactor * factor));
674+
float width = mDisplay->cfgL().lineWidth * mDownsampleFactor * factor;
675+
if (mUseSmoothLineShader) {
676+
width += SMOOTH_LINE_EXTRA_WIDTH;
677+
CHKERR(glProgramUniform1f(mShaderProgramSmoothLine, UNIFORM_LOCATION_LINE_WIDTH, width));
678+
width *= 1.4143f; // Wide lines are parallelograms in OpenGL, widen so that the perpendicular width is covered
679+
}
680+
CHKERR(glLineWidth(width));
620681
}
621682

622683
void GPUDisplayBackendOpenGL::addFontSymbol(int32_t symbol, int32_t sizex, int32_t sizey, int32_t offsetx, int32_t offsety, int32_t advance, void* data)

‎GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.h‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ class GPUDisplayBackendOpenGL : public GPUDisplayBackend
7272
static uint32_t loadShader(uint32_t type, const char* spirv, size_t size); // Create shader from SPIR-V
7373
static constexpr int32_t UNIFORM_LOCATION_MATRIX = 0; // Explicit uniform locations in the OpenGL variant of the shaders (shaders/*.vert, *.frag)
7474
static constexpr int32_t UNIFORM_LOCATION_COLOR = 4; // color, textColor, alpha
75+
static constexpr int32_t UNIFORM_LOCATION_POINT_SIZE = 5; // vertexSmoothPoint.vert
76+
static constexpr int32_t UNIFORM_LOCATION_VIEWPORT = 6; // vertexSmoothLine.vert
77+
static constexpr int32_t UNIFORM_LOCATION_LINE_WIDTH = 7; // vertexSmoothLine.vert
7578

7679
void addFontSymbol(int32_t symbol, int32_t sizex, int32_t sizey, int32_t offsetx, int32_t offsety, int32_t advance, void* data) override;
7780
void initializeTextDrawing() override;
@@ -84,12 +87,20 @@ class GPUDisplayBackendOpenGL : public GPUDisplayBackend
8487

8588
uint32_t mVertexShader;
8689
uint32_t mFragmentShader;
90+
uint32_t mVertexShaderSmoothPoint;
91+
uint32_t mFragmentShaderSmoothPoint;
92+
uint32_t mVertexShaderSmoothLine;
93+
uint32_t mFragmentShaderSmoothLine;
8794
uint32_t mVertexShaderTexture;
8895
uint32_t mVertexShaderPassthrough;
8996
uint32_t mFragmentShaderTexture;
9097
uint32_t mFragmentShaderText;
9198
uint32_t mGeometryShader;
9299
uint32_t mShaderProgram;
100+
uint32_t mShaderProgramSmoothPoint; // Points with fragmentSmoothPoint.frag, for smoothPoints in the core profile (no GL_POINT_SMOOTH)
101+
bool mUseSmoothPointShader = false;
102+
uint32_t mShaderProgramSmoothLine; // Lines with vertexSmoothLine.vert / fragmentSmoothLine.frag, for smoothLines in the core profile (no GL_LINE_SMOOTH)
103+
bool mUseSmoothLineShader = false;
93104
uint32_t mShaderProgramText;
94105
uint32_t mShaderProgramTexture;
95106
uint32_t mShaderProgramField;

0 commit comments

Comments
 (0)