Ejemplo n.º 1
0
void R_DrawAliasBatchPass (entity_t **ents, int numents, qbool showtris)
{
    int i;
    gltexture_t *lasttexture = NULL;
    gltexture_t *lastfullbright = NULL;

    if (!numents)
        return;

    if (showtris)
        GL_TexEnv (GL_TEXTURE0_ARB, GL_TEXTURE_2D, GL_REPLACE);
    else if (gl_overbright.value)
        GL_TexEnv (GL_TEXTURE0_ARB, GL_TEXTURE_2D, GL_RGB_SCALE_ARB);
    else
        GL_TexEnv (GL_TEXTURE0_ARB, GL_TEXTURE_2D, GL_MODULATE);

    for (i = 0; i < numents; i++)
    {
        entity_t *ent = ents[i];
        aliasstate_t *state = &ent->aliasstate;
        aliashdr_t *hdr = Mod_Extradata (ent->model);

        // we need a separate test for culling here as r_shadows mode doesn't cull
        if (ent->visframe != r_framecount)
            continue;

        if (!showtris && ((state->tx != lasttexture) || (state->fb != lastfullbright)))
        {
            if (state->fb)
            {
                GL_TexEnv (GL_TEXTURE1_ARB, GL_TEXTURE_2D, GL_ADD);
                GL_BindTexture (GL_TEXTURE1_ARB, state->fb);
            }
            else
                GL_TexEnv (GL_TEXTURE1_ARB, GL_TEXTURE_2D, GL_NONE);

            GL_BindTexture (GL_TEXTURE0_ARB, state->tx);

            lasttexture = state->tx;
            lastfullbright = state->fb;
        }

        // OK, this works better in GL... go figure...
        R_DrawAliasModel (ent, hdr, state, showtris);
    }

    GL_TexEnv (GL_TEXTURE1_ARB, GL_TEXTURE_2D, GL_NONE);
    GL_TexEnv (GL_TEXTURE0_ARB, GL_TEXTURE_2D, GL_REPLACE);

    qglColor4f (1, 1, 1, 1);

    // go back to the world matrix
    qglLoadMatrixf (r_world_matrix.m16);
}
Ejemplo n.º 2
0
void R_DrawSkyChain (msurface_t *surf)
{
	msurface_t *reversechain = NULL;
	int numindexes = 0;

	if (!surf) return;

	// push the depth range back to far end of the z-buffer
	// rogue has some pretty - unusual - brush placement and needs this
	glDepthRange (gldepthmax, gldepthmax);
	glProgramUniformMatrix4fv (gl_skycubeprog, u_skylocalMatrix, 1, GL_FALSE, r_mvpmatrix.m[0]);
	glEnable (GL_TEXTURE_CUBE_MAP_SEAMLESS);

	GL_UseProgram (gl_skycubeprog);
	GL_BindTexture (GL_TEXTURE0, GL_TEXTURE_CUBE_MAP, r_skysampler, r_skytexture);
	GL_Enable (DEPTHTEST_BIT | (gl_cull->value ? CULLFACE_BIT : 0));

	for (; surf; surf = surf->texturechain)
	{
		surf->reversechain = reversechain;
		reversechain = surf;
		numindexes += surf->numindexes;
	}

	R_DrawSurfaceChain (reversechain, numindexes);

	glDepthRange (gldepthmin, gldepthmax);
	glDisable (GL_TEXTURE_CUBE_MAP_SEAMLESS);
}
Ejemplo n.º 3
0
/*
==============
R_DrawSkyBox
==============
*/
void R_DrawSkyBox( void ) {
    static const int skytexorder[6] = {0,2,1,3,4,5};
    vec5_t verts[4];
    int i;

    if( skyrotate ) {
        // hack, forces full sky to draw when rotating
        for( i = 0; i < 6; i++ ) {
            skymins[0][i] = -1;
            skymins[1][i] = -1;
            skymaxs[0][i] = 1;
            skymaxs[1][i] = 1;
        }
    } else {
        // check for no sky at all
        for( i = 0; i < 6; i++ ) {
            if( SKY_VISIBLE( i ) ) {
                break;
            }
        }
        if( i == 6 ) {
            return;     // nothing visible
        }
    }

    qglPushMatrix ();
    qglTranslatef (glr.fd.vieworg[0], glr.fd.vieworg[1], glr.fd.vieworg[2]);
    if( skyrotate ) {
        qglRotatef (glr.fd.time * skyrotate, skyaxis[0], skyaxis[1], skyaxis[2]);
    }

    GL_TexEnv( GL_REPLACE );
    GL_Bits( GLS_DEFAULT );

    qglVertexPointer( 3, GL_FLOAT, 5*4, &verts[0][0] );
    qglTexCoordPointer( 2, GL_FLOAT, 5*4, &verts[0][3] );

    for( i = 0; i < 6; i++ ) {
        if( !SKY_VISIBLE( i ) ) {
            continue;
        }

        GL_BindTexture (sky_images[skytexorder[i]]);

        MakeSkyVec (skymaxs[0][i], skymins[1][i], i, verts[0]);
        MakeSkyVec (skymins[0][i], skymins[1][i], i, verts[1]);
        MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i, verts[2]);
        MakeSkyVec (skymins[0][i], skymaxs[1][i], i, verts[3]);
        qglDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
    }

    qglPopMatrix ();
}
Ejemplo n.º 4
0
void Sky_RenderLayers (void)
{
    glmatrix skymatrix;

    // standard layers
    GL_BindTexture (GL_TEXTURE0_ARB, solidskytexture);
    R_ScrollSkyMatrix (8);

    GL_TexEnv (GL_TEXTURE1_ARB, GL_TEXTURE_2D, GL_DECAL);
    GL_BindTexture (GL_TEXTURE1_ARB, alphaskytexture);
    R_ScrollSkyMatrix (16);

    GL_IdentityMatrix (&skymatrix);
    GL_TranslateMatrix (&skymatrix, -r_origin[0], -r_origin[1], -r_origin[2]);
    GL_ScaleMatrix (&skymatrix, 65536, 65536, 65536);
    qglMultMatrixf (skymatrix.m16);

    GL_SetStreamSource (GLSTREAM_POSITION, 3, GL_FLOAT, sizeof (dpskyvert_t), r_dpskyverts->xyz);
    GL_SetStreamSource (GLSTREAM_COLOR, 0, GL_NONE, 0, NULL);
    GL_SetStreamSource (GLSTREAM_TEXCOORD0, 2, GL_FLOAT, sizeof (dpskyvert_t), r_dpskyverts->st);
    GL_SetStreamSource (GLSTREAM_TEXCOORD1, 2, GL_FLOAT, sizeof (dpskyvert_t), r_dpskyverts->st);
    GL_SetStreamSource (GLSTREAM_TEXCOORD2, 0, GL_NONE, 0, NULL);

    GL_SetIndices (r_dpskyindexes);
    GL_DrawIndexedPrimitive (GL_TRIANGLES, SKYSPHERE_NUMINDEXES, SKYSPHERE_NUMVERTS);

    GL_TexEnv (GL_TEXTURE1_ARB, GL_TEXTURE_2D, GL_NONE);

    qglMatrixMode (GL_TEXTURE);
    qglLoadIdentity ();
    qglMatrixMode (GL_MODELVIEW);

    GL_ActiveTexture (GL_TEXTURE0_ARB);

    qglMatrixMode (GL_TEXTURE);
    qglLoadIdentity ();
    qglMatrixMode (GL_MODELVIEW);

    qglLoadMatrixf (r_world_matrix.m16);
}
Ejemplo n.º 5
0
void Sky_DrawCubeMap (r_modelsurf_t **mslist, int numms)
{
#if 0
    int i;
    msurface_t *surf;
    r_modelsurf_t *ms;
    qbool stateset = false;

    // cubemapped sky doesn't need depth clipping or other hackery, is always perfectly positioned, and never has bugs
    for (i = 0; i < numms; i++)
    {
        ms = mslist[i];

        if (!((surf = ms->surface)->flags & SURF_DRAWSKY)) continue;

        if (!stateset)
        {
            if (gl_support_arb_vertex_buffer_object)
            {
                GL_BindBuffer (GL_ARRAY_BUFFER_ARB, r_surfacevbo);

                GL_SetStreamSource (GLSTREAM_POSITION, 3, GL_FLOAT, sizeof (glvertex_t), (void *) (0));
                GL_SetStreamSource (GLSTREAM_TEXCOORD0, 3, GL_FLOAT, sizeof (glvertex_t), (void *) (0));
            }
            else
            {
                glvertex_t *base = (glvertex_t *) scratchbuf;

                GL_SetStreamSource (GLSTREAM_POSITION, 3, GL_FLOAT, sizeof (glvertex_t), base->v);
                GL_SetStreamSource (GLSTREAM_TEXCOORD0, 3, GL_FLOAT, sizeof (glvertex_t), base->v);
            }

            GL_SetStreamSource (GLSTREAM_COLOR, 0, GL_NONE, 0, NULL);
            GL_SetStreamSource (GLSTREAM_TEXCOORD1, 0, GL_NONE, 0, NULL);
            GL_SetStreamSource (GLSTREAM_TEXCOORD2, 0, GL_NONE, 0, NULL);

            R_BeginSurfaces ();

            // texmgr is fragile and can't handle cubemaps so we must do it manually
            qglBindTexture (GL_TEXTURE_2D, 0);
            qglDisable (GL_TEXTURE_2D);
            qglEnable (GL_TEXTURE_CUBE_MAP);
            qglBindTexture (GL_TEXTURE_CUBE_MAP, skyCubeTexture);

            qglMatrixMode (GL_TEXTURE);
            qglLoadIdentity ();
            qglTranslatef (-r_origin[0], -r_origin[1], -r_origin[2]);
            qglMatrixMode (GL_MODELVIEW);

            stateset = true;
        }

        R_BatchSurface (ms->surface, ms->matrix, ms->entnum);
    }

    if (stateset)
    {
        R_EndSurfaces ();

        qglMatrixMode (GL_TEXTURE);
        qglLoadIdentity ();
        qglMatrixMode (GL_MODELVIEW);

        // texmgr is fragile and can't handle cubemaps so we must do it manually
        qglBindTexture (GL_TEXTURE_CUBE_MAP, 0);
        qglDisable (GL_TEXTURE_CUBE_MAP);
        qglEnable (GL_TEXTURE_2D);

        // ensure that we bind a 2D texture here
        GL_BindTexture (GL_TEXTURE0_ARB, NULL);
    }
#endif
}
Ejemplo n.º 6
0
void Sky_LoadCubeMap (char *name)
{
#if 0
    int		i, mark, width[6], height[6];
    char	filename[MAX_OSPATH];
    byte	*data[6];
    qbool nonefound = true;
    int largest;

    // so that I can call Sky_LoadCubeMap (NULL) to flush a texture.
    if (!name)
    {
        // purge old texture
        Sky_ClearSkybox ();
        return;
    }

    // no change
    if (strcmp (skybox_name, name) == 0)
        return;

    // purge old texture
    Sky_ClearSkybox ();

    // turn off skybox if sky is set to ""
    if (name[0] == 0)
    {
        skybox_name[0] = 0;
        return;
    }

    mark = Hunk_LowMark ();

    // skybox faces must all be square and the same dimension so track the largest
    largest = 0;

    // load textures
    for (i=0 ; i<6 ; i++)
    {
        sprintf (filename, "gfx/env/%s%s", name, suf[i]);
        data[i] = Image_LoadImage (filename, &width[i], &height[i]);

        if (data[i])
        {
            // skybox faces must all be square and the same dimension so track the largest
            if (width[i] > largest) largest = width[i];
            if (height[i] > largest) largest = height[i];
        }
        else width[i] = height[i] = 0;
    }

    // fixme - this could get a mite cleaner
    if (largest > 0)
    {
        // now let's see what we got
        byte *cubebuffer = NULL;

        glBindTexture (GL_TEXTURE_2D, 0);
        glDisable (GL_TEXTURE_2D);
        glEnable (GL_TEXTURE_CUBE_MAP);

        glGenTextures (1, &skyCubeTexture);
        glBindTexture (GL_TEXTURE_CUBE_MAP, skyCubeTexture);

        glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

        glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

        // ATI strikes again - cubemaps should be loaded in a specific order
        for (i = 0; i < 6; i++)
        {
            if (!data[loadorder[i]])
            {
                if (!cubebuffer) cubebuffer = (byte *) Hunk_Alloc (largest * largest * 4);

                memset (cubebuffer, 0, largest * largest * 4);
                data[loadorder[i]] = cubebuffer;
                width[loadorder[i]] = largest;
                height[loadorder[i]] = largest;
            }

            if (width[loadorder[i]] != largest || height[loadorder[i]] != largest)
            {
                if (!cubebuffer) cubebuffer = (byte *) Hunk_Alloc (largest * largest * 4);

                // upsize to cube buffer and set back
                GL_Resample32BitTexture ((unsigned *) data[loadorder[i]], width[loadorder[i]], height[loadorder[i]], (unsigned *) cubebuffer, largest, largest);

                data[loadorder[i]] = cubebuffer;
                width[loadorder[i]] = largest;
                height[loadorder[i]] = largest;
            }

            switch (loadorder[i])
            {
            case 0:
                D3D_RotateTexelsInPlace ((unsigned int *) data[0], width[0]);
                break;

            case 1:
                D3D_FlipTexels ((unsigned int *) data[1], width[1], height[1]);
                break;

            case 2:
                D3D_RotateTexelsInPlace ((unsigned int *) data[2], width[2]);
                D3D_MirrorTexels ((unsigned int *) data[2], width[2], height[2]);
                D3D_FlipTexels ((unsigned int *) data[2], width[2], height[2]);
                break;

            case 3:
                D3D_MirrorTexels ((unsigned int *) data[3], width[3], height[3]);
                break;

            case 4:
                D3D_RotateTexelsInPlace ((unsigned int *) data[4], width[4]);
                break;

            case 5:
                D3D_RotateTexelsInPlace ((unsigned int *) data[5], width[5]);
                break;
            }

            // standard face
            glTexImage2D (cubefaces[i], 0, GL_RGBA8, largest, largest, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data[loadorder[i]]);

            nonefound = false;
        }

        glBindTexture (GL_TEXTURE_CUBE_MAP, 0);
        glDisable (GL_TEXTURE_CUBE_MAP);
        glEnable (GL_TEXTURE_2D);
        GL_BindTexture (GL_TEXTURE0, NULL);
    }

    Hunk_FreeToLowMark (mark);

    if (nonefound) // go back to scrolling sky if skybox is totally missing
    {
        Sky_ClearSkybox ();
        Com_Printf ("Couldn't load %s\n", name);
        return;
    }

    strcpy (skybox_name, name);
    Com_DPrintf ("loaded skybox %s OK\n", name);
#endif
}
Ejemplo n.º 7
0
/*
=================
R_DrawDecals

Draws all decals on the decal list
=================
*/
void R_DrawDecals (void)
{
	cdecal_t    *dl, *next, *active;
	float		mindist, time;
	int			r_numdecals = 0;
	vec3_t		v;
	vec4_t		color;

	if (!gl_decals->value)
		return;

	if (r_newrefdef.rdflags & RDF_NOWORLDMODEL)
		return;

	active = &active_decals;

	mindist = DotProduct(r_origin, vpn) + 4.0;

	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(-2, -2);

	GL_Enable(BLEND_BIT | DEPTHTEST_BIT);

	GL_UseProgram(gl_decalprog);

	glProgramUniformMatrix4fv (gl_decalprog, gl_decalmvpMatrix, 1, GL_FALSE, r_mvpmatrix.m[0]);

	for (dl = active->next; dl != active; dl = next)
	{
		next = dl->next;

		if (dl->node == NULL || dl->node->visframe != r_visframecount)
			continue;

		// check type
		if (dl->type < 0 || dl->type > MAX_DECAL_TEX)
		{
			R_FreeDecal (dl);
			continue;
		}

		// have we faded out yet?
		if (dl->time + gl_decalsTime->value <= r_newrefdef.time)
		{
			R_FreeDecal (dl);
			continue;
		}

		// do not render if the decal is behind the view
		if (DotProduct(dl->org, vpn) < mindist)
			continue;

		// do not render if the view origin is behind the decal
		VectorSubtract(dl->org, r_origin, v);
		if (DotProduct(dl->direction, v) < 0)
			continue;

		Vector4Copy(dl->color, color);

		time = dl->time + gl_decalsTime->value - r_newrefdef.time;
		if (time < 1.5)
			color[3] *= time / 1.5;

		// bind texture
		GL_BindTexture(GL_TEXTURE0, GL_TEXTURE_2D, r_drawnearestclampsampler, r_decalImages[dl->type]);

		// bind data into vbo
		glBindBuffer(GL_ARRAY_BUFFER, gl_decalvbo);
		glBufferData(GL_ARRAY_BUFFER, sizeof(dl->verts) + sizeof(dl->stcoords) + sizeof(color), NULL, GL_DYNAMIC_DRAW);
		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(dl->verts), dl->verts);
		glBufferSubData(GL_ARRAY_BUFFER, sizeof(dl->verts), sizeof(dl->stcoords), dl->stcoords);
		glBufferSubData(GL_ARRAY_BUFFER, sizeof(dl->verts) + sizeof(dl->stcoords), sizeof(color), color);

		// bind vao
		GL_BindVertexArray(gl_decalvao);
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
		glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void *)sizeof(dl->verts));
		glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (void *)(sizeof(dl->verts) + sizeof(dl->stcoords)));

		// draw
		glDrawArrays(GL_TRIANGLE_FAN, 0, dl->numverts);

		r_numdecals++;
		if (r_numdecals >= MAX_DECALS)
			break;
	}

	glDisable(GL_POLYGON_OFFSET_FILL);
}
Ejemplo n.º 8
0
static void drawChar(unsigned char ch, int posX, int posY, font_t* font,
    int alignFlags, short /*textFlags*/)
{
    float x = (float) posX, y = (float) posY;
    Point2Raw coords[4];
    RectRaw geometry;

    if(alignFlags & ALIGN_RIGHT)
        x -= Fonts_CharWidth(font, ch);
    else if(!(alignFlags & ALIGN_LEFT))
        x -= Fonts_CharWidth(font, ch) / 2;

    if(alignFlags & ALIGN_BOTTOM)
        y -= topToAscent(font) + lineHeight(font, ch);
    else if(!(alignFlags & ALIGN_TOP))
        y -= (topToAscent(font) + lineHeight(font, ch))/2;

    glMatrixMode(GL_MODELVIEW);
    glTranslatef(x, y, 0);

    switch(Font_Type(font))
    {
    case FT_BITMAP:
        /// @todo Filtering should be determined at a higher level.
        /// @todo We should not need to re-bind this texture here.
        GL_BindTextureUnmanaged(BitmapFont_GLTextureName(font), GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE,
                                filterUI? GL_LINEAR : GL_NEAREST);

        std::memcpy(&geometry, BitmapFont_CharGeometry(font, ch), sizeof(geometry));
        BitmapFont_CharCoords(font, ch, coords);
        break;

    case FT_BITMAPCOMPOSITE: {
        uint8_t const border = BitmapCompositeFont_CharBorder(font, ch);

        GL_BindTexture(BitmapCompositeFont_CharTexture(font, ch));

        std::memcpy(&geometry, BitmapCompositeFont_CharGeometry(font, ch), sizeof(geometry));
        if(border)
        {
            geometry.origin.x -= border;
            geometry.origin.y -= border;
            geometry.size.width += border*2;
            geometry.size.height += border*2;
        }
        BitmapCompositeFont_CharCoords(font, ch, coords);
        break; }

    default:
        Con_Error("FR_DrawChar: Invalid font type %i.", (int) Font_Type(font));
        exit(1); // Unreachable.
    }

    if(font->_marginWidth)
    {
        geometry.origin.x -= font->_marginWidth;
        geometry.size.width += font->_marginWidth*2;
    }
    if(font->_marginHeight)
    {
        geometry.origin.y -= font->_marginHeight;
        geometry.size.height += font->_marginHeight*2;
    }

    GL_DrawRectWithCoords(&geometry, coords);

    if(Font_Type(font) == FT_BITMAPCOMPOSITE)
    {
        GL_SetNoTexture();
    }

    glMatrixMode(GL_MODELVIEW);
    glTranslatef(-x, -y, 0);
}
Ejemplo n.º 9
0
/*
=================
R_DrawAliasModelShadow
=================
*/
void R_DrawAliasModelShadow(entity_t *e)
{
	int			i;
	dmdl_t		*hdr;
	float		an;
	vec3_t		bbox[8];
	image_t		*skin;
	float		lightspot[3];
	glmatrix	shadowmatrix;
	float		lheight;

	if (gl_shadows->value && (e->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW)))
		return;

	if (!(e->flags & RF_WEAPONMODEL))
	{
		if (R_CullAliasModel(bbox, e))
			return;
	}

	if (e->flags & RF_WEAPONMODEL)
	{
		if (r_lefthand->value == 2)
			return;
	}

	hdr = (dmdl_t *)e->model->extradata;

	if (e->flags & (RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE))
	{
		VectorClear(gl_meshuboupdate.shadelight);

		if (e->flags & RF_SHELL_RED) gl_meshuboupdate.shadelight[0] = 1.0;
		if (e->flags & RF_SHELL_GREEN) gl_meshuboupdate.shadelight[1] = 1.0;
		if (e->flags & RF_SHELL_BLUE) gl_meshuboupdate.shadelight[2] = 1.0;
	}
	else if (e->flags & RF_FULLBRIGHT)
	{
		gl_meshuboupdate.shadelight[0] = 1.0;
		gl_meshuboupdate.shadelight[1] = 1.0;
		gl_meshuboupdate.shadelight[2] = 1.0;
	}
	else
	{
		R_LightPoint(e->currorigin, gl_meshuboupdate.shadelight, lightspot);

		// player lighting hack for communication back to server
		// big hack!
		if (e->flags & RF_WEAPONMODEL)
		{
			// pick the greatest component, which should be the same
			// as the mono value returned by software
			if (gl_meshuboupdate.shadelight[0] > gl_meshuboupdate.shadelight[1])
			{
				if (gl_meshuboupdate.shadelight[0] > gl_meshuboupdate.shadelight[2])
					r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[0];
				else r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[2];
			}
			else
			{
				if (gl_meshuboupdate.shadelight[1] > gl_meshuboupdate.shadelight[2])
					r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[1];
				else r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[2];
			}
		}
	}

	if (e->flags & RF_MINLIGHT)
	{
		for (i = 0; i < 3; i++)
			if (gl_meshuboupdate.shadelight[i] > 0.1)
				break;

		if (i == 3)
		{
			gl_meshuboupdate.shadelight[0] = 0.1;
			gl_meshuboupdate.shadelight[1] = 0.1;
			gl_meshuboupdate.shadelight[2] = 0.1;
		}
	}

	if (e->flags & RF_GLOW)
	{
		// bonus items will pulse with time
		float	scale;
		float	min;

		scale = 0.1 * sin(r_newrefdef.time * 7);

		for (i = 0; i < 3; i++)
		{
			min = gl_meshuboupdate.shadelight[i] * 0.8;
			gl_meshuboupdate.shadelight[i] += scale;

			if (gl_meshuboupdate.shadelight[i] < min)
				gl_meshuboupdate.shadelight[i] = min;
		}
	}

	an = e->angles[1] / 180 * M_PI;
	Q_sincos(-an, &gl_meshuboupdate.shadevector[1], &gl_meshuboupdate.shadevector[0]);
	gl_meshuboupdate.shadevector[2] = 1;
	VectorNormalize(gl_meshuboupdate.shadevector);

	// locate the proper data
	c_alias_polys += hdr->num_tris;

	// draw all the triangles
	GL_LoadMatrix(&gl_meshuboupdate.localMatrix, &r_mvpmatrix);

	GL_TranslateMatrix(&gl_meshuboupdate.localMatrix, e->currorigin[0], e->currorigin[1], e->currorigin[2]);
	GL_RotateMatrix(&gl_meshuboupdate.localMatrix, e->angles[1], 0, 0, 1);
	GL_RotateMatrix(&gl_meshuboupdate.localMatrix, e->angles[0], 0, 1, 0);
	GL_RotateMatrix(&gl_meshuboupdate.localMatrix, -e->angles[2], 1, 0, 0);

	// select skin
	if (e->skin)
		skin = e->skin;	// custom player skin
	else
	{
		if (e->skinnum >= MAX_MD2SKINS)
			skin = e->model->skins[0];
		else
		{
			skin = e->model->skins[e->skinnum];

			if (!skin)
				skin = e->model->skins[0];
		}
	}

	if (!skin)
		skin = r_notexture;	// fallback...

	GL_BindTexture(GL_TEXTURE0, GL_TEXTURE_2D, r_modelsampler, skin->texnum);

	if ((e->currframe >= hdr->num_frames) || (e->currframe < 0))
	{
		VID_Printf(PRINT_ALL, S_COLOR_RED "R_DrawAliasModel %s: no such frame %d\n", e->model->name, e->currframe);
		e->currframe = 0;
		e->lastframe = 0;
	}

	if ((e->lastframe >= hdr->num_frames) || (e->lastframe < 0))
	{
		VID_Printf(PRINT_ALL, S_COLOR_RED "R_DrawAliasModel %s: no such oldframe %d\n", e->model->name, e->lastframe);
		e->currframe = 0;
		e->lastframe = 0;
	}

	if (!r_lerpmodels->value)
		e->backlerp = 0;

	lheight = e->currorigin[2] - lightspot[2];
	GL_TranslateMatrix(&gl_meshuboupdate.localMatrix, 0.0f, 0.0f, -lheight);

	shadowmatrix.m[0][0] = 1;
	shadowmatrix.m[0][1] = 0;
	shadowmatrix.m[0][2] = 0;
	shadowmatrix.m[0][3] = 0;

	shadowmatrix.m[1][0] = 0;
	shadowmatrix.m[1][1] = 1;
	shadowmatrix.m[1][2] = 0;
	shadowmatrix.m[1][3] = 0;

	shadowmatrix.m[2][0] = SHADOW_SKEW_X;
	shadowmatrix.m[2][1] = SHADOW_SKEW_Y;
	shadowmatrix.m[2][2] = SHADOW_VSCALE;
	shadowmatrix.m[2][3] = 0;

	shadowmatrix.m[3][0] = 0;
	shadowmatrix.m[3][1] = 0;
	shadowmatrix.m[3][2] = SHADOW_HEIGHT;
	shadowmatrix.m[3][3] = 1;

	GL_MultMatrix(&gl_meshuboupdate.localMatrix, &gl_meshuboupdate.localMatrix, &shadowmatrix);

	GL_TranslateMatrix(&gl_meshuboupdate.localMatrix, 0.0f, 0.0f, lheight);

	// draw shadow
	GL_DrawAliasFrameLerp(e, hdr, e->backlerp);
}
Ejemplo n.º 10
0
/*
=================
R_DrawAliasModel
=================
*/
void R_DrawAliasModel (entity_t *e)
{
	int			i;
	dmdl_t		*hdr;
	float		an;
	vec3_t		bbox[8];
	image_t		*skin;
	float		lightspot[3];

	if (!(e->flags & RF_WEAPONMODEL))
	{
		if (R_CullAliasModel (bbox, e))
			return;
	}

	if (e->flags & RF_WEAPONMODEL)
	{
		if (r_lefthand->value == 2)
			return;
	}

	hdr = (dmdl_t *) e->model->extradata;

	if (e->flags & (RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE))
	{
		VectorClear (gl_meshuboupdate.shadelight);

		if (e->flags & RF_SHELL_RED) gl_meshuboupdate.shadelight[0] = 1.0;
		if (e->flags & RF_SHELL_GREEN) gl_meshuboupdate.shadelight[1] = 1.0;
		if (e->flags & RF_SHELL_BLUE) gl_meshuboupdate.shadelight[2] = 1.0;
	}
	else if (e->flags & RF_FULLBRIGHT)
	{
		gl_meshuboupdate.shadelight[0] = 1.0;
		gl_meshuboupdate.shadelight[1] = 1.0;
		gl_meshuboupdate.shadelight[2] = 1.0;
	}
	else
	{
		dlight_t *l;
		int i;

		// grab static lighting from lightmap
		R_LightPoint (e->currorigin, gl_meshuboupdate.shadelight, lightspot);

		// grab dynamic lighting
		glProgramUniform1i (gl_meshprog, u_meshMaxLights, r_newrefdef.num_dlights);
		glProgramUniform3fv (gl_meshprog, u_meshEntOrig, 1, e->currorigin);
		for (i = 0, l = r_newrefdef.dlights; i < r_newrefdef.num_dlights; i++, l++)
		{
			glProgramUniform3fv (gl_meshprog, u_meshLightPos[i], 1, l->origin);
			glProgramUniform3fv (gl_meshprog, u_meshLightColor[i], 1, l->color);
			glProgramUniform1f (gl_meshprog, u_meshLightAtten[i], l->radius);
		}

		// player lighting hack for communication back to server
		// big hack!
		if (e->flags & RF_WEAPONMODEL)
		{
			// pick the greatest component, which should be the same
			// as the mono value returned by software
			if (gl_meshuboupdate.shadelight[0] > gl_meshuboupdate.shadelight[1])
			{
				if (gl_meshuboupdate.shadelight[0] > gl_meshuboupdate.shadelight[2])
					r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[0];
				else r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[2];
			}
			else
			{
				if (gl_meshuboupdate.shadelight[1] > gl_meshuboupdate.shadelight[2])
					r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[1];
				else r_lightlevel->value = 150 * gl_meshuboupdate.shadelight[2];
			}
		}
	}

	if (e->flags & RF_MINLIGHT)
	{
		for (i = 0; i < 3; i++)
		{
			if (gl_meshuboupdate.shadelight[i] > 0.1)
				break;
		}

		if (i == 3)
		{
			gl_meshuboupdate.shadelight[0] = 0.1;
			gl_meshuboupdate.shadelight[1] = 0.1;
			gl_meshuboupdate.shadelight[2] = 0.1;
		}
	}

	if (e->flags & RF_GLOW)
	{
		// bonus items will pulse with time
		float	scale;
		float	min;

		scale = 0.1 * sin (r_newrefdef.time * 7);

		for (i = 0; i < 3; i++)
		{
			min = gl_meshuboupdate.shadelight[i] * 0.8;
			gl_meshuboupdate.shadelight[i] += scale;

			if (gl_meshuboupdate.shadelight[i] < min)
				gl_meshuboupdate.shadelight[i] = min;
		}
	}

	an = e->angles[1] / 180 * M_PI;
	Q_sincos (-an, &gl_meshuboupdate.shadevector[1], &gl_meshuboupdate.shadevector[0]);
	gl_meshuboupdate.shadevector[2] = 1;
	VectorNormalize (gl_meshuboupdate.shadevector);

	// locate the proper data
	c_alias_polys += hdr->num_tris;

	// draw all the triangles
	if (e->flags & RF_DEPTHHACK) // hack the depth range to prevent view model from poking into walls
		glDepthRange (gldepthmin, gldepthmin + 0.3 * (gldepthmax - gldepthmin));

	if ((e->flags & RF_WEAPONMODEL) && (r_lefthand->value == 1.0F))
	{
		glmatrix gunmatrix;

		GL_LoadIdentity (&gunmatrix);
		GL_ScaleMatrix (&gunmatrix, -1, 1, 1);
		GL_PerspectiveMatrix (&gunmatrix, r_newrefdef.fov_y, (float) r_newrefdef.width / r_newrefdef.height);

		// eval a new mvp for left-handedness
		GL_LoadMatrix (&gl_meshuboupdate.localMatrix, &r_worldmatrix);
		GL_MultMatrix (&gl_meshuboupdate.localMatrix, &gl_meshuboupdate.localMatrix, &gunmatrix);

		glCullFace (GL_BACK);
	}
	else
		GL_LoadMatrix (&gl_meshuboupdate.localMatrix, &r_mvpmatrix);

	GL_TranslateMatrix (&gl_meshuboupdate.localMatrix, e->currorigin[0], e->currorigin[1], e->currorigin[2]);
	GL_RotateMatrix (&gl_meshuboupdate.localMatrix, e->angles[1], 0, 0, 1);
	GL_RotateMatrix (&gl_meshuboupdate.localMatrix, e->angles[0], 0, 1, 0);
	GL_RotateMatrix (&gl_meshuboupdate.localMatrix, -e->angles[2], 1, 0, 0);

	// select skin
	if (e->skin)
		skin = e->skin;	// custom player skin
	else
	{
		if (e->skinnum >= MAX_MD2SKINS)
			skin = e->model->skins[0];
		else
		{
			skin = e->model->skins[e->skinnum];

			if (!skin)
				skin = e->model->skins[0];
		}
	}

	if (!skin)
		skin = r_notexture;	// fallback...

	GL_BindTexture (GL_TEXTURE0, GL_TEXTURE_2D, r_modelsampler, skin->texnum);

	if ((e->currframe >= hdr->num_frames) || (e->currframe < 0))
	{
		VID_Printf (PRINT_ALL, S_COLOR_RED "R_DrawAliasModel %s: no such frame %d\n", e->model->name, e->currframe);
		e->currframe = 0;
		e->lastframe = 0;
	}

	if ((e->lastframe >= hdr->num_frames) || (e->lastframe < 0))
	{
		VID_Printf (PRINT_ALL, S_COLOR_RED "R_DrawAliasModel %s: no such oldframe %d\n", e->model->name, e->lastframe);
		e->currframe = 0;
		e->lastframe = 0;
	}

	if (!r_lerpmodels->value)
		e->backlerp = 0;

	GL_DrawAliasFrameLerp (e, hdr, e->backlerp);

	if ((e->flags & RF_WEAPONMODEL) && (r_lefthand->value == 1.0F))
	{
		glCullFace (GL_FRONT);
	}

	if (e->flags & RF_DEPTHHACK)
		glDepthRange (gldepthmin, gldepthmax);
}