Author Topic: Tron Light Cycle  (Read 11355 times)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1983
    • zapsolution
Re: Tron Light Cycle
« Reply #15 on: January 21, 2018, 02:21:34 pm »
Please, post the full code of the procedure, just to make sure we are using the same.
Because i don't see any visual difference by me...
Patrice
(Always working with the latest Windows version available...)

Michael Lobko-Lobanovsky

  • Administrator
  • *****
  • Posts: 1481
Re: Tron Light Cycle
« Reply #16 on: January 21, 2018, 08:53:29 pm »
Quote
Because i don't see any visual difference by me...

If you don't see the difference then you probably didn't merge my previous code with yours correctly, because the placement of doneBillboard: label was distinctly different as was the order of epilogue function calls.

But never mind, here comes the entire function code:

Code: [Select]
void Mobj_DrawUsingProgrammablePipeline(IN HWND hCheckList, IN long nSpecularMode, IN long nUseTexture) {
    MobjMesh* pMesh = 0;
    MobjMat* pMaterial = 0;

    long nI = 0, nCount = 0, nTexture = 0, nFlagBump = 0, nChecked = -1, nGlassIsUsed = 0, doSpherical = 0;
    long nFlagTextures = Mobj_enableTextures(0, 0); // ML: 11-24-2015

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    long nVertexSize = Mobj_getVertexSize();
    long nMeshes = Mobj_getNumberOfMeshes();
    float rShine = 64.0f; // 128.0f;

    long nClockwise = Mobj_gl_cw(0, 0);
    long nLights = 3; // ML 02-01-2018: keep it a uniform for when number of lights becomes per-material :)
    long nLightFlags = gP.nLightFlags & 7; // ML 02-01-2018: another uniform with respective light on/off bitfield flags

    bool doRefresh = true; // ML 01-18-2018: need or not to refresh current MODELVIEW matrix
    long isBillboard = 0; // ML 01-18-2018: faster local cache (checked twice)

    for (nI = 0; nI < nMeshes; ++nI) {
        if (IsWindow(hCheckList)) {
            nChecked = ListView_GetCheckState(hCheckList, nI);
        }
        if (nChecked) {
            pMesh = Mobj_getMesh(nI);
            pMaterial = pMesh->pMaterial;
            isBillboard = pMaterial->isBillboard; // ML 01-18-2018:

            if (!isSphereInFrustum(grm_frustum, pMesh->centerPoint, pMesh->meshRadius)) continue; // ML: 03-14-2016

            if (pMaterial->isA2C) { glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); } // PAT: 01-07-2018

            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pMaterial->ambient);
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pMaterial->diffuse);
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pMaterial->specular);
            glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, pMaterial->emissive); // ML 01-02-2018: glow
            glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, pMaterial->shininess * rShine);

            pMaterial->ambient[3] = pMaterial->alpha;
            pMaterial->diffuse[3] = pMaterial->alpha;
            pMaterial->specular[3] = pMaterial->alpha;
            pMaterial->emissive[3] = pMaterial->alpha; // ML 01-02-2018: glow

            nTexture = 0;
            doSpherical = 0; // ML: 11-26-2015
            if ((pMaterial->alpha < 1.0f) || (pMaterial->illum == 12)) { nGlassIsUsed = -1; } // 11-27-2015

            // 12-09-2015 ML: !!! can't do "Specular mode" in multishader !!!
            // ML 01-18-2018: diffuse only mapping for billboards for now
            if (!pMaterial->bumpMapID || nSpecularMode || isBillboard) {

                // Per fragment Blinn-Phong code path.
                glUseProgram(gnm_BlinnPhongShader);

                // Bind the color map texture.  // ML: 11-26-2015
                glActiveTexture(GL_TEXTURE0);
                glEnable(GL_TEXTURE_2D);
                if (nFlagTextures && !nSpecularMode) { // ML: 12-09-2015
                    if ((pMaterial->reflMapID) && (pMaterial->illum > 2)) { // 11-13-2015
                        doSpherical = 1;
                        if ((pMaterial->illum == 4) || (pMaterial->illum == 11)) { // global reflection
                            nTexture = nUseTexture;
                        } else {                     // individual reflection
                            nTexture = pMaterial->reflMapID;
                        }
                    } else if (pMaterial->illum == 11) {
                        doSpherical = 1;
                        nTexture = nUseTexture;
                    } else {
                        nTexture = pMaterial->colorMapID;
                        if (nTexture == 0) { nTexture = gnm_NullTexture; }
                    }
                } else {
                    if (nSpecularMode) {
                        doSpherical = 1;
                        if (nFlagTextures) {
                            if ((pMaterial->reflMapID) && (pMaterial->illum > 2)) {
                                nTexture = pMaterial->reflMapID;
                            } else {
                                nTexture = pMaterial->colorMapID;
                            }
                            if (nTexture == 0) { nTexture = nUseTexture; }
                        } else {
                            nTexture = nUseTexture;
                        }
                    } else {
                        nTexture = gnm_NullTexture;
                    }
                }
                GL_BindTexture(GL_TEXTURE_2D, nTexture);

                if (isBillboard) { // ML 01-18-2018: let it ride w/o shaders for the time being
                    cylindricalBillBoard(pMesh->centerPoint, pMesh->meshRadius, &doRefresh, isBillboard == -2);
                    goto doneBillboard;
                }

                // Update shader parameters.
                glUniform1i(glGetUniformLocation(gnm_BlinnPhongShader, "colorMap"), 0);
                glUniform1i(glGetUniformLocation(gnm_BlinnPhongShader, "nLights"), nLights); // ML: 12-11-2015
                glUniform1i(glGetUniformLocation(gnm_BlinnPhongShader, "nLightFlags"), nLightFlags); // ML 02-01-2018:
                glUniform1i(glGetUniformLocation(gnm_BlinnPhongShader, "doSpherical"), doSpherical); // ML: 11-26-2015
                glUniform1f(glGetUniformLocation(gnm_BlinnPhongShader, "materialAlpha"), pMaterial->alpha);

            } else {

                // Normal mapping code path.
                glUseProgram(gnm_NormalMappingShader);

                // Bind the specular map texture. // ML: 11-05-2015
                glActiveTexture(GL_TEXTURE2); nFlagBump = -1;
                glEnable(GL_TEXTURE_2D);
                glUniform1i(glGetUniformLocation(gnm_NormalMappingShader, "sSpecmap"), 2);
                if (nFlagTextures) { // ML: 11-24-2015
                    if (pMaterial->specMapID) {
                        nTexture = pMaterial->specMapID;
                    } else {
                        if (pMaterial->colorMapID) {
                            nTexture = pMaterial->colorMapID; // !!! ML: LEAVE IT BE !!!
                        } else {
                            nTexture = gnm_NullTexture;
                        }
                    }
                } else {
                    nTexture = gnm_NullTexture;
                }
                glBindTexture(GL_TEXTURE_2D, nTexture);

                // Bind the normal map texture. // ML: 11-05-2015
                glActiveTexture(GL_TEXTURE1); nFlagBump = -1;
                glEnable(GL_TEXTURE_2D);
                glUniform1i(glGetUniformLocation(gnm_NormalMappingShader, "sNormalmap"), 1);
                if (nFlagTextures) { // ML: 11-24-2015
                    if (pMaterial->bumpMapID) {
                        nTexture = pMaterial->bumpMapID;
                    } else {
                        nTexture = gnm_NullBump;
                    }
                } else {
                    nTexture = gnm_NullBump;
                }
                glBindTexture(GL_TEXTURE_2D, nTexture);

                // Bind the color map texture.
                glActiveTexture(GL_TEXTURE0);
                glEnable(GL_TEXTURE_2D);
                glUniform1i(glGetUniformLocation(gnm_NormalMappingShader, "sBasemap"), 0);
                if (nFlagTextures) { // ML: 11-24-2015
                    if (pMaterial->colorMapID) {
                        nTexture = pMaterial->colorMapID;
                    } else {
                        nTexture = gnm_NullTexture;
                    }
                } else {
                    nTexture = gnm_NullTexture;
                }
                glBindTexture(GL_TEXTURE_2D, nTexture);

                glUniform1i(glGetUniformLocation(gnm_NormalMappingShader, "nLights"), nLights); // ML: 12-11-2015
                glUniform1i(glGetUniformLocation(gnm_NormalMappingShader, "nLightFlags"), nLightFlags); // ML 02-01-2018:
                glUniform1f(glGetUniformLocation(gnm_NormalMappingShader, "materialAlpha"), pMaterial->alpha);
            }

            // Render mesh.
            glClientActiveTexture(GL_TEXTURE0);
            if (Mobj_hasPositions()) {
                glEnableClientState(GL_VERTEX_ARRAY);
                glVertexPointer(3, GL_FLOAT, nVertexSize, Mobj_getVertexBufferPosition());
            }

            if (Mobj_hasTextureCoords()) {
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                glTexCoordPointer(2, GL_FLOAT, nVertexSize, Mobj_getVertexBufferTexCoord());
            }

            if (Mobj_hasNormals()) {
                glEnableClientState(GL_NORMAL_ARRAY);
                glNormalPointer(GL_FLOAT, nVertexSize, Mobj_getVertexBufferNormal());
            }

            if (Mobj_hasTangents()) {
                glClientActiveTexture(GL_TEXTURE1);
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                glTexCoordPointer(4, GL_FLOAT, nVertexSize, Mobj_getVertexBufferTangent());
            }

            if (nFlagBump) {
                // ML: 11-05-2015
                if (Mobj_hasTextureCoords()) {
                    glClientActiveTexture(GL_TEXTURE2);
                    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                    glTexCoordPointer(2, GL_FLOAT, nVertexSize, Mobj_getVertexBufferTexCoord());
                }
            }

            nCount = pMesh->triangleCount * 3;
            const GLvoid* indices = Mobj_getIndexBuffer() + pMesh->startIndex;

            if (nGlassIsUsed) {  // if we are using transparency then get rid of artefacts
                glEnable(GL_CULL_FACE);
                glFrontFace(nClockwise ? GL_CCW : GL_CW);
                glDrawElements(GL_TRIANGLES, nCount, GL_UNSIGNED_INT, indices);
                glFrontFace(nClockwise ? GL_CW : GL_CCW);
            }

            glDrawElements(GL_TRIANGLES, nCount, GL_UNSIGNED_INT, indices);

            if (nGlassIsUsed) { // 11-27-2015
                if (!Mobj_CullBackFace(0, 0)) { glDisable(GL_CULL_FACE); }
            }

            if (nFlagBump) { // ML: 11-05-2015
                glActiveTexture(GL_TEXTURE2);
                glBindTexture(GL_TEXTURE_2D, 0);
                glDisable(GL_TEXTURE_2D);
                if (Mobj_hasTextureCoords()) {
                    glClientActiveTexture(GL_TEXTURE2);
                    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                }
                nFlagBump = 0;
            } else { // ML 01-18-2018: else it's impossible to get rid of these shitty tex coords in immediate mode!
                if (doSpherical) {
                    glUniform1i(glGetUniformLocation(gnm_BlinnPhongShader, "doSpherical"), 0);
                }
            }

            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_2D, 0);
            glDisable(GL_TEXTURE_2D);

            if (Mobj_hasTangents()) {
                glClientActiveTexture(GL_TEXTURE1);
                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
            }

