Skip to content

Commit

Permalink
SL-20606: (WIP) (has debug) Don't use immediate mode emulation for pr…
Browse files Browse the repository at this point in the history
…eview rendering. Miscellaneous cleanup.
  • Loading branch information
cosmic-linden committed Dec 15, 2023
1 parent 1a16a3f commit c22e38d
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 56 deletions.
4 changes: 4 additions & 0 deletions indra/llrender/llvertexbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,10 @@ bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, U32 index,
{
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector4a>& strider, U32 index, S32 count)
{
return VertexBufferStrider<LLVector4a, TYPE_NORMAL>::get(*this, strider, index, count);
}
bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, U32 index, S32 count)
{
return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count);
Expand Down
1 change: 1 addition & 0 deletions indra/llrender/llvertexbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ class LLVertexBuffer final : public LLRefCount
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
bool getTexCoord2Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
bool getNormalStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
bool getNormalStrider(LLStrider<LLVector4a>& strider, U32 index = 0, S32 count = -1);
bool getTangentStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
bool getTangentStrider(LLStrider<LLVector4a>& strider, U32 index=0, S32 count = -1);
bool getColorStrider(LLStrider<LLColor4U>& strider, U32 index=0, S32 count = -1);
Expand Down
6 changes: 6 additions & 0 deletions indra/newview/lldynamictexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
return TRUE;
}

struct DoDebugGL
{
DoDebugGL() { gDebugGL = true; }
~DoDebugGL() { gDebugGL = false; }
} do_debug_gl; // TODO: Remove

LLRenderTarget& bake_target = gPipeline.mAuxillaryRT.deferredScreen;

if (!bake_target.isComplete())
Expand Down
200 changes: 144 additions & 56 deletions indra/newview/llgltfmaterialpreviewmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

#include "llgltfmaterialpreviewmgr.h"

#include <vector>

#include "llavatarappearancedefines.h"
#include "llselectmgr.h"
#include "llviewercamera.h"
Expand Down Expand Up @@ -196,6 +198,115 @@ void LLGLTFPreviewTexture::preRender(BOOL clear_depth)
LLViewerDynamicTexture::preRender(clear_depth);
}


namespace {

struct GLTFPreviewModel
{
GLTFPreviewModel(LLPointer<LLDrawInfo>& info, const LLMatrix4& mat)
: mDrawInfo(info)
, mModelMatrix(mat)
{
mDrawInfo->mModelMatrix = &mModelMatrix;
}
LLPointer<LLDrawInfo> mDrawInfo;
LLMatrix4 mModelMatrix; // Referenced by mDrawInfo
};

// Like LLVolumeGeometryManager::registerFace but without batching or too-many-indices/vertices checking.
std::vector<GLTFPreviewModel> create_preview_sphere(LLPointer<LLFetchedGLTFMaterial>& material, const LLMatrix4& model_matrix)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
#if 1
// Simple shader
const LLColor4U& vertex_color = LLColor4U::white;
#else
// *TODO: PBR + Environment/probe lighting
const LLColor4U vertex_color(material);
#endif

LLPrimitive prim;
prim.init_primitive(LL_PCODE_VOLUME);
LLVolumeParams params;
params.setType(LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE);
params.setBeginAndEndS(0.f, 1.f);
params.setBeginAndEndT(0.f, 1.f);
params.setRatio(1, 1);
params.setShear(0, 0);
constexpr auto MAX_LOD = LLVolumeLODGroup::NUM_LODS - 1;
prim.setVolume(params, MAX_LOD);

LLVolume* volume = prim.getVolume();
llassert(volume);
for (LLVolumeFace& face : volume->getVolumeFaces())
{
face.createTangents();
}

std::vector<GLTFPreviewModel> preview_sphere;
preview_sphere.reserve(volume->getNumFaces());

LLPointer<LLVertexBuffer> buf = new LLVertexBuffer(
LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TANGENT
);
U32 nv = 0;
U32 ni = 0;
for (LLVolumeFace& face : volume->getVolumeFaces())
{
nv += face.mNumVertices;
ni += face.mNumIndices;
}
buf->allocateBuffer(nv, ni);

LLStrider<U16> indices;
LLStrider<LLVector4a> positions;
LLStrider<LLVector4a> normals;
LLStrider<LLVector2> texcoords;
LLStrider<LLColor4U> colors;
LLStrider<LLVector4a> tangents;
buf->getIndexStrider(indices);
buf->getVertexStrider(positions);
buf->getNormalStrider(normals);
buf->getTexCoord0Strider(texcoords);
buf->getColorStrider(colors);
buf->getTangentStrider(tangents);
U32 index_offset = 0;
U32 vertex_offset = 0;
for (const LLVolumeFace& face : volume->getVolumeFaces())
{
for (S32 i = 0; i < face.mNumIndices; ++i)
{
*indices++ = face.mIndices[i] + vertex_offset;
}
for (S32 v = 0; v < face.mNumVertices; ++v)
{
*positions++ = face.mPositions[v];
*normals++ = face.mNormals[v];
*texcoords++ = face.mTexCoords[v];
*colors++ = vertex_color;
*tangents++ = face.mTangents[v];
}

constexpr LLViewerTexture* no_media = nullptr;
LLPointer<LLDrawInfo> info = new LLDrawInfo(U16(vertex_offset), U16(vertex_offset + face.mNumVertices - 1), face.mNumIndices, index_offset, no_media, buf.get());
info->mGLTFMaterial = material;
preview_sphere.emplace_back(info, model_matrix);
index_offset += face.mNumIndices;
vertex_offset += face.mNumVertices;
}

buf->unmapBuffer();

return preview_sphere;
}

}; // namespace


