Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ list(APPEND CLDLL_SOURCES
# render source files
file(GLOB RENDER_SOURCES "render/*.cpp")

# render visualizer source files
file(GLOB RENDER_VISUALIZER_SOURCES "render/visualizer/*.cpp")

# entity wrappers source files
file(GLOB ENTITIES_SOURCES "entities/*.cpp")

Expand All @@ -93,6 +96,7 @@ if(NOT ENABLE_VGUI_COMPATIBILITY)
endif()

list(APPEND CLDLL_SOURCES ${RENDER_SOURCES})
list(APPEND CLDLL_SOURCES ${RENDER_VISUALIZER_SOURCES})
list(APPEND CLDLL_SOURCES ${ENTITIES_SOURCES})
list(APPEND CLDLL_SOURCES ${GAME_EVENTS_SOURCES})
list(APPEND CLDLL_SOURCES ${WEAPONS_SHARED_SOURCES})
Expand Down
2 changes: 2 additions & 0 deletions client/render/gl_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ GNU General Public License for more details.
#include "vector.h"
#include <matrix.h>
#include "material.h"
#include "debug_visualizer.h"

#define ACTUAL_GL_VERSION 30.0f

Expand Down Expand Up @@ -627,6 +628,7 @@ typedef struct

// cull info
Vector modelorg; // relative to viewpoint
CDebugVisualizer debugVisualizer;
} ref_globals_t;

typedef struct
Expand Down
2 changes: 2 additions & 0 deletions client/render/gl_rmisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ GNU General Public License for more details.
#include "gl_debug.h"
#include "gl_unit_cube.h"
#include "r_weather.h"
#include "visualizer/debug_visualizer.h"

#define DEFAULT_SMOOTHNESS 0.0f
#define FILTER_SIZE 2
Expand Down Expand Up @@ -915,6 +916,7 @@ void R_VidInit( void )
glState.height = RENDER_GET_PARM( PARM_SCREEN_HEIGHT, 0 );

COpenGLUnitCube::GetInstance().Initialize();
CDebugVisualizer::GetInstance().Initialize();
R_InitCommonTextures();
R_InitCubemapShaders();

Expand Down
166 changes: 166 additions & 0 deletions client/render/visualizer/debug_visualizer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#include "gl_local.h"
#include "debug_visualizer.h"

CDebugVisualizer g_DebugVisualizer;

CDebugVisualizer& CDebugVisualizer::GetInstance()
{
return g_DebugVisualizer;
}

void CDebugVisualizer::Initialize()
{
if (m_bInitialized)
return;

// reserve memory for line buffers
m_noDepthLines.reserve(1024);
m_depthLines.reserve(1024);

// load debug shader
word shaderHandle = GL_FindShader("common/debug_draw", "common/debug_draw", "common/debug_draw");
m_DebugShader.SetShader(shaderHandle);

// create VAO and VBO
pglGenVertexArrays(1, &m_iVAO);
pglGenBuffersARB(1, &m_iVBO);

// fill buffer
pglBindBufferARB(GL_ARRAY_BUFFER_ARB, m_iVBO);
pglBufferDataARB(GL_ARRAY_BUFFER_ARB, MAX_DEBUG_VBO_SIZE * sizeof(SLineVertex), nullptr, GL_DYNAMIC_DRAW_ARB);

// link vertex attributes
pglBindVertexArray(m_iVAO);

pglEnableVertexAttribArrayARB(ATTR_INDEX_POSITION);
pglVertexAttribPointerARB(ATTR_INDEX_POSITION, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);

pglEnableVertexAttribArrayARB(/*ATTR_INDEX_TANGENT*/ATTR_INDEX_LIGHT_COLOR);
pglVertexAttribPointerARB(/*ATTR_INDEX_TANGENT*/ATTR_INDEX_LIGHT_COLOR, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));

pglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
pglBindVertexArray(0);

m_bInitialized = true;
}

void CDebugVisualizer::Shutdown()
{
// Release ? TODO...
}

void CDebugVisualizer::Render()
{
GL_BindShader(m_DebugShader.GetShader());

// Render lines with depth buffer
RenderLines(m_depthLines, true);

// ... and without
RenderLines(m_noDepthLines, false);
}

void CDebugVisualizer::RenderLines(const std::vector<SLineVertex>& lines, bool isDepthEnabled)
{
if (lines.empty())
return;

if (isDepthEnabled)
pglEnable(GL_DEPTH_TEST);
else
pglDisable(GL_DEPTH_TEST);

// bind vertex buffer
pglBindVertexArray(m_iVAO);
pglBindBufferARB(GL_ARRAY_BUFFER_ARB, m_iVBO);

size_t offset = 0;
while (offset < lines.size())
{
const size_t kLineVertexLimit = MAX_DEBUG_VBO_SIZE;

size_t drawCount = std::min(kLineVertexLimit, lines.size() - offset);

// Update vertex buffer
//pglBufferDataARB(GL_ARRAY_BUFFER_ARB, drawCount * sizeof(SLineVertex), lines.data() + offset, GL_DYNAMIC_DRAW_ARB);
pglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, drawCount * sizeof(SLineVertex), lines.data() + offset);
pglDrawArrays(GL_LINES, 0, lines.size());

offset += drawCount;
}

