//--------------------------------------- VOX LIBRARY BEGINS --------------------------------------- #ifdef USE_OPENGL #include "compat.h" #include "build.h" #include "engine_priv.h" #include "polymost.h" #include "mdsprite.h" #include "v_video.h" #include "flatvertices.h" #include "hw_renderstate.h" #include "texturemanager.h" #include "voxels.h" #include "glbackend/gl_models.h" #include "printf.h" #include "palette.h" #include "../../glbackend/glbackend.h" using namespace Polymost; void voxfree(voxmodel_t *m) { if (!m) return; Xfree(m); } voxmodel_t *voxload(int lumpnum) { FVoxel* voxel = R_LoadKVX(lumpnum); if (voxel != nullptr) { voxmodel_t* vm = (voxmodel_t*)Xmalloc(sizeof(voxmodel_t)); memset(vm, 0, sizeof(voxmodel_t)); auto pivot = voxel->Mips[0].Pivot; vm->mdnum = 1; //VOXel model id vm->scale = vm->bscale = 1.f; vm->piv.x = float(pivot.X); vm->piv.y = float(pivot.Y); vm->piv.z = float(pivot.Z); vm->siz.x = voxel->Mips[0].SizeX; vm->siz.y = voxel->Mips[0].SizeY; vm->siz.z = voxel->Mips[0].SizeZ; vm->is8bit = true; voxel->Mips[0].Pivot.Zero(); // Needs to be taken out of the voxel data because it gets baked into the vertex buffer which we cannot use here. vm->model = new FVoxelModel(voxel, true); return vm; } return nullptr; } //Draw voxel model as perfect cubes // Note: This is a hopeless mess that totally forfeits any chance of using a vertex buffer with its messy coordinate adjustments. :( int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr) { float f, g, k0, zoff; if ((intptr_t)m == (intptr_t)(-1)) // hackhackhack return 0; if ((tspr->cstat & 48) == 32) return 0; vec3f_t m0 = { m->scale, m->scale, m->scale }; vec3f_t a0 = { 0, 0, m->zadd*m->scale }; k0 = m->bscale / 64.f; f = (float) tspr->xrepeat * (256.f/320.f) * k0; if ((sprite[tspr->owner].cstat&48)==16) { f *= 1.25f; a0.y -= tspr->xoffset * bcosf(spriteext[tspr->owner].angoff, -20); a0.x += tspr->xoffset * bsinf(spriteext[tspr->owner].angoff, -20); } if (globalorientation&8) { m0.z = -m0.z; a0.z = -a0.z; } //y-flipping if (globalorientation&4) { m0.x = -m0.x; a0.x = -a0.x; a0.y = -a0.y; } //x-flipping m0.x *= f; a0.x *= f; f = -f; m0.y *= f; a0.y *= f; f = (float) tspr->yrepeat * k0; m0.z *= f; a0.z *= f; k0 = (float) (tspr->z+spriteext[tspr->owner].position_offset.z); f = ((globalorientation&8) && (sprite[tspr->owner].cstat&48)!=0) ? -4.f : 4.f; k0 -= (tspr->yoffset*tspr->yrepeat)*f*m->bscale; zoff = m->siz.z*.5f; if (!(tspr->cstat&128)) zoff += m->piv.z; else if ((tspr->cstat&48) != 48) { zoff += m->piv.z; zoff -= m->siz.z*.5f; } if (globalorientation&8) zoff = m->siz.z-zoff; f = (65536.f*512.f) / ((float)xdimen*viewingrange); g = 32.f / ((float)xdimen*gxyaspect); int const shadowHack = !!(tspr->clipdist & TSPR_FLAGS_MDHACK); m0.y *= f; a0.y = (((float)(tspr->x+spriteext[tspr->owner].position_offset.x-globalposx)) * (1.f/1024.f) + a0.y) * f; m0.x *=-f; a0.x = (((float)(tspr->y+spriteext[tspr->owner].position_offset.y-globalposy)) * -(1.f/1024.f) + a0.x) * -f; m0.z *= g; a0.z = (((float)(k0 -globalposz - shadowHack)) * -(1.f/16384.f) + a0.z) * g; float mat[16]; md3_vox_calcmat_common(tspr, &a0, f, mat); //Mirrors if (grhalfxdown10x < 0) { mat[0] = -mat[0]; mat[4] = -mat[4]; mat[8] = -mat[8]; mat[12] = -mat[12]; } if (shadowHack) { GLInterface.SetDepthFunc(DF_LEqual); } int winding = ((grhalfxdown10x >= 0) ^ ((globalorientation & 8) != 0) ^ ((globalorientation & 4) != 0)) ? Winding_CW : Winding_CCW; GLInterface.SetCull(Cull_Back, winding); float pc[4]; pc[0] = pc[1] = pc[2] = 1.f; if (!shadowHack) { pc[3] = (tspr->cstat & 2) ? glblend[tspr->blend].def[!!(tspr->cstat & 512)].alpha : 1.0f; pc[3] *= 1.0f - spriteext[tspr->owner].alpha; SetRenderStyleFromBlend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512)); if (!(tspr->cstat & 2) || spriteext[tspr->owner].alpha > 0.f || pc[3] < 1.0f) GLInterface.EnableBlend(true); // else GLInterface.EnableBlend(false); } else pc[3] = 1.f; GLInterface.SetShade(std::max(0, globalshade), numshades); //------------ //transform to Build coords float omat[16]; memcpy(omat, mat, sizeof(omat)); f = 1.f/64.f; g = m0.x*f; mat[0] *= g; mat[1] *= g; mat[2] *= g; g = m0.y*f; mat[4] = omat[8]*g; mat[5] = omat[9]*g; mat[6] = omat[10]*g; g =-m0.z*f; mat[8] = omat[4]*g; mat[9] = omat[5]*g; mat[10] = omat[6]*g; // mat[12] -= (m->piv.x*mat[0] + m->piv.y*mat[4] + zoff*mat[8]); mat[13] -= (m->piv.x*mat[1] + m->piv.y*mat[5] + zoff*mat[9]); mat[14] -= (m->piv.x*mat[2] + m->piv.y*mat[6] + zoff*mat[10]); // //Let OpenGL (and perhaps hardware :) handle the matrix rotation mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; for (int i = 0; i < 15; i++) mat[i] *= 1024.f; // Adjust to backend coordinate system being used by the vertex buffer. for (int i = 4; i < 8; i++) { float f = mat[i]; mat[i] = -mat[i + 4]; mat[i + 4] = -f; } GLInterface.SetMatrix(Matrix_Model, mat); int palId = TRANSLATION(Translation_Remap + curbasepal, globalpal); GLInterface.SetPalswap(globalpal); GLInterface.SetFade(sector[tspr->sectnum].floorpal); auto tex = TexMan.GetGameTexture(m->model->GetPaletteTexture()); GLInterface.SetTexture(tex, TRANSLATION(Translation_Remap + curbasepal, globalpal), CLAMP_NOFILTER_XY, true); GLInterface.SetModel(m->model, 0, 0, 0); GLInterface.Draw(DT_Triangles, 0, 0); GLInterface.SetModel(nullptr, 0, 0, 0); GLInterface.SetCull(Cull_None); if (shadowHack) { GLInterface.SetDepthFunc(DF_Less); } GLInterface.SetIdentityMatrix(Matrix_Model); return 1; } extern char* voxfilenames[MAXVOXELS]; void (*PolymostProcessVoxels_Callback)(void) = NULL; void PolymostProcessVoxels(void) { if (PolymostProcessVoxels_Callback) PolymostProcessVoxels_Callback(); if (g_haveVoxels != 1) return; g_haveVoxels = 2; Printf(PRINT_NONOTIFY, "Generating voxel models for Polymost. This may take a while...\n"); for (bssize_t i = 0; i < MAXVOXELS; i++) { if (voxfilenames[i]) { int lumpnum = fileSystem.FindFile(voxfilenames[i]); if (lumpnum >= 0) { voxmodels[i] = voxload(lumpnum); voxmodels[i]->scale = voxscale[i] * (1.f / 65536.f); } DO_FREE_AND_NULL(voxfilenames[i]); } } } #endif //---------------------------------------- VOX LIBRARY ENDS ----------------------------------------