/*
 ==================
 GL_Setup3D

 TODO: time is messed up
 ==================
*/
void GL_Setup3D (int time){

	double	clipPlane[4];

	QGL_LogPrintf("---------- RB_Setup3D ----------\n");

	backEnd.projection2D = false;

	backEnd.time = time;
	backEnd.floatTime = MS2SEC(Sys_Milliseconds());

	backEnd.viewport.x = backEnd.viewParms.viewport.x;
	backEnd.viewport.y = backEnd.viewParms.viewport.y;
	backEnd.viewport.width = backEnd.viewParms.viewport.width;
	backEnd.viewport.height = backEnd.viewParms.viewport.height;

	backEnd.scissor.x = backEnd.viewParms.scissor.x;
	backEnd.scissor.y = backEnd.viewParms.scissor.y;
	backEnd.scissor.width = backEnd.viewParms.scissor.width;
	backEnd.scissor.height = backEnd.viewParms.scissor.height;

	backEnd.coordScale[0] = 1.0f / backEnd.viewport.width;
	backEnd.coordScale[1] = 1.0f / backEnd.viewport.height;

	backEnd.coordBias[0] = -backEnd.viewport.x * backEnd.coordScale[0];
	backEnd.coordBias[1] = -backEnd.viewport.y * backEnd.coordScale[1];

	backEnd.depthFilling = false;
	backEnd.debugRendering = false;

	backEnd.currentColorCaptured = SORT_BAD;
	backEnd.currentDepthCaptured = false;

	// Set up the viewport
	GL_Viewport(backEnd.viewport);

	// Set up the scissor
	GL_Scissor(backEnd.viewport);

	// Set up the depth bounds
	if (glConfig.depthBoundsTestAvailable)
		GL_DepthBounds(0.0f, 1.0f);

	// Set the projection matrix
	GL_LoadMatrix(GL_PROJECTION, backEnd.viewParms.projectionMatrix);

	// Set the modelview matrix
	GL_LoadIdentity(GL_MODELVIEW);

	// Set the GL state
	GL_PolygonMode(GL_FILL);

	GL_Disable(GL_CULL_FACE);
	GL_Disable(GL_POLYGON_OFFSET_FILL);
	GL_Disable(GL_BLEND);
	GL_Disable(GL_ALPHA_TEST);
	GL_Disable(GL_DEPTH_TEST);
	GL_Disable(GL_STENCIL_TEST);

	GL_DepthRange(0.0f, 1.0f);

	GL_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	GL_DepthMask(GL_TRUE);
	GL_StencilMask(255);

	// Enable the clip plane if needed
	if (backEnd.viewParms.viewType != VIEW_MIRROR)
		qglDisable(GL_CLIP_PLANE0);
	else {
		clipPlane[0] = -DotProduct(backEnd.viewParms.axis[1], backEnd.viewParms.clipPlane.normal);
		clipPlane[1] = DotProduct(backEnd.viewParms.axis[2], backEnd.viewParms.clipPlane.normal);
		clipPlane[2] = -DotProduct(backEnd.viewParms.axis[0], backEnd.viewParms.clipPlane.normal);
		clipPlane[3] = DotProduct(backEnd.viewParms.origin, backEnd.viewParms.clipPlane.normal) - backEnd.viewParms.clipPlane.dist;

		qglEnable(GL_CLIP_PLANE0);
		qglClipPlane(GL_CLIP_PLANE0, clipPlane);
	}

	// Enable multisampling if available
	if (glConfig.multiSamples > 1)
		qglEnable(GL_MULTISAMPLE);

	// Clear the buffers
	qglClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	qglClearDepth(1.0f);
	qglClearStencil(0);

	if (backEnd.viewParms.primaryView)
		qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	else
		qglClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	// Check for errors
	if (!r_ignoreGLErrors->integerValue)
		GL_CheckForErrors();

	QGL_LogPrintf("--------------------\n");
}
Beispiel #2
0
/**
* @brief This routine is responsible for setting the most commonly changed state in Q3.
*/
void GL_State(uint32_t stateBits)
{
	uint32_t diff = stateBits ^ glState.glStateBits;

	if (!diff)
	{
		return;
	}

	// check depthFunc bits
	if (diff & GLS_DEPTHFUNC_BITS)
	{
		switch (stateBits & GLS_DEPTHFUNC_BITS)
		{
		default:
			GL_DepthFunc(GL_LEQUAL);
			break;
		case GLS_DEPTHFUNC_LESS:
			GL_DepthFunc(GL_LESS);
			break;
		case GLS_DEPTHFUNC_EQUAL:
			GL_DepthFunc(GL_EQUAL);
			break;
		}
	}

	// check blend bits
	if (diff & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS))
	{
		GLenum srcFactor, dstFactor;

		if (stateBits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS))
		{
			switch (stateBits & GLS_SRCBLEND_BITS)
			{
			case GLS_SRCBLEND_ZERO:
				srcFactor = GL_ZERO;
				break;
			case GLS_SRCBLEND_ONE:
				srcFactor = GL_ONE;
				break;
			case GLS_SRCBLEND_DST_COLOR:
				srcFactor = GL_DST_COLOR;
				break;
			case GLS_SRCBLEND_ONE_MINUS_DST_COLOR:
				srcFactor = GL_ONE_MINUS_DST_COLOR;
				break;
			case GLS_SRCBLEND_SRC_ALPHA:
				srcFactor = GL_SRC_ALPHA;
				break;
			case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA:
				srcFactor = GL_ONE_MINUS_SRC_ALPHA;
				break;
			case GLS_SRCBLEND_DST_ALPHA:
				srcFactor = GL_DST_ALPHA;
				break;
			case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA:
				srcFactor = GL_ONE_MINUS_DST_ALPHA;
				break;
			case GLS_SRCBLEND_ALPHA_SATURATE:
				srcFactor = GL_SRC_ALPHA_SATURATE;
				break;
			default:
				srcFactor = GL_ONE;     // to get warning to shut up
				Ren_Drop("GL_State: invalid src blend state bits\n");
				break;
			}

			switch (stateBits & GLS_DSTBLEND_BITS)
			{
			case GLS_DSTBLEND_ZERO:
				dstFactor = GL_ZERO;
				break;
			case GLS_DSTBLEND_ONE:
				dstFactor = GL_ONE;
				break;
			case GLS_DSTBLEND_SRC_COLOR:
				dstFactor = GL_SRC_COLOR;
				break;
			case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR:
				dstFactor = GL_ONE_MINUS_SRC_COLOR;
				break;
			case GLS_DSTBLEND_SRC_ALPHA:
				dstFactor = GL_SRC_ALPHA;
				break;
			case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA:
				dstFactor = GL_ONE_MINUS_SRC_ALPHA;
				break;
			case GLS_DSTBLEND_DST_ALPHA:
				dstFactor = GL_DST_ALPHA;
				break;
			case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA:
				dstFactor = GL_ONE_MINUS_DST_ALPHA;
				break;
			default:
				dstFactor = GL_ONE;     // to get warning to shut up
				Ren_Drop("GL_State: invalid dst blend state bits\n");
				break;
			}

			glEnable(GL_BLEND);
			GL_BlendFunc(srcFactor, dstFactor);
		}
		else
		{
			glDisable(GL_BLEND);
		}
	}

	// check colormask
	if (diff & GLS_COLORMASK_BITS)
	{
		if (stateBits & GLS_COLORMASK_BITS)
		{
			GL_ColorMask((stateBits & GLS_REDMASK_FALSE) ? GL_FALSE : GL_TRUE,
			             (stateBits & GLS_GREENMASK_FALSE) ? GL_FALSE : GL_TRUE,
			             (stateBits & GLS_BLUEMASK_FALSE) ? GL_FALSE : GL_TRUE,
			             (stateBits & GLS_ALPHAMASK_FALSE) ? GL_FALSE : GL_TRUE);
		}
		else
		{
			GL_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
		}
	}

	// check depthmask
	if (diff & GLS_DEPTHMASK_TRUE)
	{
		if (stateBits & GLS_DEPTHMASK_TRUE)
		{
			GL_DepthMask(GL_TRUE);
		}
		else
		{
			GL_DepthMask(GL_FALSE);
		}
	}

	// fill/line mode
	if (diff & GLS_POLYMODE_LINE)
	{
		if (stateBits & GLS_POLYMODE_LINE)
		{
			GL_PolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		}
		else
		{
			GL_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
		}
	}

	// depthtest
	if (diff & GLS_DEPTHTEST_DISABLE)
	{
		if (stateBits & GLS_DEPTHTEST_DISABLE)
		{
			glDisable(GL_DEPTH_TEST);
		}
		else
		{
			glEnable(GL_DEPTH_TEST);
		}
	}

	// alpha test - deprecated in OpenGL 3.0
