示例#1
0
void RenderFaceShadow (tFaceProps *propsP)
{
	int				i, nVertices = propsP->nVertices;
	g3sPoint			*p;
	CFloatVector	v [9];

for (i = 0; i < nVertices; i++) {
	p = gameData.segs.points + propsP->vp [i];
	if (p->p3_index < 0)
		v [i].Assign (p->p3_vec);
	else
		memcpy (v + i, gameData.render.vertP + p->p3_index, sizeof (CFloatVector));
	}
v [nVertices] = v [0];
ogl.EnableClientState (GL_VERTEX_ARRAY);
OglVertexPointer (3, GL_FLOAT, 0, v);
#if DBG_SHADOWS
if (bShadowTest) {
	if (bFrontCap)
		OglDrawArrays (GL_LINE_LOOP, 0, nVertices);
	}
else
#endif
OglDrawArrays (GL_TRIANGLE_FAN, 0, nVertices);
#if DBG_SHADOWS
if (!bShadowTest || bShadowVolume)
#endif
for (i = 0; i < nVertices; i++)
	G3RenderShadowVolumeFace (v + i);
ogl.DisableClientState (GL_VERTEX_ARRAY);
#if DBG_SHADOWS
if (!bShadowTest || bRearCap)
#endif
G3RenderFarShadowCapFace (v, nVertices);
}
示例#2
0
void RenderWireFrame (CSegFace *faceP, int bTextured)
{
    if (gameOpts->render.debug.bWireFrame) {
        if ((nDbgFace < 0) || (faceP - FACES.faces == nDbgFace)) {
            tFaceTriangle	*triP = FACES.tris + faceP->nTriIndex;
            ogl.DisableClientState (GL_COLOR_ARRAY);
            if (bTextured)
                glDisable (GL_TEXTURE_2D);
            glColor3f (1.0f, 0.5f, 0.0f);
            glLineWidth (6);
            glBegin (GL_LINE_LOOP);
            for (int i = 0; i < 4; i++)
                glVertex3fv (reinterpret_cast<GLfloat*> (gameData.segs.fVertices + faceP->index [i]));
            glEnd ();
            if (gameStates.render.bTriangleMesh) {
                glLineWidth (2);
                glColor3f (1,1,1);
                for (int i = 0; i < faceP->nTris; i++, triP++)
                    OglDrawArrays (GL_LINE_LOOP, triP->nIndex, 3);
                glLineWidth (1);
            }
            if (gameOpts->render.debug.bDynamicLight)
                ogl.EnableClientState (GL_COLOR_ARRAY);
            if (bTextured)
                glEnable (GL_TEXTURE_2D);
        }
        glLineWidth (1);
    }
}
示例#3
0
文件: glare.cpp 项目: paud/d2x-xl
void RenderSoftGlare (CFloatVector *sprite, CFloatVector *vCenter, int nTexture, float fIntensity, int bAdditive, int bColored)
{
	tRgbaColorf color;
	tTexCoord2f	tcGlare [4] = {{{0,0}},{{1,0}},{{1,1}},{{0,1}}};
	int 			i;
	CBitmap*		bmP = NULL;

if (gameStates.render.bQueryCoronas) {
	glDisable (GL_TEXTURE_2D);
	glBlendFunc (GL_ONE, GL_ZERO);
	}
else {
	glEnable (GL_TEXTURE_2D);
	glDepthFunc (GL_ALWAYS);
	if (bAdditive)
		glBlendFunc (GL_ONE, GL_ONE);
	if (!(bmP = bAdditive ? bmpGlare : bmpCorona))
		return;
	}
if (gameStates.render.bAmbientColor)
	color = gameData.render.color.textures [nTexture].color;
else
	color.red = color.green = color.blue = X2F (IsLight (nTexture)) / 2;
if (!bColored)
	color.red = color.green = color.blue = (color.red + color.green + color.blue) / 4;
if (gameOptions [0].render.coronas.nStyle == 1)
	fIntensity = float (sqrt (fIntensity));
if (bAdditive)
	glColor4f (fIntensity * color.red, fIntensity * color.green, fIntensity * color.blue, 1);
else
	glColor4f (color.red, color.green, color.blue, fIntensity);
if (ogl.EnableClientStates (gameStates.render.bQueryCoronas == 0, 0, 0, GL_TEXTURE0)) {
	if (!gameStates.render.bQueryCoronas) {
		bmP->Bind (1);
		OglTexCoordPointer (2, GL_FLOAT, 0, tcGlare);
		}
	OglVertexPointer (3, GL_FLOAT, sizeof (CFloatVector), sprite);
	OglDrawArrays (GL_QUADS, 0, 4);
	ogl.DisableClientStates (gameStates.render.bQueryCoronas == 0, 0, 0, GL_TEXTURE0);
	}
else {
	if (gameStates.render.bQueryCoronas == 0)
		bmP->Bind (1);
	glBegin (GL_QUADS);
	for  (i = 0; i < 4; i++) {
		glTexCoord2fv (reinterpret_cast<GLfloat*> (tcGlare + i));
		glVertex3fv (reinterpret_cast<GLfloat*> (sprite + i));
		}
	glEnd ();
	}
if (!gameStates.render.bQueryCoronas && bAdditive)
	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
RenderCoronaOutline (sprite, vCenter);
if (gameStates.render.bQueryCoronas != 2) {
	glEnable (GL_DEPTH_TEST);
	if (gameStates.render.bQueryCoronas == 1)
		glDepthFunc (GL_LEQUAL);
	}
}
示例#4
0
void OglDrawEllipse (int nSides, int nType, float xsc, float xo, float ysc, float yo, tSinCosf *sinCosP)
{
    int		i;
    double	ang;

    glPushMatrix ();
    glEnable (GL_LINE_SMOOTH);
    glTranslatef (xo, yo, 0.0f);
    glScalef (xsc, ysc, 1.0f);
    if (nType == GL_LINES) {	// implies a dashed circle
        glBegin (nType);
        if (sinCosP) {
            for (i = 0; i < nSides; i++, sinCosP++) {
                glVertex2f (sinCosP->fCos, sinCosP->fSin);
                i++, sinCosP++;
                glVertex2f (sinCosP->fCos, sinCosP->fSin);
            }
        }
        else {
            for (i = 0; i < nSides; i++) {
                ang = 2.0 * Pi * i / nSides;
                glVertex2f (float (cos (ang)), float (sin (ang)));
                i++;
                ang = 2.0 * Pi * i / nSides;
                glVertex2f (float (cos (ang)), float (sin (ang)));
            }
        }
        glEnd ();
    }
    else {
        if (sinCosP) {
#if 1
            ogl.EnableClientStates (0, 0, 0, GL_TEXTURE0);
            OglVertexPointer (2, GL_FLOAT, 2 * sizeof (float), reinterpret_cast<GLfloat*> (sinCosP));
            OglDrawArrays (nType, 0, nSides);
            ogl.DisableClientStates (0, 0, 0, GL_TEXTURE0);
#else
            for (i = 0; i < nSides; i++, sinCosP++)
                glVertex2f (sinCosP->fCos, sinCosP->fSin);
#endif
        }
        else {
            glBegin (nType);
            for (i = 0; i < nSides; i++) {
                ang = 2.0 * Pi * i / nSides;
                glVertex2f (float (cos (ang)), float (sin (ang)));
            }
        }
        glEnd ();
    }
    glDisable (GL_LINE_SMOOTH);
    glPopMatrix ();
}
示例#5
0
void CBitmap::OglRender (tRgbaColorf* colorP, int nColors, int orient)
{
	float				verts [4][2] = {{m_render.x0, m_render.y0}, {m_render.x1, m_render.y0}, {m_render.x1, m_render.y1}, {m_render.x0, m_render.y1}};
	tTexCoord2f		texCoord [4];

SetTexCoord (m_render.u1, m_render.v1, orient, texCoord [0]);
SetTexCoord (m_render.u2, m_render.v1, orient, texCoord [1]);
SetTexCoord (m_render.u2, m_render.v2, orient, texCoord [2]);
SetTexCoord (m_render.u1, m_render.v2, orient, texCoord [3]);
ogl.EnableClientStates (1, (nColors == 4), 0, GL_TEXTURE0);
glTexCoordPointer (2, GL_FLOAT, sizeof (tTexCoord2f), texCoord);
if (nColors == 4)
	OglColorPointer (4, GL_FLOAT, sizeof (tRgbaColorf), colorP);
else
	glColor4fv (reinterpret_cast<GLfloat*> (colorP));
OglVertexPointer (2, GL_FLOAT, 2 * sizeof (float), verts);
OglDrawArrays (GL_QUADS, 0, 4);
ogl.DisableClientStates (1, (nColors == 4), 0, GL_TEXTURE0);
}
示例#6
0
void G3FillFaceBuffer (CSegFace *faceP, CBitmap *bmBot, CBitmap *bmTop, int bTextured)
{
#if DBG
    if (!gameOpts->render.debug.bTextures)
        return;
#endif
#if 0
    if (!gameStates.render.bTriangleMesh) {
        if (gameStates.render.bFullBright)
            glColor3f (1,1,1);
        OglDrawArrays (GL_TRIANGLE_FAN, faceP->nIndex, 4);
    }
    else
#endif
    {
        int	i = faceP->nIndex,
            j = gameStates.render.bTriangleMesh ? faceP->nTris * 3 : 4;

#if DBG
        if (i == nDbgVertex)
            nDbgVertex = nDbgVertex;
        if (i + j > int (FACES.vertices.Length ())) {
            PrintLog ("invalid vertex index %d in G3FillFaceBuffer\n");
            return;
        }
#endif
        if (!gameStates.render.bTriangleMesh || (faceBuffer.bmBot != bmBot) || (faceBuffer.bmTop != bmTop) || (faceBuffer.nElements + j > FACE_BUFFER_INDEX_SIZE)) {
            if (faceBuffer.nFaces)
                G3FlushFaceBuffer (1);
            faceBuffer.bmBot = bmBot;
            faceBuffer.bmTop = bmTop;
        }
        faceBuffer.bTextured = bTextured;
        for (; j; j--)
            faceBuffer.index [faceBuffer.nElements++] = i++;
        faceBuffer.nFaces++;
    }
}
示例#7
0
int G3DrawTexPolyMulti (
    int			nVertices,
    g3sPoint**	pointList,
    tUVL*			uvlList,
    tUVL*			uvlLMap,
    CBitmap*		bmBot,
    CBitmap*		bmTop,
    tLightmap*	lightmap,
    CFixVector*	pvNormal,
    int			orient,
    int			bBlend,
    short			nSegment)
{
    int			i, nShader, nFrame;
    int			bShaderMerge = 0,
                bSuperTransp = 0;
    int			bLight = 1,
                bDynLight = gameStates.render.bApplyDynLight && (gameStates.app.bEndLevelSequence < EL_OUTSIDE),
                bDepthSort,
                bResetColor = 0,
                bOverlay = 0;
    tFaceColor	*pc;
    CBitmap		*bmP = NULL, *mask = NULL;
    g3sPoint		*pl, **ppl;
#if USE_VERTNORMS
    CFloatVector	vNormal, vVertPos;
#endif
#if G3_DRAW_ARRAYS
    int			bVertexArrays = gameData.render.vertP != NULL;
#else
    int			bVertexArrays = 0;
#endif

    if (gameStates.render.nShadowBlurPass == 1) {
        G3DrawWhitePoly (nVertices, pointList);
        return 0;
    }
    if (!bmBot)
        return 1;
    r_tpolyc++;
    if (FAST_SHADOWS) {
        if (!bBlend)
            glDisable (GL_BLEND);
#if 0
        else
            glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
    }
    else {
        if (gameStates.render.nShadowPass == 1)
            bLight = !bDynLight;
        else if (gameStates.render.nShadowPass == 3) {
            glEnable (GL_BLEND);
            glBlendFunc (GL_ONE, GL_ONE);
        }
    }
    glDepthFunc (GL_LEQUAL);
    bmBot = bmBot->Override (-1);
    bDepthSort = (!bmTop && (gameOpts->render.bDepthSort > 0) &&
                  ((gameStates.render.grAlpha < 1.0f) ||
                   (bmBot->Flags () & (BM_FLAG_TRANSPARENT | BM_FLAG_SEE_THRU | BM_FLAG_TGA)) == (BM_FLAG_TRANSPARENT | BM_FLAG_TGA)));
    if (bmTop && (bmTop = bmTop->Override (-1)) && bmTop->Frames ()) {
        nFrame = (int) (bmTop->CurFrame () - bmTop->Frames ());
        bmP = bmTop;
        bmTop = bmTop->CurFrame ();
    }
    else
        nFrame = -1;
    if (bmTop) {
        if (nFrame < 0)
            bSuperTransp = (bmTop->Flags () & BM_FLAG_SUPER_TRANSPARENT) != 0;
        else
            bSuperTransp = (bmP->Flags () & BM_FLAG_SUPER_TRANSPARENT) != 0;
        bShaderMerge = bSuperTransp && ogl.m_states.bGlTexMerge;
        bOverlay = !bShaderMerge;
    }
    else
        bOverlay = -1;
#if G3_DRAW_ARRAYS
retry:
#endif
    if (bShaderMerge) {
        mask = gameStates.render.textures.bHaveMaskShader ? bmTop->Mask () : NULL;
        nShader = bSuperTransp ? mask ? 2 : 1 : 0;
        glUseProgramObject (activeShaderProg = tmShaderProgs [nShader]);
        INIT_TMU (InitTMU0, GL_TEXTURE0, bmBot, lightmapManager.Buffer (), bVertexArrays, 0);
        glUniform1i (glGetUniformLocation (activeShaderProg, "btmTex"), 0);
        INIT_TMU (InitTMU1, GL_TEXTURE1, bmTop, lightmapManager.Buffer (), bVertexArrays, 0);
        glUniform1i (glGetUniformLocation (activeShaderProg, "topTex"), 1);
        if (mask) {
#if DBG
            InitTMU2 (bVertexArrays);
            G3_BIND (GL_TEXTURE2, mask, lightmapManager.Buffer (), bVertexArrays);
#else
            INIT_TMU (InitTMU2, GL_TEXTURE2, mask, lightmapManager.Buffer (), bVertexArrays, 0);
#endif
            glUniform1i (glGetUniformLocation (activeShaderProg, "maskTex"), 2);
        }
        glUniform1f (glGetUniformLocation (activeShaderProg, "grAlpha"), gameStates.render.grAlpha);
    }
    else if (!bDepthSort) {
        if (bmBot == gameData.endLevel.satellite.bmP) {
            ogl.SelectTMU (GL_TEXTURE0);
            glEnable (GL_TEXTURE_2D);
        }
        else
            InitTMU0 (bVertexArrays);
        if (bmBot->Bind (1))
            return 1;
        bmBot = bmBot->CurFrame (-1);
        bmBot->Texture ()->Wrap ((bmBot == bmpDeadzone) ? GL_CLAMP : GL_REPEAT);
    }

    if (!bDepthSort) {
        if (SHOW_DYN_LIGHT) {
#if USE_VERTNORMS
            if (pvNormal) {
                vNormal.Assign (*pvNormal);
                transformation.Rotate(vNormal, vNormal, 0);
            }
            else
                G3CalcNormal (pointList, &vNormal);
#else
            G3Normal (pointList, pvNormal);
#endif
        }
        if (gameStates.render.bFullBright) {
            glColor3f (1,1,1);
            bLight = 0;
        }
        else if (!gameStates.render.nRenderPass)
            bLight = 0;
        else if (!bLight)
            glColor3i (0,0,0);
        if (!bLight)
            bDynLight = 0;
        ogl.m_states.bDynObjLight = bDynLight;
    }

    ogl.m_states.fAlpha = gameStates.render.grAlpha;
    if (bVertexArrays || bDepthSort) {
        CFloatVector	vertices [8];
        tFaceColor		vertColors [8];
        tTexCoord2f		texCoord [2][8];
        int				vertIndex [8];
        //int				colorIndex [8];

        for (i = 0, ppl = pointList; i < nVertices; i++, ppl++) {
            pl = *ppl;
            vertIndex [i] = pl->p3_index;
            //colorIndex [i] = i;
            if (pl->p3_index < 0)
                vertices[i].Assign (pl->p3_vec);
            else
                vertices [i] = gameData.render.vertP [pl->p3_index];
            texCoord [0][i].v.u = X2F (uvlList [i].u);
            texCoord [0][i].v.v = X2F (uvlList [i].v);
            SetTexCoord (uvlList + i, orient, 1, texCoord [1] + i, 0);
            G3VERTPOS (vVertPos, pl);
            if (bDynLight)
                G3VertexColor (G3GetNormal (pl, &vNormal), vVertPos.XYZ(), vertIndex [i], vertColors + i, NULL,
                               gameStates.render.nState ? X2F (uvlList [i].l) : 1, 0, 0);
            else if (bLight)
                SetTMapColor (uvlList + i, i, bmBot, !bOverlay, vertColors + i);
        }
#if 1
        if (gameOpts->render.bDepthSort > 0) {
            bmBot->SetupTexture (1, 0);
            transparencyRenderer.AddPoly (NULL, NULL, bmBot, vertices, nVertices, texCoord [0], NULL, vertColors, nVertices, 1, GL_TRIANGLE_FAN, GL_REPEAT, 0, nSegment);
            return 0;
        }
#endif
    }
#if G3_DRAW_ARRAYS
    if (bVertexArrays) {
        if (!ogl.EnableClientStates (1, 1, 0, GL_TEXTURE0)) {
            bVertexArrays = 0;
            goto retry;
        }
        OglVertexPointer (3, GL_FLOAT, sizeof (CFloatVector), vertices);
//	OglIndexPointer (GL_INT, 0, colorIndex);
        OglTexCoordPointer (2, GL_FLOAT, sizeof (tTexCoord3f), texCoord [0]);
        if (bLight)
            OglColorPointer (4, GL_FLOAT, sizeof (tFaceColor), vertColors);
        if (bmTop && !bOverlay) {
            if (!ogl.EnableClientStates (1, 1, 0, GL_TEXTURE1)) {
                ogl.DisableClientStates (1, 1, 0, GL_TEXTURE0);
                bVertexArrays = 0;
                goto retry;
            }
            OglVertexPointer (3, GL_FLOAT, sizeof (CFloatVector), vertices);
            if (bLight)
                OglColorPointer (4, GL_FLOAT, sizeof (tFaceColor), vertColors);
//		OglIndexPointer (GL_INT, 0, colorIndex);
            OglTexCoordPointer (2, GL_FLOAT, sizeof (tTexCoord3f), texCoord [1]);
        }
        OglDrawArrays (GL_TRIANGLE_FAN, 0, nVertices);
        ogl.DisableClientStates (1, 1, 0, GL_TEXTURE0);
        if (bmTop && !bOverlay)
            ogl.DisableClientStates (GL_TEXTURE1);
    }
    else
#endif
    {
        glBegin (GL_TRIANGLE_FAN);
        if (bDynLight) {
            if (bOverlay) {
                for (i = 0, ppl = pointList; i < nVertices; i++, ppl++) {
                    pl = *ppl;
                    G3VERTPOS (vVertPos, pl);
                    G3VertexColor (G3GetNormal (pl, &vNormal), vVertPos.XYZ(), pl->p3_index, NULL, NULL,
                                   gameStates.render.nState ? X2F (uvlList [i].l) : 1, 1, 0);
                    glTexCoord2f (X2F (uvlList [i].u), X2F (uvlList [i].v));
                    glVertex3fv (reinterpret_cast<GLfloat*> (&vVertPos));
                }
            }
            else {
                for (i = 0, ppl = pointList; i < nVertices; i++, ppl++) {
                    pl = *ppl;
                    G3VERTPOS (vVertPos, pl);
                    G3VertexColor (G3GetNormal (pl, &vNormal), vVertPos.XYZ(), pl->p3_index, NULL, NULL,
                                   /*gameStates.render.nState ? X2F (uvlList [i].l) :*/ 1, 1, 0);
                    glMultiTexCoord2f (GL_TEXTURE0, X2F (uvlList [i].u), X2F (uvlList [i].v));
                    SetTexCoord (uvlList + i, orient, 1, NULL, mask != NULL);
                    glVertex3fv (reinterpret_cast<GLfloat*> (&vVertPos));
                }
            }
        }
        else if (bLight) {
            if (bOverlay) {
                for (i = 0, ppl = pointList; i < nVertices; i++, ppl++) {
                    if (gameStates.render.nState || gameStates.app.bEndLevelSequence)
                        SetTMapColor (uvlList + i, i, bmBot, 1, NULL);
                    else {
                        pc = gameData.render.color.vertices + (*ppl)->p3_index;
                        glColor3fv (reinterpret_cast<GLfloat*> (&pc->color));
                    }
                    glTexCoord2f (X2F (uvlList [i].u), X2F (uvlList [i].v));
                    OglVertex3f (*ppl);
                }
            }
            else {
                bResetColor = (bOverlay != 1);
                for (i = 0, ppl = pointList; i < nVertices; i++, ppl++) {
                    if (gameStates.render.nState || !RENDERPATH)
                        SetTMapColor (uvlList + i, i, bmBot, 1, NULL);
                    else {
                        pc = gameData.render.color.vertices + (*ppl)->p3_index;
                        glColor3fv (reinterpret_cast<GLfloat*> (&pc->color));
                    }
                    glMultiTexCoord2f (GL_TEXTURE0, X2F (uvlList [i].u), X2F (uvlList [i].v));
                    SetTexCoord (uvlList + i, orient, 1, NULL, mask != NULL);
                    OglVertex3f (*ppl);
                }
            }
        }
        else {
            if (bOverlay) {
                for (i = 0, ppl = pointList; i < nVertices; i++, ppl++) {
                    glTexCoord2f (X2F (uvlList [i].u), X2F (uvlList [i].v));
                    OglVertex3f (*ppl);
                }
            }
            else {
                for (i = 0, ppl = pointList; i < nVertices; i++, ppl++) {
                    glMultiTexCoord2f (GL_TEXTURE0, X2F (uvlList [i].u), X2F (uvlList [i].v));
                    SetTexCoord (uvlList + i, orient, 1, NULL, mask != NULL);
                    OglVertex3f (*ppl);
                }
            }
        }
        glEnd ();
    }
    if (bOverlay > 0) {
        r_tpolyc++;
        ogl.SelectTMU (GL_TEXTURE0);
        glEnable (GL_TEXTURE_2D);
        if (bmTop->Bind (1))
            return 1;
        bmTop = bmTop->CurFrame (-1);
        bmTop->Texture ()->Wrap (GL_REPEAT);
        glBegin (GL_TRIANGLE_FAN);
        if (bDynLight) {
            for (i = 0, ppl = pointList; i < nVertices; i++, ppl++) {
                vVertPos.Assign ((*ppl)->p3_vec);
                G3VertexColor (G3GetNormal (*ppl, &vNormal), vVertPos.XYZ(), (*ppl)->p3_index, NULL, NULL, 1, 1, 0);
                SetTexCoord (uvlList + i, orient, 0, NULL, mask != NULL);
                OglVertex3f (*ppl);
            }
        }
        else if (bLight) {
            for (i = 0, ppl = pointList; i < nVertices; i++, ppl++) {
                SetTMapColor (uvlList + i, i, bmTop, 1, NULL);
                SetTexCoord (uvlList + i, orient, 0, NULL, mask != NULL);
                OglVertex3f (*ppl);
            }
        }
        else {
            for (i = 0, ppl = pointList; i < nVertices; i++, ppl++) {
                SetTexCoord (uvlList + i, orient, 0, NULL, mask != NULL);
                OglVertex3f (*ppl);
            }
        }
        glEnd ();
        glDepthFunc (GL_LESS);
#if OGL_CLEANUP
        OGL_BINDTEX (0);
        glDisable (GL_TEXTURE_2D);
#endif
    }
    else if (bShaderMerge) {
#if OGL_CLEANUP
        ogl.SelectTMU (GL_TEXTURE1, bVertexArrays != 0);
        OGL_BINDTEX (0);
        glDisable (GL_TEXTURE_2D); // Disable the 2nd texture
#endif
        glUseProgramObject (activeShaderProg = 0);
    }
    ogl.SelectTMU (GL_TEXTURE0, bVertexArrays != 0);
    OGL_BINDTEX (0);
    glDisable (GL_TEXTURE_2D);
    tMapColor.index =
        lightColor.index = 0;
    if (!bBlend)
        glEnable (GL_BLEND);
    return 0;
}
示例#8
0
int OglRenderArrays (CBitmap *bmP, int nFrame, CFloatVector *vertexP, int nVertices, tTexCoord2f *texCoordP,
                     tRgbaColorf *colorP, int nColors, int nPrimitive, int nWrap)
{
    int	bVertexArrays = ogl.EnableClientStates (bmP && texCoordP, colorP && (nColors == nVertices), 0, GL_TEXTURE0);

    if (bmP)
        glEnable (GL_TEXTURE_2D);
    else
        glDisable (GL_TEXTURE_2D);
    if (bmP) {
        if (bmP->Bind (1))
            return 0;
        bmP = bmP->Override (-1);
        if (bmP->Frames ())
            bmP = bmP->Frames () + nFrame;
        bmP->Texture ()->Wrap (nWrap);
    }
    if (bVertexArrays) {
        if (texCoordP)
            OglTexCoordPointer (2, GL_FLOAT, sizeof (tTexCoord2f), texCoordP);
        if (colorP) {
            if (nColors == nVertices)
                OglColorPointer (4, GL_FLOAT, sizeof (tRgbaColorf), colorP);
            else
                glColor4fv (reinterpret_cast<GLfloat*> (colorP));
        }
        OglVertexPointer (3, GL_FLOAT, sizeof (CFloatVector), vertexP);
        OglDrawArrays (nPrimitive, 0, nVertices);
        ogl.DisableClientState (GL_VERTEX_ARRAY);
        if (texCoordP)
            ogl.DisableClientState (GL_TEXTURE_COORD_ARRAY);
        if (colorP)
            ogl.DisableClientState (GL_COLOR_ARRAY);
    }
    else {
        int i = nVertices;
        glBegin (nPrimitive);
        if (colorP && (nColors == nVertices)) {
            if (bmP) {
                for (i = 0; i < nVertices; i++) {
                    glColor4fv (reinterpret_cast<GLfloat*> (colorP + i));
                    glVertex3fv (reinterpret_cast<GLfloat*> (vertexP + i));
                    glTexCoord2fv (reinterpret_cast<GLfloat*> (texCoordP + i));
                }
            }
            else {
                for (i = 0; i < nVertices; i++) {
                    glColor4fv (reinterpret_cast<GLfloat*> (colorP + i));
                    glVertex3fv (reinterpret_cast<GLfloat*> (vertexP + i));
                }
            }
        }
        else {
            if (colorP)
                glColor4fv (reinterpret_cast<GLfloat*> (colorP));
            else
                glColor3d (1, 1, 1);
            if (bmP) {
                for (i = 0; i < nVertices; i++) {
                    glVertex3fv (reinterpret_cast<GLfloat*> (vertexP + i));
                    glTexCoord2fv (reinterpret_cast<GLfloat*> (texCoordP + i));
                }
            }
            else {
                for (i = 0; i < nVertices; i++) {
                    glVertex3fv (reinterpret_cast<GLfloat*> (vertexP + i));
                }
            }
        }
        glEnd ();
    }
    return 1;
}