Implement ShowNormals in RendererGL2
This commit is contained in:
parent
7d0117c183
commit
addf0d9bea
|
|
@ -141,7 +141,140 @@ Draws vertex normals for debugging
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
static void DrawNormals (shaderCommands_t *input) {
|
static void DrawNormals (shaderCommands_t *input) {
|
||||||
//FIXME: implement this
|
if (!input) return;
|
||||||
|
|
||||||
|
const int vertexCount = input->numVertexes;
|
||||||
|
if (vertexCount <= 0 || !input->xyz || !input->normal) return;
|
||||||
|
if (!input->shader || input->shader->isSky) return; // do not draw over sky/clouds
|
||||||
|
if (input->shader->numDeforms > 0) return; // skip vertex-deformed surfaces
|
||||||
|
|
||||||
|
// Skip animated entities that are interpolating; otherwise normals will appear to "swim".
|
||||||
|
if (backEnd.currentEntity != &tr.worldEntity) {
|
||||||
|
const trRefEntity_t* refEnt = backEnd.currentEntity;
|
||||||
|
if (refEnt && refEnt->e.backlerp > 0) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float lineLength = 6.0f;
|
||||||
|
|
||||||
|
// xyz is vec4_t (x,y,z,1)
|
||||||
|
const float* positionsXYZW = (const float*)input->xyz;
|
||||||
|
const int16_t* packedNormals = (const int16_t*)input->normal;
|
||||||
|
const float* floatNormals = (const float*)input->normal;
|
||||||
|
|
||||||
|
const vao_t* boundVao = glState.currentVao;
|
||||||
|
qboolean usePacked = qfalse;
|
||||||
|
|
||||||
|
if (boundVao) {
|
||||||
|
const vaoAttrib_t* a = &boundVao->attribs[ATTR_INDEX_NORMAL];
|
||||||
|
usePacked = (a->type == GL_SHORT && a->normalized);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const float sx = packedNormals[0] * (1.0f / 32767.0f);
|
||||||
|
const float sy = packedNormals[1] * (1.0f / 32767.0f);
|
||||||
|
const float sz = packedNormals[2] * (1.0f / 32767.0f);
|
||||||
|
|
||||||
|
const float lp = sx * sx + sy * sy + sz * sz;
|
||||||
|
const float lf = floatNormals[0] * floatNormals[0]
|
||||||
|
+ floatNormals[1] * floatNormals[1]
|
||||||
|
+ floatNormals[2] * floatNormals[2];
|
||||||
|
|
||||||
|
usePacked = fabsf(lp - 1.0f) <= fabsf(lf - 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
const GLsizeiptr floatsPerVertex = 6;
|
||||||
|
const GLsizeiptr maxFloatCount = floatsPerVertex * (GLsizeiptr)vertexCount;
|
||||||
|
const GLsizeiptr maxByteCount = (GLsizeiptr)sizeof(float) * maxFloatCount;
|
||||||
|
|
||||||
|
float* lineVertices = (float*)ri.Hunk_AllocateTempMemory((int)maxByteCount);
|
||||||
|
float* writePtr = lineVertices;
|
||||||
|
|
||||||
|
// Build the line list
|
||||||
|
for (int i = 0; i < vertexCount; ++i, positionsXYZW += 4) {
|
||||||
|
vec3_t n;
|
||||||
|
|
||||||
|
if (usePacked) {
|
||||||
|
R_VaoUnpackNormal(n, (int16_t*)packedNormals);
|
||||||
|
packedNormals += 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
n[0] = floatNormals[0];
|
||||||
|
n[1] = floatNormals[1];
|
||||||
|
n[2] = floatNormals[2];
|
||||||
|
floatNormals += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// endpoints in object/world space
|
||||||
|
const float startX = positionsXYZW[0];
|
||||||
|
const float startY = positionsXYZW[1];
|
||||||
|
const float startZ = positionsXYZW[2];
|
||||||
|
|
||||||
|
const float endX = startX + n[0] * lineLength;
|
||||||
|
const float endY = startY + n[1] * lineLength;
|
||||||
|
const float endZ = startZ + n[2] * lineLength;
|
||||||
|
|
||||||
|
|
||||||
|
// emit line
|
||||||
|
*writePtr++ = startX; *writePtr++ = startY; *writePtr++ = startZ;
|
||||||
|
*writePtr++ = endX; *writePtr++ = endY; *writePtr++ = endZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GLsizei numVerts = (GLsizei)((writePtr - lineVertices) / 3);
|
||||||
|
if (numVerts == 0) {
|
||||||
|
ri.Hunk_FreeTempMemory(lineVertices);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save bindings
|
||||||
|
GLint prevProg = 0, prevVao = 0, prevArrayBuf = 0;
|
||||||
|
qglGetIntegerv(GL_CURRENT_PROGRAM, &prevProg);
|
||||||
|
qglGetIntegerv(GL_VERTEX_ARRAY_BINDING, &prevVao);
|
||||||
|
qglGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prevArrayBuf);
|
||||||
|
|
||||||
|
GL_BindToTMU(tr.whiteImage, TB_COLORMAP);
|
||||||
|
GL_State(GLS_POLYMODE_LINE);
|
||||||
|
GLboolean prevDepthMask;
|
||||||
|
qglGetBooleanv(GL_DEPTH_WRITEMASK, &prevDepthMask);
|
||||||
|
qglDepthMask(GL_FALSE);
|
||||||
|
|
||||||
|
|
||||||
|
R_BindNullVao();
|
||||||
|
|
||||||
|
// temp VAO/VBO
|
||||||
|
GLuint vao = 0, vbo = 0;
|
||||||
|
qglGenVertexArrays(1, &vao);
|
||||||
|
qglBindVertexArray(vao);
|
||||||
|
|
||||||
|
qglGenBuffers(1, &vbo);
|
||||||
|
qglBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
qglBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * numVerts, lineVertices, GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
shaderProgram_t* program = &tr.textureColorShader;
|
||||||
|
GLSL_BindProgram(program);
|
||||||
|
GLSL_SetUniformMat4(program, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||||
|
|
||||||
|
vec4_t white;
|
||||||
|
VectorSet4(white, 1, 1, 1, 1);
|
||||||
|
GLSL_SetUniformVec4(program, UNIFORM_COLOR, white);
|
||||||
|
|
||||||
|
// position at location 0 in this backend
|
||||||
|
qglEnableVertexAttribArray(ATTR_INDEX_POSITION);
|
||||||
|
qglVertexAttribPointer(ATTR_INDEX_POSITION, 3, GL_FLOAT, GL_FALSE, 0, (const void*)0);
|
||||||
|
|
||||||
|
qglDrawArrays(GL_LINES, 0, numVerts);
|
||||||
|
|
||||||
|
qglDisableVertexAttribArray(ATTR_INDEX_POSITION);
|
||||||
|
|
||||||
|
// restore
|
||||||
|
qglDepthMask(prevDepthMask);
|
||||||
|
qglBindBuffer(GL_ARRAY_BUFFER, prevArrayBuf);
|
||||||
|
qglBindVertexArray(prevVao);
|
||||||
|
qglDeleteBuffers(1, &vbo);
|
||||||
|
qglDeleteVertexArrays(1, &vao);
|
||||||
|
|
||||||
|
if (prevProg) qglUseProgram((GLuint)prevProg);
|
||||||
|
else qglUseProgram(0);
|
||||||
|
|
||||||
|
ri.Hunk_FreeTempMemory(lineVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user