Example #1
0
void
R_DrawAliasModel ( entity_t *e )
{
	int i;
	dmdl_t      *paliashdr;
	float an;
	vec3_t bbox [ 8 ];
	image_t     *skin;

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

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

	paliashdr = (dmdl_t *) currentmodel->extradata;

	/* get lighting information */
	if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) )
	{
		VectorClear( shadelight );

		if ( currententity->flags & RF_SHELL_HALF_DAM )
		{
			shadelight [ 0 ] = 0.56;
			shadelight [ 1 ] = 0.59;
			shadelight [ 2 ] = 0.45;
		}

		if ( currententity->flags & RF_SHELL_DOUBLE )
		{
			shadelight [ 0 ] = 0.9;
			shadelight [ 1 ] = 0.7;
		}

		if ( currententity->flags & RF_SHELL_RED )
		{
			shadelight [ 0 ] = 1.0;
		}

		if ( currententity->flags & RF_SHELL_GREEN )
		{
			shadelight [ 1 ] = 1.0;
		}

		if ( currententity->flags & RF_SHELL_BLUE )
		{
			shadelight [ 2 ] = 1.0;
		}
	}
	else if ( currententity->flags & RF_FULLBRIGHT )
	{
		for ( i = 0; i < 3; i++ )
		{
			shadelight [ i ] = 1.0;
		}
	}
	else
	{
		R_LightPoint( currententity->origin, shadelight );

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

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

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

	if ( currententity->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 = shadelight [ i ] * 0.8;
			shadelight [ i ] += scale;

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

	/* ir goggles color override */
	if ( r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE )
	{
		shadelight [ 0 ] = 1.0;
		shadelight [ 1 ] = 0.0;
		shadelight [ 2 ] = 0.0;
	}

	shadedots =
		r_avertexnormal_dots [ ( (int) ( currententity->angles [ 1 ] * ( SHADEDOT_QUANT / 360.0 ) ) ) & ( SHADEDOT_QUANT - 1 ) ];

	an = currententity->angles [ 1 ] / 180 * M_PI;
	shadevector [ 0 ] = cos( -an );
	shadevector [ 1 ] = sin( -an );
	shadevector [ 2 ] = 1;
	VectorNormalize( shadevector );

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

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

	if ( ( currententity->flags & RF_WEAPONMODEL ) && ( gl_lefthand->value == 1.0F ) )
	{
		extern void R_MYgluPerspective ( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar );

		qglMatrixMode( GL_PROJECTION );
		qglPushMatrix();
		qglLoadIdentity();
		qglScalef( -1, 1, 1 );
		R_MYgluPerspective( r_newrefdef.fov_y, (float) r_newrefdef.width / r_newrefdef.height,  4,  4096 );
		qglMatrixMode( GL_MODELVIEW );

		qglCullFace( GL_BACK );
	}

	qglPushMatrix();
	e->angles [ PITCH ] = -e->angles [ PITCH ];
	R_RotateForEntity( e );
	e->angles [ PITCH ] = -e->angles [ PITCH ];

	/* select skin */
	if ( currententity->skin )
	{
		skin = currententity->skin; /* custom player skin */
	}
	else
	{
		if ( currententity->skinnum >= MAX_MD2SKINS )
		{
			skin = currentmodel->skins [ 0 ];
		}
		else
		{
			skin = currentmodel->skins [ currententity->skinnum ];

			if ( !skin )
			{
				skin = currentmodel->skins [ 0 ];
			}
		}
	}

	if ( !skin )
	{
		skin = r_notexture; /* fallback... */
	}

	R_Bind( skin->texnum );

	/* draw it */
	qglShadeModel( GL_SMOOTH );

	R_TexEnv( GL_MODULATE );

	if ( currententity->flags & RF_TRANSLUCENT )
	{
		qglEnable( GL_BLEND );
	}

	if ( ( currententity->frame >= paliashdr->num_frames ) ||
		 ( currententity->frame < 0 ) )
	{
		ri.Con_Printf( PRINT_ALL, "R_DrawAliasModel %s: no such frame %d\n",
				currentmodel->name, currententity->frame );
		currententity->frame = 0;
		currententity->oldframe = 0;
	}

	if ( ( currententity->oldframe >= paliashdr->num_frames ) ||
		 ( currententity->oldframe < 0 ) )
	{
		ri.Con_Printf( PRINT_ALL, "R_DrawAliasModel %s: no such oldframe %d\n",
				currentmodel->name, currententity->oldframe );
		currententity->frame = 0;
		currententity->oldframe = 0;
	}

	if ( !gl_lerpmodels->value )
	{
		currententity->backlerp = 0;
	}

	R_DrawAliasFrameLerp( paliashdr, currententity->backlerp );

	R_TexEnv( GL_REPLACE );
	qglShadeModel( GL_FLAT );

	qglPopMatrix();

	if ( ( currententity->flags & RF_WEAPONMODEL ) && ( gl_lefthand->value == 1.0F ) )
	{
		qglMatrixMode( GL_PROJECTION );
		qglPopMatrix();
		qglMatrixMode( GL_MODELVIEW );
		qglCullFace( GL_FRONT );
	}

	if ( currententity->flags & RF_TRANSLUCENT )
	{
		qglDisable( GL_BLEND );
	}

	if ( currententity->flags & RF_DEPTHHACK )
	{
		qglDepthRange( gldepthmin, gldepthmax );
	}

	if ( gl_shadows->value &&
		 !( currententity->flags & ( RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW ) ) )
	{
		qglPushMatrix();

		/* don't rotate shadows on ungodly axes */
		qglTranslatef( e->origin [ 0 ], e->origin [ 1 ], e->origin [ 2 ] );
		qglRotatef( e->angles [ 1 ], 0, 0, 1 );

		qglDisable( GL_TEXTURE_2D );
		qglEnable( GL_BLEND );
		qglColor4f( 0, 0, 0, 0.5f );
		R_DrawAliasShadow( paliashdr, currententity->frame );
		qglEnable( GL_TEXTURE_2D );
		qglDisable( GL_BLEND );
		qglPopMatrix();
	}

	qglColor4f( 1, 1, 1, 1 );
}
Example #2
0
/*
 * This is also used as an entry point for the generated r_notexture
 */
gl3image_t *
GL3_LoadPic(char *name, byte *pic, int width, int realwidth,
            int height, int realheight, imagetype_t type, int bits)
{
	gl3image_t *image = NULL;
	GLuint texNum=0;
	int i;

	qboolean nolerp = false;

	if (gl_nolerp_list != NULL && gl_nolerp_list->string != NULL)
	{
		nolerp = strstr(gl_nolerp_list->string, name) != NULL;
	}
	/* find a free gl3image_t */
	for (i = 0, image = gl3textures; i < numgl3textures; i++, image++)
	{
		if (image->texnum == 0)
		{
			break;
		}
	}

	if (i == numgl3textures)
	{
		if (numgl3textures == MAX_GL3TEXTURES)
		{
			ri.Sys_Error(ERR_DROP, "MAX_GLTEXTURES");
		}

		numgl3textures++;
	}

	image = &gl3textures[i];

	if (strlen(name) >= sizeof(image->name))
	{
		ri.Sys_Error(ERR_DROP, "GL3_LoadPic: \"%s\" is too long", name);
	}

	strcpy(image->name, name);
	image->registration_sequence = registration_sequence;

	image->width = width;
	image->height = height;
	image->type = type;

	if ((type == it_skin) && (bits == 8))
	{
		FloodFillSkin(pic, width, height);

	}

	// image->scrap = false; // TODO: reintroduce scrap? would allow optimizations in 2D rendering..

	glGenTextures(1, &texNum);

	image->texnum = texNum;

	GL3_SelectTMU(GL_TEXTURE0);
	GL3_Bind(texNum);

	if (bits == 8)
	{
		image->has_alpha = GL3_Upload8(pic, width, height,
					(image->type != it_pic && image->type != it_sky),
					image->type == it_sky);
	}
	else
	{
		image->has_alpha = GL3_Upload32((unsigned *)pic, width, height,
					(image->type != it_pic && image->type != it_sky));
	}

	if (realwidth && realheight)
	{
		if ((realwidth <= image->width) && (realheight <= image->height))
		{
			image->width = realwidth;
			image->height = realheight;
		}
		else
		{
			R_Printf(PRINT_DEVELOPER,
					"Warning, image '%s' has hi-res replacement smaller than the original! (%d x %d) < (%d x %d)\n",
					name, image->width, image->height, realwidth, realheight);
		}
	}

	image->sl = 0;
	image->sh = 1;
	image->tl = 0;
	image->th = 1;

	if (nolerp)
	{
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	}
#if 0 // TODO: the scrap could allow batch rendering 2D stuff? not sure it's worth the hassle..
	/* load little pics into the scrap */
	if (!nolerp && (image->type == it_pic) && (bits == 8) &&
		(image->width < 64) && (image->height < 64))
	{
		int x, y;
		int i, j, k;
		int texnum;

		texnum = Scrap_AllocBlock(image->width, image->height, &x, &y);

		if (texnum == -1)
		{
			goto nonscrap;
		}

		scrap_dirty = true;

		/* copy the texels into the scrap block */
		k = 0;

		for (i = 0; i < image->height; i++)
		{
			for (j = 0; j < image->width; j++, k++)
			{
				scrap_texels[texnum][(y + i) * BLOCK_WIDTH + x + j] = pic[k];
			}
		}

		image->texnum = TEXNUM_SCRAPS + texnum;
		image->scrap = true;
		image->has_alpha = true;
		image->sl = (x + 0.01) / (float)BLOCK_WIDTH;
		image->sh = (x + image->width - 0.01) / (float)BLOCK_WIDTH;
		image->tl = (y + 0.01) / (float)BLOCK_WIDTH;
		image->th = (y + image->height - 0.01) / (float)BLOCK_WIDTH;
	}
	else
	{
	nonscrap:
		image->scrap = false;
		image->texnum = TEXNUM_IMAGES + (image - gltextures);
		R_Bind(image->texnum);

		if (bits == 8)
		{
			image->has_alpha = R_Upload8(pic, width, height,
						(image->type != it_pic && image->type != it_sky),
						image->type == it_sky);
		}
		else
		{
			image->has_alpha = R_Upload32((unsigned *)pic, width, height,
						(image->type != it_pic && image->type != it_sky));
		}

		image->upload_width = upload_width; /* after power of 2 and scales */
		image->upload_height = upload_height;
		image->paletted = uploaded_paletted;

		if (realwidth && realheight)
		{
			if ((realwidth <= image->width) && (realheight <= image->height))
			{
				image->width = realwidth;
				image->height = realheight;
			}
			else
			{
				R_Printf(PRINT_DEVELOPER,
						"Warning, image '%s' has hi-res replacement smaller than the original! (%d x %d) < (%d x %d)\n",
						name, image->width, image->height, realwidth, realheight);
			}
		}

		image->sl = 0;
		image->sh = 1;
		image->tl = 0;
		image->th = 1;

		if (nolerp)
		{
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		}
	}
#endif // 0
	return image;
}