You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/RenderDll/XRenderNULL/NULLRenderAuxGeom.cpp

465 lines
15 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "RenderDll_precompiled.h"
#include "NULL_Renderer.h"
#include "NULLRenderAuxGeom.h"
// CryTek undefs some defines from WinBase.h...so let's redefine them here
#if defined(WIN32) || defined(WIN64)
#ifdef UNICODE
#define RegisterClass RegisterClassW
#else
#define RegisterClass RegisterClassA
#endif // !UNICODE
#endif
CNULLRenderAuxGeom* CNULLRenderAuxGeom::s_pThis = NULL;
#ifdef ENABLE_WGL_DEBUG_RENDERER
static const float W = 800.0f;
static const float H = 600.0f;
static const float THETA = 5.0f;
static const Vec3 VUP(0.0f, 0.0f, 1.0f);
bool CNULLRenderAuxGeom::s_active = false;
bool CNULLRenderAuxGeom::s_hidden = true;
void CNULLRenderAuxGeom::EnableOpenGL()
{
CCamera& camera = gEnv->pSystem->GetViewCamera();
camera.SetFrustum(W, H);
const float FOV = camera.GetFov() / PI * 180.0f;
const float PNR = camera.GetNearPlane();
const float PFR = camera.GetFarPlane();
PIXELFORMATDESCRIPTOR pfd;
int format;
// get the device context (DC)
m_hdc = GetDC(m_hwnd);
// set the pixel format for the DC
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ChoosePixelFormat(m_hdc, &pfd);
SetPixelFormat(m_hdc, format, &pfd);
// create and enable the render context (RC)
m_glrc = wglCreateContext(m_hdc);
wglMakeCurrent(m_hdc, m_glrc);
m_qobj = gluNewQuadric();
glShadeModel(GL_FLAT);
glPolygonMode(GL_FRONT, GL_FILL);
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, W, H);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(FOV, W / H, PNR, PFR);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void CNULLRenderAuxGeom::DisableOpenGL()
{
gluDeleteQuadric(m_qobj);
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_glrc);
ReleaseDC(m_hwnd, m_hdc);
}
#endif
CNULLRenderAuxGeom::CNULLRenderAuxGeom(CNULLRenderer& renderer)
: m_renderer(&renderer)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
const char* wndClassName = "DebugRenderer";
// register window class
WNDCLASS wc;
wc.style = CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = wndClassName;
RegisterClass(&wc);
// create main window
m_hwnd = CreateWindow(
wndClassName, wndClassName,
WS_CAPTION | WS_POPUP,
0, 0, W, H,
NULL, NULL, wc.hInstance, NULL);
ShowWindow(m_hwnd, SW_HIDE);
UpdateWindow(m_hwnd);
EnableOpenGL();
m_eye.Set(0.0f, 0.0f, 0.0f);
m_dir.Set(0.0f, 1.0f, 0.0f);
m_up.Set(0.0f, 0.0f, 1.0f);
m_updateSystemView = true;
REGISTER_COMMAND("r_debug_renderer_show_window", DebugRendererShowWindow, VF_NULL, "");
REGISTER_COMMAND("r_debug_renderer_set_eye_pos", DebugRendererSetEyePos, VF_NULL, "");
REGISTER_COMMAND("r_debug_renderer_update_system_view", DebugRendererUpdateSystemView, VF_NULL, "");
#endif
}
CNULLRenderAuxGeom::~CNULLRenderAuxGeom()
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
DisableOpenGL();
DestroyWindow(m_hwnd);
#endif
}
void CNULLRenderAuxGeom::BeginFrame()
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
FUNCTION_PROFILER(gEnv->pSystem, PROFILE_RENDERER);
{
m_dir.normalize();
m_up.normalize();
Vec3 right = m_dir ^ m_up;
if (s_active)
{
Matrix34 m;
m.SetIdentity();
if (GetAsyncKeyState('W') & 0x8000)
{
m.AddTranslation(m_dir);
}
if (GetAsyncKeyState('S') & 0x8000)
{
m.AddTranslation(-m_dir);
}
if (GetAsyncKeyState('A') & 0x8000)
{
m.AddTranslation(-right);
}
if (GetAsyncKeyState('D') & 0x8000)
{
m.AddTranslation(right);
}
m_eye = m * m_eye;
m.SetIdentity();
if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
{
m.SetRotationAA(-PI / 180.0f * THETA, VUP); // !m_up
}
if (GetAsyncKeyState(VK_LEFT) & 0x8000)
{
m.SetRotationAA(PI / 180.0f * THETA, VUP); // !m_up
}
if (GetAsyncKeyState(VK_UP) & 0x8000)
{
m.SetRotationAA(PI / 180.0f * THETA, right);
}
if (GetAsyncKeyState(VK_DOWN) & 0x8000)
{
m.SetRotationAA(-PI / 180.0f * THETA, right);
}
m_up = m * m_up;
m_dir = m * m_dir;
}
if (m_updateSystemView)
{
Matrix34 m(Matrix33::CreateOrientation(m_dir, m_up, 0), m_eye);
gEnv->pSystem->GetViewCamera().SetMatrix(m);
}
else
{
const Matrix34& viewMatrix = gEnv->pSystem->GetViewCamera().GetMatrix();
m_eye = viewMatrix.GetTranslation();
m_dir = viewMatrix.GetColumn1();
m_up = viewMatrix.GetColumn2();
}
}
#endif
}
void CNULLRenderAuxGeom::EndFrame()
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
FUNCTION_PROFILER(gEnv->pSystem, PROFILE_RENDERER);
if (!s_hidden)
{
glLoadIdentity();
Vec3 at = m_eye + m_dir;
gluLookAt(m_eye.x, m_eye.y, m_eye.z, at.x, at.y, at.z, m_up.x, m_up.y, m_up.z);
glClearColor(0.0f, 0.0f, 0.3f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
gluSphere(m_qobj, 1.0f, 32, 32);
glInterleavedArrays(GL_C3F_V3F, 0, &m_points[0]);
glDrawArrays(GL_POINTS, 0, m_points.size());
glInterleavedArrays(GL_C3F_V3F, 0, &m_lines[0]);
glDrawArrays(GL_LINES, 0, m_lines.size() * 2);
for (size_t i = 0; i < m_polyLines.size(); ++i)
{
const SPolyLine& polyline = m_polyLines[i];
glInterleavedArrays(GL_C3F_V3F, 0, &polyline.points[0]);
glDrawArrays(GL_LINE_STRIP, 0, polyline.points.size());
}
glInterleavedArrays(GL_C3F_V3F, 0, &m_triangles[0]);
glDrawArrays(GL_TRIANGLES, 0, m_triangles.size() * 3);
for (size_t i = 0; i < m_spheres.size(); ++i)
{
glColor3fv(m_spheres[i].p.color);
glPushMatrix();
glLoadIdentity();
glTranslatef(m_spheres[i].p.vertex[0], m_spheres[i].p.vertex[1], m_spheres[i].p.vertex[2]);
gluSphere(m_qobj, m_spheres[i].r, 32, 32);
glPopMatrix();
}
glFlush();
SwapBuffers(m_hdc);
}
m_points.resize(0);
m_lines.resize(0);
m_polyLines.resize(0);
m_triangles.resize(0);
m_spheres.resize(0);
#endif
}
void CNULLRenderAuxGeom::DrawPoint([[maybe_unused]] const Vec3& v, [[maybe_unused]] const ColorB& col, [[maybe_unused]] uint8 size /* = 1 */)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
m_points.push_back(SPoint(v, col));
#endif
}
void CNULLRenderAuxGeom::DrawPoints([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB* col, [[maybe_unused]] uint8 size /* = 1 */)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
for (uint32 i = 0; i < numPoints; ++i)
{
m_points.push_back(SPoint(v[i], *col));
}
#endif
}
void CNULLRenderAuxGeom::DrawPoints([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB& col, [[maybe_unused]] uint8 size /* = 1 */)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
for (uint32 i = 0; i < numPoints; ++i)
{
m_points.push_back(SPoint(v[i], col));
}
#endif
}
void CNULLRenderAuxGeom::DrawLine([[maybe_unused]] const Vec3& v0, [[maybe_unused]] const ColorB& colV0, [[maybe_unused]] const Vec3& v1, [[maybe_unused]] const ColorB& colV1, [[maybe_unused]] float thickness /* = 1::0f */)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
m_lines.push_back(SLine(SPoint(v0, colV0), SPoint(v1, colV1)));
#endif
}
void CNULLRenderAuxGeom::DrawLines([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB& col, [[maybe_unused]] float thickness /* = 1::0f */)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
assert((numPoints >= 2) && (0 == (numPoints & 1)));
for (uint32 i = 0; i < numPoints; i += 2)
{
m_lines.push_back(SLine(SPoint(v[i], col), SPoint(v[i + 1], col)));
}
#endif
}
void CNULLRenderAuxGeom::DrawLines([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB* col, [[maybe_unused]] float thickness /* = 1::0f */)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
assert((numPoints >= 2) && (0 == (numPoints & 1)));
for (uint32 i = 0; i < numPoints; i += 2)
{
m_lines.push_back(SLine(SPoint(v[i], *col), SPoint(v[i + 1], *col)));
}
#endif
}
void CNULLRenderAuxGeom::DrawLines([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const vtx_idx* ind, [[maybe_unused]] uint32 numIndices, [[maybe_unused]] const ColorB& col, [[maybe_unused]] float thickness /* = 1::0f */)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
assert(numPoints >= 2);
assert((numIndices >= 2) && (0 == (numIndices & 1)));
for (uint32 i = 0; i < numIndices; i += 2)
{
vtx_idx i0 = ind[i], i1 = ind[i + 1];
assert(i0 < numPoints && i1 < numPoints);
m_lines.push_back(SLine(SPoint(v[i0], col), SPoint(v[i1], col)));
}
#endif
}
void CNULLRenderAuxGeom::DrawLines([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const vtx_idx* ind, [[maybe_unused]] uint32 numIndices, [[maybe_unused]] const ColorB* col, [[maybe_unused]] float thickness /* = 1::0f */)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
assert(numPoints >= 2);
assert((numIndices >= 2) && (0 == (numIndices & 1)));
for (uint32 i = 0; i < numIndices; i += 2)
{
vtx_idx i0 = ind[i], i1 = ind[i + 1];
assert(i0 < numPoints && i1 < numPoints);
m_lines.push_back(SLine(SPoint(v[i0], *col), SPoint(v[i1], *col)));
}
#endif
}
void CNULLRenderAuxGeom::DrawPolyline([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] bool closed, [[maybe_unused]] const ColorB& col, [[maybe_unused]] float thickness /* = 1::0f */)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
assert(numPoints >= 2);
assert(!closed || numPoints >= 3); // if "closed" then we need at least three vertices
m_polyLines.resize(m_polyLines.size() + 1);
SPolyLine& polyline = m_polyLines[m_polyLines.size() - 1];
for (uint32 i = 0; i < numPoints; ++i)
{
polyline.points.push_back(SPoint(v[i], col));
}
if (closed)
{
polyline.points.push_back(SPoint(v[0], col));
}
#endif
}
void CNULLRenderAuxGeom::DrawPolyline([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] bool closed, [[maybe_unused]] const ColorB* col, [[maybe_unused]] float thickness /* = 1::0f */)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
assert(numPoints >= 2);
assert(!closed || numPoints >= 3); // if "closed" then we need at least three vertices
m_polyLines.resize(m_polyLines.size() + 1);
SPolyLine& polyline = m_polyLines[m_polyLines.size() - 1];
for (uint32 i = 0; i < numPoints; ++i)
{
polyline.points.push_back(SPoint(v[i], *col));
}
if (closed)
{
polyline.points.push_back(SPoint(v[0], *col));
}
#endif
}
void CNULLRenderAuxGeom::DrawTriangle([[maybe_unused]] const Vec3& v0, [[maybe_unused]] const ColorB& colV0, [[maybe_unused]] const Vec3& v1, [[maybe_unused]] const ColorB& colV1, [[maybe_unused]] const Vec3& v2, [[maybe_unused]] const ColorB& colV2)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
FUNCTION_PROFILER(gEnv->pSystem, PROFILE_RENDERER);
m_triangles.push_back(STriangle(SPoint(v0, colV0), SPoint(v1, colV1), SPoint(v2, colV2)));
#endif
}
void CNULLRenderAuxGeom::DrawTriangles([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB& col)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
assert((numPoints >= 3) && (0 == (numPoints % 3)));
FUNCTION_PROFILER(gEnv->pSystem, PROFILE_RENDERER);
for (size_t i = 0; i < numPoints; i += 3)
{
m_triangles.push_back(STriangle(SPoint(v[i], col), SPoint(v[i + 1], col), SPoint(v[i + 2], col)));
}
#endif
}
void CNULLRenderAuxGeom::DrawTriangles([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const ColorB* col)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
assert((numPoints >= 3) && (0 == (numPoints % 3)));
FUNCTION_PROFILER(gEnv->pSystem, PROFILE_RENDERER);
for (size_t i = 0; i < numPoints; i += 3)
{
m_triangles.push_back(STriangle(SPoint(v[i], *col), SPoint(v[i + 1], *col), SPoint(v[i + 2], *col)));
}
#endif
}
void CNULLRenderAuxGeom::DrawTriangles([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const vtx_idx* ind, [[maybe_unused]] uint32 numIndices, [[maybe_unused]] const ColorB& col)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
assert(numPoints >= 3);
assert((numIndices >= 3) && (0 == (numIndices % 3)));
FUNCTION_PROFILER(gEnv->pSystem, PROFILE_RENDERER);
for (size_t i = 0; i < numIndices; i += 3)
{
vtx_idx i0 = ind[i], i1 = ind[i + 1], i2 = ind[i + 2];
assert(i0 < numPoints && i1 < numPoints && i2 < numPoints);
m_triangles.push_back(STriangle(SPoint(v[i0], col), SPoint(v[i1], col), SPoint(v[i2], col)));
}
#endif
}
void CNULLRenderAuxGeom::DrawTriangles([[maybe_unused]] const Vec3* v, [[maybe_unused]] uint32 numPoints, [[maybe_unused]] const vtx_idx* ind, [[maybe_unused]] uint32 numIndices, [[maybe_unused]] const ColorB* col)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
assert(numPoints >= 3);
assert((numIndices >= 3) && (0 == (numIndices % 3)));
FUNCTION_PROFILER(gEnv->pSystem, PROFILE_RENDERER);
for (size_t i = 0; i < numIndices; i += 3)
{
vtx_idx i0 = ind[i], i1 = ind[i + 1], i2 = ind[i + 2];
assert(i0 < numPoints && i1 < numPoints && i2 < numPoints);
m_triangles.push_back(STriangle(SPoint(v[i0], *col), SPoint(v[i1], *col), SPoint(v[i2], *col)));
}
#endif
}
void CNULLRenderAuxGeom::DrawSphere([[maybe_unused]] const Vec3& pos, [[maybe_unused]] float radius, [[maybe_unused]] const ColorB& col, [[maybe_unused]] bool drawShaded)
{
#ifdef ENABLE_WGL_DEBUG_RENDERER
m_spheres.push_back(SSphere(SPoint(pos, col), radius));
#endif
}