BOOL LLGLTFPreviewTexture::render()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
Expand All @@ -206,81 +317,58 @@ BOOL LLGLTFPreviewTexture::render()
LLGLDisable stencil(GL_STENCIL_TEST);
LLGLDisable scissor(GL_SCISSOR_TEST);

LLViewerCamera camera; // Default camera
LLViewerCamera camera;

constexpr F32 fill_ratio = 0.8f;
// Calculate the object distance at which the object of a given radius will
// span the partial width of the screen given by fill_ratio.
// Assume the primitive has a scale of 1 (this is the default).
constexpr F32 fill_ratio = 0.8f;
constexpr F32 object_radius = 0.5f;
// z_s = (r / alpha) * tan(theta)
const F32 object_distance = (object_radius / fill_ratio) * tan(camera.getDefaultFOV());

const LLVector3 origin(0.0, 0.0, 0.0);
const LLVector3 object_position(0.0, object_distance, 0.0);
LLMatrix4 object_transform;
object_transform.translate(object_position);

// Set up camera and viewport
const LLVector3 origin(0.0, 0.0, 0.0);
camera.lookAt(origin, object_position);

const LLRect texture_rect(0, mFullHeight, mFullWidth, 0);

camera.setAspect(mFullHeight / mFullWidth);
const LLRect texture_rect(0, mFullHeight, mFullWidth, 0);
camera.setPerspective(NOT_FOR_SELECTION, texture_rect.mLeft, texture_rect.mBottom, texture_rect.getWidth(), texture_rect.getHeight(), FALSE, camera.getNear(), MAX_FAR_CLIP*2.f);

glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);

// Generate sphere object on-the-fly. Discard afterwards.
LLPrimitive prim;
prim.init_primitive(LL_PCODE_VOLUME);
{
LLVolumeParams params;
params.setType(LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE);
params.setBeginAndEndS(0.f, 1.f);
params.setBeginAndEndT(0.f, 1.f);
params.setRatio(1, 1);
params.setShear(0, 0);
constexpr auto MAX_LOD = LLVolumeLODGroup::NUM_LODS - 1;
prim.setVolume(params, MAX_LOD);
}
LLVolume* volume = prim.getVolume();
llassert(volume);
// Generate sphere object on-the-fly. Discard afterwards. (Vertex buffer is
// discarded, but the sphere should be cached in LLVolumeMgr.)
std::vector<GLTFPreviewModel> preview_sphere = create_preview_sphere(mGLTFMaterial, object_transform);

{
#if 1
// Simple shader
gDebugProgram.bind();
LLGLState cull(GL_CULL_FACE, TRUE);

LLColor4 debug_color(1.0 / (1.0 + mBestLoad[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]),
1.0 / (1.0 + mBestLoad[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]),
1.0 / (1.0 + mBestLoad[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]),
1.0 / (1.0 + mBestLoad[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]));
gDebugProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, debug_color.mV[VX], debug_color.mV[VY], debug_color.mV[VZ], debug_color.mV[VW]);
// Simple shader
gDebugProgram.bind();
LLGLState cull(GL_CULL_FACE, TRUE);

LLColor4 debug_color(1.0 / (1.0 + mBestLoad[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]),
1.0 / (1.0 + mBestLoad[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]),
1.0 / (1.0 + mBestLoad[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]),
1.0 / (1.0 + mBestLoad[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]));
gDebugProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, debug_color.mV[VX], debug_color.mV[VY], debug_color.mV[VZ], debug_color.mV[VW]);
#else
// *TODO: PBR + Environment/probe lighting
if (mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_OPAQUE)
{
gDeferredPBROpaqueProgram.bind();
}
else
{
gDeferredPBRAlphaProgram.bind();
}
// *TODO: PBR + Environment/probe lighting
constexpr LLViewerTexture* no_media = nullptr;
mGLTFMaterial->bind(no_media);
// *TODO: Normally, the GLTF base color is baked into the vertex color. Need to fix that...
LLGLState cull(GL_CULL_FACE, mGLTFMaterial->mDoubleSided ? FALSE : TRUE);
if (mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_OPAQUE)
{
gDeferredPBROpaqueProgram.bind();
}
else
{
gDeferredPBRAlphaProgram.bind();
}
#endif
LLMatrix4 model_matrix;
model_matrix.translate(object_position);
LLRenderPass::applyModelMatrix(&model_matrix);

// *TODO: Don't use GL immediate mode emulation
LLVertexBuffer::unbind();
for (const LLVolumeFace& face : volume->getVolumeFaces())
{
LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices);
}
for (GLTFPreviewModel& part : preview_sphere)
{
LLRenderPass::pushGLTFBatch(*part.mDrawInfo);
}

return TRUE;
Expand Down

0 comments on commit c22e38d

Please sign in to comment.