#if 0
	if (diff & GLS_ATEST_BITS)
	{
		switch (stateBits & GLS_ATEST_BITS)
		{
		case GLS_ATEST_GT_0:
		case GLS_ATEST_LT_128:
		case GLS_ATEST_GE_128:
			//case GLS_ATEST_GT_CUSTOM:
			glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
			break;

		default:
		case 0:
			glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
			break;
		}
	}
#endif

	/*
	if(diff & GLS_ATEST_BITS)
	{
	switch (stateBits & GLS_ATEST_BITS)
	{
	case 0:
	glDisable(GL_ALPHA_TEST);
	break;
	case GLS_ATEST_GT_0:
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.0f);
	break;
	case GLS_ATEST_LT_80:
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_LESS, 0.5f);
	break;
	case GLS_ATEST_GE_80:
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GEQUAL, 0.5f);
	break;
	case GLS_ATEST_GT_CUSTOM:
	// FIXME
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.5f);
	break;
	default:
	assert(0);
	break;
	}
	}
	*/

	// stenciltest
	if (diff & GLS_STENCILTEST_ENABLE)
	{
		if (stateBits & GLS_STENCILTEST_ENABLE)
		{
			glEnable(GL_STENCIL_TEST);
		}
		else
		{
			glDisable(GL_STENCIL_TEST);
		}
	}

	glState.glStateBits = stateBits;
}
/*
 ==================
 GL_Setup2D

 TODO: time is messed up
 ==================
*/
void GL_Setup2D (int time){

	mat4_t	projectionMatrix = {2.0f / backEnd.cropWidth, 0.0f, 0.0f, 0.0f, 0.0f, -2.0f / backEnd.cropHeight, 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 0.0f, -1.0f, 1.0f, -1.0f, 1.0f};

	QGL_LogPrintf("---------- RB_Setup2D ----------\n");

	backEnd.projection2D = true;

	backEnd.time = time;
	backEnd.floatTime = MS2SEC(Sys_Milliseconds());

	backEnd.viewport.x = 0;
	backEnd.viewport.y = 0;
	backEnd.viewport.width = backEnd.cropWidth;
	backEnd.viewport.height = backEnd.cropHeight;

	backEnd.scissor.x = 0;
	backEnd.scissor.y = 0;
	backEnd.scissor.width = backEnd.cropWidth;
	backEnd.scissor.height = backEnd.cropHeight;

	backEnd.coordScale[0] = 1.0f / backEnd.viewport.width;
	backEnd.coordScale[1] = 1.0f / backEnd.viewport.height;

	backEnd.coordBias[0] = -backEnd.viewport.x * backEnd.coordScale[0];
	backEnd.coordBias[1] = -backEnd.viewport.y * backEnd.coordScale[1];

	backEnd.depthFilling = false;
	backEnd.debugRendering = false;

	backEnd.currentColorCaptured = SORT_BAD;
	backEnd.currentDepthCaptured = false;

	// Set up the viewport
	GL_Viewport(backEnd.viewport);

	// Set up the scissor
	GL_Scissor(backEnd.viewport);

	// Set up the depth bounds
	if (glConfig.depthBoundsTestAvailable)
		GL_DepthBounds(0.0f, 1.0f);

	// Set the projection matrix
	GL_LoadMatrix(GL_PROJECTION, projectionMatrix);

	// Set the modelview matrix
	GL_LoadIdentity(GL_MODELVIEW);

	// Set the GL state
	GL_PolygonMode(GL_FILL);

	GL_Disable(GL_CULL_FACE);
	GL_Disable(GL_POLYGON_OFFSET_FILL);
	GL_Disable(GL_BLEND);
	GL_Disable(GL_ALPHA_TEST);
	GL_Disable(GL_DEPTH_TEST);
	GL_Disable(GL_STENCIL_TEST);

	GL_DepthRange(0.0f, 1.0f);

	GL_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	GL_DepthMask(GL_FALSE);
	GL_StencilMask(255);

	// Disable the clip plane
	qglDisable(GL_CLIP_PLANE0);

	// Disable multisampling if available
	if (glConfig.multiSamples > 1)
		qglDisable(GL_MULTISAMPLE);

	// Check for errors
	if (!r_ignoreGLErrors->integerValue)
		GL_CheckForErrors();

	QGL_LogPrintf("--------------------\n");
}