Beispiel #1
0
void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy, int cm)
{
	AActor * playermo=players[consoleplayer].camera;
	FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->state->sprite, psp->state->GetFrame());

	// [BB] No model found for this sprite, so we can't render anything.
	if ( smf == NULL )
		return;

	// [BB] The model has to be drawn independtly from the position of the player,
	// so we have to reset the GL_MODELVIEW matrix.
	gl.MatrixMode(GL_MODELVIEW);
	gl.PushMatrix();
	gl.LoadIdentity();
	gl.DepthFunc(GL_LEQUAL);

	// [BB] In case the model should be rendered translucent, do back face culling.
	// This solves a few of the problems caused by the lack of depth sorting.
	// TO-DO: Implement proper depth sorting.
	if (!( playermo->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
	{
		gl.Enable(GL_CULL_FACE);
		glFrontFace(GL_CCW);
	}

	// Scaling and model space offset.
	gl.Scalef(	
		smf->xscale,
		smf->zscale,	// y scale for a sprite means height, i.e. z in the world!
		smf->yscale);

	// [BB] Apply zoffset here, needs to be scaled by 1 / smf->zscale, so that zoffset doesn't depend on the z-scaling.
	gl.Translatef(0., smf->zoffset / smf->zscale, 0.);

	// [BB] Weapon bob, very similar to the normal Doom weapon bob.
	gl.Rotatef(FIXED2FLOAT(ofsx)/4, 0, 1, 0);
	gl.Rotatef(-FIXED2FLOAT(ofsy-WEAPONTOP)/4, 1, 0, 0);

	// [BB] For some reason the jDoom models need to be rotated.
	gl.Rotatef(90., 0, 1, 0);

	gl_RenderFrameModels( smf, psp->state, psp->tics, playermo->player->ReadyWeapon->GetClass(), cm, NULL, NULL, 0 );

	gl.MatrixMode(GL_MODELVIEW);
	gl.PopMatrix();
	gl.DepthFunc(GL_LESS);
	if (!( playermo->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
		gl.Disable(GL_CULL_FACE);
}
Beispiel #2
0
void gl_RenderHUDModel(DPSprite *psp, float ofsX, float ofsY)
{
	AActor * playermo=players[consoleplayer].camera;
	FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false);

	// [BB] No model found for this sprite, so we can't render anything.
	if ( smf == nullptr )
		return;

	glDepthFunc(GL_LEQUAL);

	// [BB] In case the model should be rendered translucent, do back face culling.
	// This solves a few of the problems caused by the lack of depth sorting.
	// TO-DO: Implement proper depth sorting.
	if (!( playermo->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
	{
		glEnable(GL_CULL_FACE);
		glFrontFace(GL_CCW);
	}

	// [BB] The model has to be drawn independently from the position of the player,
	// so we have to reset the view matrix.
	gl_RenderState.mViewMatrix.loadIdentity();

	// Scaling model (y scale for a sprite means height, i.e. z in the world!).
	gl_RenderState.mViewMatrix.scale(smf->xscale, smf->zscale, smf->yscale);
	
	// Aplying model offsets (model offsets do not depend on model scalings).
	gl_RenderState.mViewMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale);

	// [BB] Weapon bob, very similar to the normal Doom weapon bob.
	gl_RenderState.mViewMatrix.rotate(ofsX/4, 0, 1, 0);
	gl_RenderState.mViewMatrix.rotate((ofsY-WEAPONTOP)/-4., 1, 0, 0);

	// [BB] For some reason the jDoom models need to be rotated.
	gl_RenderState.mViewMatrix.rotate(90.f, 0, 1, 0);

	// Applying angleoffset, pitchoffset, rolloffset.
	gl_RenderState.mViewMatrix.rotate(-smf->angleoffset, 0, 1, 0);
	gl_RenderState.mViewMatrix.rotate(smf->pitchoffset, 0, 0, 1);
	gl_RenderState.mViewMatrix.rotate(-smf->rolloffset, 1, 0, 0);
	gl_RenderState.ApplyMatrices();

	gl_RenderFrameModels( smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), nullptr, 0 );

	glDepthFunc(GL_LESS);
	if (!( playermo->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
		glDisable(GL_CULL_FACE);
}
Beispiel #3
0
void gl_RenderModel(GLSprite * spr)
{
	FSpriteModelFrame * smf = spr->modelframe;


	// Setup transformation.
	glDepthFunc(GL_LEQUAL);
	gl_RenderState.EnableTexture(true);
	// [BB] In case the model should be rendered translucent, do back face culling.
	// This solves a few of the problems caused by the lack of depth sorting.
	// TO-DO: Implement proper depth sorting.
	if (!( spr->actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
	{
		glEnable(GL_CULL_FACE);
		glFrontFace(GL_CW);
	}

	int translation = 0;
	if ( !(smf->flags & MDL_IGNORETRANSLATION) )
		translation = spr->actor->Translation;


	// y scale for a sprite means height, i.e. z in the world!
	float scaleFactorX = spr->actor->Scale.X * smf->xscale;
	float scaleFactorY = spr->actor->Scale.X * smf->yscale;
	float scaleFactorZ = spr->actor->Scale.Y * smf->zscale;
	float pitch = 0;
	float roll = 0;
	float rotateOffset = 0;
	float angle = spr->actor->Angles.Yaw.Degrees;

	// [BB] Workaround for the missing pitch information.
	if ( (smf->flags & MDL_PITCHFROMMOMENTUM) )
	{
		const double x = spr->actor->Vel.X;
		const double y = spr->actor->Vel.Y;
		const double z = spr->actor->Vel.Z;

		if (spr->actor->Vel.LengthSquared() > EQUAL_EPSILON)
		{
			// [BB] Calculate the pitch using spherical coordinates.
			if (z || x || y) pitch = float(atan(z / sqrt(x*x + y*y)) / M_PI * 180);

			// Correcting pitch if model is moving backwards
			if (fabs(x) > EQUAL_EPSILON || fabs(y) > EQUAL_EPSILON)
			{
				if ((x * cos(angle * M_PI / 180) + y * sin(angle * M_PI / 180)) / sqrt(x * x + y * y) < 0) pitch *= -1;
			}
			else pitch = fabs(pitch);
		}
	}

	if( smf->flags & MDL_ROTATING )
	{
		const float time = smf->rotationSpeed*GetTimeFloat()/200.f;
		rotateOffset = float((time - xs_FloorToInt(time)) *360.f );
	}

	// Added MDL_USEACTORPITCH and MDL_USEACTORROLL flags processing.
	// If both flags MDL_USEACTORPITCH and MDL_PITCHFROMMOMENTUM are set, the pitch sums up the actor pitch and the momentum vector pitch.
	if (smf->flags & MDL_USEACTORPITCH)
	{
		double d = spr->actor->Angles.Pitch.Degrees;
		if (smf->flags & MDL_BADROTATION) pitch -= d;
		else pitch += d;
	}
	if(smf->flags & MDL_USEACTORROLL) roll += spr->actor->Angles.Roll.Degrees;

	gl_RenderState.mModelMatrix.loadIdentity();

	// Model space => World space
	gl_RenderState.mModelMatrix.translate(spr->x, spr->z, spr->y );	
	
	// Applying model transformations:
	// 1) Applying actor angle, pitch and roll to the model
	gl_RenderState.mModelMatrix.rotate(-angle, 0, 1, 0);
	gl_RenderState.mModelMatrix.rotate(pitch, 0, 0, 1);
	gl_RenderState.mModelMatrix.rotate(-roll, 1, 0, 0);
	
	// 2) Applying Doomsday like rotation of the weapon pickup models
	// The rotation angle is based on the elapsed time.
	
	if( smf->flags & MDL_ROTATING )
	{
		gl_RenderState.mModelMatrix.translate(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ);
		gl_RenderState.mModelMatrix.rotate(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate);
		gl_RenderState.mModelMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ);
	}

	// 3) Scaling model.
	gl_RenderState.mModelMatrix.scale(scaleFactorX, scaleFactorZ, scaleFactorY);

	// 4) Aplying model offsets (model offsets do not depend on model scalings).
	gl_RenderState.mModelMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale);
	
	// 5) Applying model rotations.
	gl_RenderState.mModelMatrix.rotate(-smf->angleoffset, 0, 1, 0);
	gl_RenderState.mModelMatrix.rotate(smf->pitchoffset, 0, 0, 1);
	gl_RenderState.mModelMatrix.rotate(-smf->rolloffset, 1, 0, 0);

	// consider the pixel stretching. For non-voxels this must be factored out here
	float stretch = (smf->modelIDs[0] != -1 ? Models[smf->modelIDs[0]]->getAspectFactor() : 1.f) / glset.pixelstretch;
	gl_RenderState.mModelMatrix.scale(1, stretch, 1);


	gl_RenderState.EnableModelMatrix(true);
	gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, spr->actor->GetClass(), nullptr, translation );
	gl_RenderState.EnableModelMatrix(false);

	glDepthFunc(GL_LESS);
	if (!( spr->actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
		glDisable(GL_CULL_FACE);
}
Beispiel #4
0
void gl_RenderModel(GLSprite * spr, int cm)
{
	// [BB/EP] Take care of gl_fogmode and ZADF_FORCE_GL_DEFAULTS.
	OVERRIDE_FOGMODE_IF_NECESSARY

	FSpriteModelFrame * smf = spr->modelframe;


	// Setup transformation.
	gl.MatrixMode(GL_MODELVIEW);
	gl.PushMatrix();
	gl.DepthFunc(GL_LEQUAL);
	// [BB] In case the model should be rendered translucent, do back face culling.
	// This solves a few of the problems caused by the lack of depth sorting.
	// TO-DO: Implement proper depth sorting.
	if (!( spr->actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
	{
		gl.Enable(GL_CULL_FACE);
		glFrontFace(GL_CW);
	}

	int translation = 0;
	if ( !(smf->flags & MDL_IGNORETRANSLATION) )
		translation = spr->actor->Translation;


	// y scale for a sprite means height, i.e. z in the world!
	float scaleFactorX = FIXED2FLOAT(spr->actor->scaleX) * smf->xscale;
	float scaleFactorY = FIXED2FLOAT(spr->actor->scaleX) * smf->yscale;
	float scaleFactorZ = FIXED2FLOAT(spr->actor->scaleY) * smf->zscale;
	float pitch = 0;
	float rotateOffset = 0;
	float angle = ANGLE_TO_FLOAT(spr->actor->angle);

	// [BB] Workaround for the missing pitch information.
	if ( (smf->flags & MDL_PITCHFROMMOMENTUM) )
	{
		const double x = static_cast<double>(spr->actor->velx);
		const double y = static_cast<double>(spr->actor->vely);
		const double z = static_cast<double>(spr->actor->velz);
		// [BB] Calculate the pitch using spherical coordinates.
		
		pitch = float(atan( z/sqrt(x*x+y*y) ) / M_PI * 180);
	}

	if( smf->flags & MDL_ROTATING )
	{
		const float time = smf->rotationSpeed*GetTimeFloat()/200.f;
		rotateOffset = float((time - xs_FloorToInt(time)) *360.f );
	}

	if (gl_fogmode != 2 && (GLRenderer->mLightCount == 0 || !gl_light_models))
	{
		// Model space => World space
		gl.Translatef(spr->x, spr->z, spr->y );

		if ( !(smf->flags & MDL_ALIGNANGLE) )
			gl.Rotatef(-angle, 0, 1, 0);
		// [BB] Change the angle so that the object is exactly facing the camera in the x/y plane.
		else
			gl.Rotatef( -ANGLE_TO_FLOAT ( R_PointToAngle ( spr->actor->x, spr->actor->y ) ), 0, 1, 0);

		// [BB] Change the pitch so that the object is vertically facing the camera (only makes sense combined with MDL_ALIGNANGLE).
		if ( (smf->flags & MDL_ALIGNPITCH) )
		{
			const fixed_t distance = R_PointToDist2( spr->actor->x - viewx, spr->actor->y - viewy );
			const float pitch = RAD2DEG ( atan2( FIXED2FLOAT ( spr->actor->z - viewz ), FIXED2FLOAT ( distance ) ) );
			gl.Rotatef(pitch, 0, 0, 1);
		}

		// [BB] Workaround for the missing pitch information.
		if (pitch != 0)	gl.Rotatef(pitch, 0, 0, 1);

		// [BB] Special flag for flat, beam like models.
		if ( (smf->flags & MDL_ROLLAGAINSTANGLE) )
			gl.Rotatef( gl_RollAgainstAngleHelper ( spr->actor ), 1, 0, 0);

		// Model rotation.
		// [BB] Added Doomsday like rotation of the weapon pickup models.
		// The rotation angle is based on the elapsed time.

		if( smf->flags & MDL_ROTATING )
		{
			gl.Translatef(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ);
			gl.Rotatef(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate);
			gl.Translatef(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ);
		} 		

		// Scaling and model space offset.
		gl.Scalef(scaleFactorX, scaleFactorZ, scaleFactorY);

		// [BB] Apply zoffset here, needs to be scaled by 1 / smf->zscale, so that zoffset doesn't depend on the z-scaling.
		gl.Translatef(0., smf->zoffset / smf->zscale, 0.);

		gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, NULL, NULL, translation );
	}
	else
	{
		Matrix3x4 ModelToWorld;
		Matrix3x4 NormalTransform;

		// For radial fog we need to pass coordinates in world space in order to calculate distances.
		// That means that the local transformations cannot be part of the modelview matrix

		ModelToWorld.MakeIdentity();

		// Model space => World space
		ModelToWorld.Translate(spr->x, spr->z, spr->y);

		if ( !(smf->flags & MDL_ALIGNANGLE) )
			ModelToWorld.Rotate(0,1,0, -angle);
		// [BB] Change the angle so that the object is exactly facing the camera in the x/y plane.
		else
			ModelToWorld.Rotate(0,1,0, -ANGLE_TO_FLOAT ( R_PointToAngle ( spr->actor->x, spr->actor->y ) ) );

		// [BB] Change the pitch so that the object is vertically facing the camera (only makes sense combined with MDL_ALIGNANGLE).
		if ( (smf->flags & MDL_ALIGNPITCH) )
		{
			const fixed_t distance = R_PointToDist2( spr->actor->x - viewx, spr->actor->y - viewy );
			const float pitch = RAD2DEG ( atan2( FIXED2FLOAT ( spr->actor->z - viewz ), FIXED2FLOAT ( distance ) ) );
			ModelToWorld.Rotate(0,0,1,pitch);
		}

		// [BB] Workaround for the missing pitch information.
		if (pitch != 0) ModelToWorld.Rotate(0,0,1,pitch);

		// [BB] Special flag for flat, beam like models.
		if ( (smf->flags & MDL_ROLLAGAINSTANGLE) )
			ModelToWorld.Rotate(1, 0, 0, gl_RollAgainstAngleHelper ( spr->actor ));

		// Model rotation.
		// [BB] Added Doomsday like rotation of the weapon pickup models.
		// The rotation angle is based on the elapsed time.

		if( smf->flags & MDL_ROTATING )
		{
			ModelToWorld.Translate(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ);
			ModelToWorld.Rotate(smf->xrotate, smf->yrotate, smf->zrotate, rotateOffset);
			ModelToWorld.Translate(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ);
		}

		ModelToWorld.Scale(scaleFactorX, scaleFactorZ, scaleFactorY);

		// [BB] Apply zoffset here, needs to be scaled by 1 / smf->zscale, so that zoffset doesn't depend on the z-scaling.
		ModelToWorld.Translate(0., smf->zoffset / smf->zscale, 0.);

		if (!gl_light_models)
		{
			gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, &ModelToWorld, NULL, translation );
		}
		else
		{
			// The normal transform matrix only contains the inverse rotations and scalings but not the translations
			NormalTransform.MakeIdentity();

			NormalTransform.Scale(1.f/scaleFactorX, 1.f/scaleFactorZ, 1.f/scaleFactorY);
			if( smf->flags & MDL_ROTATING ) NormalTransform.Rotate(smf->xrotate, smf->yrotate, smf->zrotate, -rotateOffset);
			if (pitch != 0) NormalTransform.Rotate(0,0,1,-pitch);
			if (angle != 0) NormalTransform.Rotate(0,1,0, angle);

			gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, &ModelToWorld, &NormalTransform, translation );
		}

	}

	gl.MatrixMode(GL_MODELVIEW);
	gl.PopMatrix();
	gl.DepthFunc(GL_LESS);
	if (!( spr->actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
		gl.Disable(GL_CULL_FACE);
}