// TODO: return depth back
}

void CDebugVisualizer::DrawLine(const Vector& start, const Vector& end, Vector color, float lifespan, bool depthTest)
{
SLineVertex vertexA = { start, color };
SLineVertex vertexB = { end, color };

std::vector<SLineVertex>& lines = depthTest ? m_depthLines : m_noDepthLines;
lines.push_back(vertexA);
lines.push_back(vertexB);
}

void CDebugVisualizer::DrawAABB(const Vector &mins, const Vector &maxs, Vector color, float lifespan, bool depthTest)
{
Vector from = Vector(mins.x, mins.y, mins.z);
Vector to = Vector(maxs.x, maxs.y, maxs.z);

Vector halfExtents = (to - from) * 0.5f;
Vector center = (to + from) * 0.5f;

Vector edgecoord(1.f, 1.f, 1.f), pa, pb;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
pa = Vector(edgecoord[0] * halfExtents[0], edgecoord[1] * halfExtents[1],
edgecoord[2] * halfExtents[2]);
pa += center;

int othercoord = j % 3;
edgecoord[othercoord] *= -1.f;
pb = Vector(edgecoord[0] * halfExtents[0], edgecoord[1] * halfExtents[1],
edgecoord[2] * halfExtents[2]);
pb += center;

DrawLine(pa, pb, color, lifespan, depthTest);
}

edgecoord = Vector(-1.f, -1.f, -1.f);
if (i < 3)
edgecoord[i] *= -1.f;
}
}

void CDebugVisualizer::DrawSphere(const Vector& center, float radius, Vector color, float lifespan, bool depthTest)
{
std::vector<SLineVertex>& lines = depthTest ? m_depthLines : m_noDepthLines;

const uint latitudeDivisions = 8;
const uint longitudeDivisions = 8;
uint voffset = lines.size();
uint count = (latitudeDivisions + 1) * (longitudeDivisions + 1);
for (uint lat = 0; lat <= latitudeDivisions; ++lat) {
float theta = (float)lat * M_PI / (float)latitudeDivisions;
for (uint lon = 0; lon <= longitudeDivisions; ++lon) {
float phi = (float)lon * M_PI2 / (float)longitudeDivisions;
lines.push_back({ {
center.x + radius * sin(theta) * cos(phi),
center.y + radius * sin(theta) * sin(phi),
center.z + radius * cos(theta) },
color });
}
}
}

void CDebugVisualizer::DrawVector(const Vector& position, const Vector& direction, Vector color, float lifespan, bool depthTest)
{
DrawLine(position, (position + direction) * position.Length(), color, lifespan, depthTest);
}

void CDebugVisualizer::DrawFrustum(const CFrustum& frustum, Vector color, float lifespan, bool depthTest)
{
// TODO
}
47 changes: 47 additions & 0 deletions client/render/visualizer/debug_visualizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once
#include "vector.h"
#include "gl_frustum.h"
#include "shader.h"

#define MAX_DEBUG_VBO_SIZE 1024 * 1024

struct SLineVertex
{
Vector position;
Vector color;
};

class CDebugVisualizer
{
public:
static CDebugVisualizer& GetInstance();

public:
void Initialize();
void Shutdown();

void Render();

void DrawLine(const Vector &start, const Vector& end, Vector color, float lifespan, bool depthTest);
void DrawAABB(const Vector &mins, const Vector &maxs, Vector color, float lifespan, bool depthTest);
void DrawSphere(const Vector &center, float radius, Vector color, float lifespan, bool depthTest);
void DrawVector(const Vector &position, const Vector& direction, Vector color, float lifespan, bool depthTest);
void DrawFrustum(const CFrustum &frustum, Vector color, float lifespan, bool depthTest);
// and so on...

private:
void RenderLines(const std::vector<SLineVertex>& lines, bool isDepthEnabled);

private:
std::vector<SLineVertex> m_noDepthLines;
std::vector<SLineVertex> m_depthLines;

shader_t m_DebugShader;

GLuint m_iVAO = 0;
GLuint m_iVBO = 0;

bool m_bInitialized = false;
};

extern CDebugVisualizer g_DebugVisualizer;
21 changes: 21 additions & 0 deletions game_dir/glsl/common/debug_draw_fp.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
debug_draw_vp.glsl - debug draw
Copyright (C) 2025 ugo_zapad

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/

varying vec3 var_Color;

void main()
{
gl_FragColor = vec4(var_Color, 1.0);
}
28 changes: 28 additions & 0 deletions game_dir/glsl/common/debug_draw_vp.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
debug_draw_vp.glsl - debug draw
Copyright (C) 2025 ugo_zapad

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/

attribute vec3 attr_Position;
attribute vec3 attr_Normal; // Color

uniform mat4 u_ModelMatrix; // model-view matrix
uniform mat4 u_ProjectionMatrix; // projection matrix

varying vec3 var_Color;

void main()
{
var_Color = attr_Normal;
gl_Position = u_ProjectionMatrix * u_ModelMatrix * vec4(attr_Position, 1.0);
}
Loading