doneBillboard: // ML 01-21-2018: immediate mode for billboards is emulated by the OpenGL driver with an intrinsic shader,
               // so our billboard epilogue should also include disabling client states even though we didn't enable them.
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, 0);
            glClientActiveTexture(GL_TEXTURE0);

            if (Mobj_hasNormals()) { glDisableClientState(GL_NORMAL_ARRAY); }

            if (Mobj_hasTextureCoords()) { glDisableClientState(GL_TEXTURE_COORD_ARRAY); }

            if (Mobj_hasPositions()) { glDisableClientState(GL_VERTEX_ARRAY); }

            if (pMaterial->isA2C) { glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); } // PAT: 01-07-2018
        }
    }

    glUseProgram(0);
    glDisable(GL_BLEND);
}
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1983
    • zapsolution
Re: Tron Light Cycle
« Reply #17 on: January 21, 2018, 09:50:51 pm »
Thank you!
Patrice
(Always working with the latest Windows version available...)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1983
    • zapsolution
Re: Tron Light Cycle
« Reply #18 on: January 22, 2018, 10:53:50 pm »
Playing with colors...
Patrice
(Always working with the latest Windows version available...)

Michael Lobko-Lobanovsky

  • Administrator
  • *****
  • Posts: 1481
Re: Tron Light Cycle
« Reply #19 on: January 23, 2018, 12:51:08 am »
I am glad you enjoy our new options. :)
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)