Esempio n. 1
0
void apply(CoreRenderingStatus & target, const CoreRenderingStatus & actual, bool forced) {
	// Blending
	if(forced || target.blendingParametersChanged(actual)) {
		const BlendingParameters & targetParams = target.getBlendingParameters();
		const BlendingParameters & actualParams = actual.getBlendingParameters();
		if(forced || targetParams.isEnabled() != actualParams.isEnabled()) {
			if(actualParams.isEnabled()) {
				glEnable(GL_BLEND);
			} else {
				glDisable(GL_BLEND);
			}
		}
		if(forced ||
				targetParams.getBlendFuncSrcRGB() != actualParams.getBlendFuncSrcRGB() ||
				targetParams.getBlendFuncDstRGB() != actualParams.getBlendFuncDstRGB() ||
				targetParams.getBlendFuncSrcAlpha() != actualParams.getBlendFuncSrcAlpha() ||
				targetParams.getBlendFuncDstAlpha() != actualParams.getBlendFuncDstAlpha()) {
			glBlendFuncSeparate(BlendingParameters::functionToGL(actualParams.getBlendFuncSrcRGB()),
								BlendingParameters::functionToGL(actualParams.getBlendFuncDstRGB()),
								BlendingParameters::functionToGL(actualParams.getBlendFuncSrcAlpha()),
								BlendingParameters::functionToGL(actualParams.getBlendFuncDstAlpha()));
		}
		if(forced || targetParams.getBlendColor() != actualParams.getBlendColor()) {
			glBlendColor(actualParams.getBlendColor().getR(),
						 actualParams.getBlendColor().getG(),
						 actualParams.getBlendColor().getB(),
						 actualParams.getBlendColor().getA());
		}
		if(forced ||
				targetParams.getBlendEquationRGB() != actualParams.getBlendEquationRGB() ||
				targetParams.getBlendEquationAlpha() != actualParams.getBlendEquationAlpha()) {
			glBlendEquationSeparate(BlendingParameters::equationToGL(actualParams.getBlendEquationRGB()),
									BlendingParameters::equationToGL(actualParams.getBlendEquationAlpha()));
		}
		target.updateBlendingParameters(actual);
	}

	// ColorBuffer
	if(forced || target.colorBufferParametersChanged(actual)) {
		glColorMask(
			actual.getColorBufferParameters().isRedWritingEnabled() ? GL_TRUE : GL_FALSE,
			actual.getColorBufferParameters().isGreenWritingEnabled() ? GL_TRUE : GL_FALSE,
			actual.getColorBufferParameters().isBlueWritingEnabled() ? GL_TRUE : GL_FALSE,
			actual.getColorBufferParameters().isAlphaWritingEnabled() ? GL_TRUE : GL_FALSE
		);
		target.setColorBufferParameters(actual.getColorBufferParameters());
	}
	GET_GL_ERROR();

	// CullFace
	if(forced || target.cullFaceParametersChanged(actual)) {
		if(actual.getCullFaceParameters().isEnabled()) {
			glEnable(GL_CULL_FACE);

		} else {
			glDisable(GL_CULL_FACE);
		}
		switch(actual.getCullFaceParameters().getMode()) {
			case CullFaceParameters::CULL_BACK:
				glCullFace(GL_BACK);
				break;
			case CullFaceParameters::CULL_FRONT:
				glCullFace(GL_FRONT);
				break;
			case CullFaceParameters::CULL_FRONT_AND_BACK:
				glCullFace(GL_FRONT_AND_BACK);
				break;
			default:
				throw std::invalid_argument("Invalid CullFaceParameters::cullFaceMode_t enumerator");
		}
		target.setCullFaceParameters(actual.getCullFaceParameters());
	}

	// DepthBuffer
	if(forced || target.depthBufferParametersChanged(actual)) {
		if(actual.getDepthBufferParameters().isTestEnabled()) {
			glEnable(GL_DEPTH_TEST);
		} else {
			glDisable(GL_DEPTH_TEST);
		}
		if(actual.getDepthBufferParameters().isWritingEnabled()) {
			glDepthMask(GL_TRUE);
		} else {
			glDepthMask(GL_FALSE);
		}
		glDepthFunc(Comparison::functionToGL(actual.getDepthBufferParameters().getFunction()));
		target.setDepthBufferParameters(actual.getDepthBufferParameters());
	}
	GET_GL_ERROR();

	// Line
	if(forced || target.lineParametersChanged(actual)) {
		auto width = actual.getLineParameters().getWidth();
		glLineWidth(RenderingContext::getCompabilityMode() ? width : std::min(width, 1.0f));
		target.setLineParameters(actual.getLineParameters());
	}

	// stencil
	if (forced || target.stencilParametersChanged(actual)) {
		const StencilParameters & targetParams = target.getStencilParameters();
		const StencilParameters & actualParams = actual.getStencilParameters();
		if(forced || targetParams.isEnabled() != actualParams.isEnabled()) {
			if(actualParams.isEnabled()) {
				glEnable(GL_STENCIL_TEST);
			} else {
				glDisable(GL_STENCIL_TEST);
			}
		}
		if(forced || targetParams.differentFunctionParameters(actualParams)) {
			glStencilFunc(Comparison::functionToGL(actualParams.getFunction()), actualParams.getReferenceValue(), actualParams.getBitMask().to_ulong());
		}
		if(forced || targetParams.differentActionParameters(actualParams)) {
			glStencilOp(convertStencilAction(actualParams.getFailAction()),
						convertStencilAction(actualParams.getDepthTestFailAction()),
						convertStencilAction(actualParams.getDepthTestPassAction()));
		}
		target.updateStencilParameters(actual);
	}

	GET_GL_ERROR();

#ifdef LIB_GL
 	if(RenderingContext::getCompabilityMode()) {
		// AlphaTest
		if(forced || target.alphaTestParametersChanged(actual)) {
			if(actual.getAlphaTestParameters().isEnabled()) {
				glDisable(GL_ALPHA_TEST);
			} else {
				glEnable(GL_ALPHA_TEST);
			}
			glAlphaFunc(Comparison::functionToGL(actual.getAlphaTestParameters().getMode()), actual.getAlphaTestParameters().getReferenceValue());
			target.setAlphaTestParameters(actual.getAlphaTestParameters());
		}
		GET_GL_ERROR();
 	}
#endif /* LIB_GL */

	// Lighting
	if(forced || target.lightingParametersChanged(actual)) {
#ifdef LIB_GL
 		if(RenderingContext::getCompabilityMode()) {
			if(actual.getLightingParameters().isEnabled()) {
				glEnable(GL_LIGHTING);
			} else {
				glDisable(GL_LIGHTING);
			}
 		}
#endif /* LIB_GL */
		target.setLightingParameters(actual.getLightingParameters());
	}
	GET_GL_ERROR();

#ifdef LIB_GL
	// polygonMode
	if(forced || target.polygonModeParametersChanged(actual) ) {
		glPolygonMode(GL_FRONT_AND_BACK, PolygonModeParameters::modeToGL(actual.getPolygonModeParameters().getMode()));
		target.setPolygonModeParameters(actual.getPolygonModeParameters());
	}
	GET_GL_ERROR();
#endif /* LIB_GL */

	// PolygonOffset
	if(forced || target.polygonOffsetParametersChanged(actual)) {
		if(actual.getPolygonOffsetParameters().isEnabled()) {
			glEnable(GL_POLYGON_OFFSET_FILL);
#ifdef LIB_GL
			glEnable(GL_POLYGON_OFFSET_LINE);
			glEnable(GL_POLYGON_OFFSET_POINT);
#endif /* LIB_GL */
			glPolygonOffset(actual.getPolygonOffsetParameters().getFactor(), actual.getPolygonOffsetParameters().getUnits());
		} else {
			glDisable(GL_POLYGON_OFFSET_FILL);
#ifdef LIB_GL
			glDisable(GL_POLYGON_OFFSET_LINE);
			glDisable(GL_POLYGON_OFFSET_POINT);
#endif /* LIB_GL */
		}
		target.setPolygonOffsetParameters(actual.getPolygonOffsetParameters());
	}
	GET_GL_ERROR();

		// PrimitiveRestart
	#ifdef LIB_GL
		if(forced || target.primitiveRestartParametersChanged(actual)) {
			if(actual.getPrimitiveRestartParameters().isEnabled()) {
				glEnable(GL_PRIMITIVE_RESTART);
				glPrimitiveRestartIndex(actual.getPrimitiveRestartParameters().getIndex());
			} else {
				glDisable(GL_PRIMITIVE_RESTART);
			}
			target.setPrimitiveRestartParameters(actual.getPrimitiveRestartParameters());
		}
		GET_GL_ERROR();
	#endif /* LIB_GL */

	// Textures
	if(forced || target.texturesChanged(actual)) {
		for(uint_fast8_t unit = 0; unit < MAX_TEXTURES; ++unit) {
			const auto & texture = actual.getTexture(unit);
			const auto & oldTexture = target.getTexture(unit);
			if(forced || texture != oldTexture) {
				glActiveTexture(GL_TEXTURE0 + static_cast<GLenum>(unit));
				if( texture ) {
					glBindTexture(texture->getGLTextureType(), texture->getGLId());
#if defined(LIB_GL)
					BufferObject* buffer = texture->getBufferObject();
					if(buffer)
						glTexBuffer( GL_TEXTURE_BUFFER, texture->getFormat().pixelFormat.glInternalFormat, buffer->getGLId() );
#endif
				} else if( oldTexture ) {
					glBindTexture(oldTexture->getGLTextureType(), 0);
				} else {
					glBindTexture(GL_TEXTURE_2D, 0);
				}
			}
		}
		target.updateTextures(actual);
	}
	GET_GL_ERROR();
}
Esempio n. 2
0
void Kinc_G4_Internal_SetPipeline(kinc_g4_pipeline_t *pipeline) {
#ifndef KORE_OPENGL_ES
	Kinc_Internal_ProgramUsesTessellation = pipeline->tessellation_control_shader != NULL;
#endif
	glUseProgram(pipeline->impl.programId);
	glCheckErrors();
	for (int index = 0; index < pipeline->impl.textureCount; ++index) {
		glUniform1i(pipeline->impl.textureValues[index], index);
		glCheckErrors();
	}

	if (pipeline->stencil_mode == KINC_G4_COMPARE_ALWAYS && pipeline->stencil_both_pass == KINC_G4_STENCIL_KEEP &&
	    pipeline->stencil_depth_fail == KINC_G4_STENCIL_KEEP && pipeline->stencil_fail == KINC_G4_STENCIL_KEEP) {
		glDisable(GL_STENCIL_TEST);
	}
	else {
		glEnable(GL_STENCIL_TEST);
		int stencilFunc = Kinc_G4_Internal_StencilFunc(pipeline->stencil_mode);
		glStencilMask(pipeline->stencil_write_mask);
		glStencilOp(convertStencilAction(pipeline->stencil_fail), convertStencilAction(pipeline->stencil_depth_fail), convertStencilAction(pipeline->stencil_both_pass));
		glStencilFunc(stencilFunc, pipeline->stencil_reference_value, pipeline->stencil_read_mask);
	}

	#ifdef KORE_OPENGL_ES
	glColorMask(pipeline->colorWriteMaskRed[0], pipeline->colorWriteMaskGreen[0], pipeline->colorWriteMaskBlue[0], pipeline->colorWriteMaskAlpha[0]);
	#else
	for (int i = 0; i < 8; ++i) glColorMaski(i, pipeline->color_write_mask_red[i], pipeline->color_write_mask_green[i], pipeline->color_write_mask_blue[i], pipeline->color_write_mask_alpha[i]);
	#endif

	if (Kinc_Internal_SupportsConservativeRaster) {
		if (pipeline->conservative_rasterization) {
			glEnable(0x9346); // GL_CONSERVATIVE_RASTERIZATION_NV
		}
		else {
			glDisable(0x9346);
		}
	}

	glCheckErrors();

	/*switch (state) {
	case Normalize:
	device->SetRenderState(D3DRS_NORMALIZENORMALS, on ? TRUE : FALSE);
	break;
	case BackfaceCulling:
	if (on) device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
	else device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	break;
	case FogState:
	device->SetRenderState(D3DRS_FOGENABLE, on ? TRUE : FALSE);
	break;
	case ScissorTestState:
	device->SetRenderState(D3DRS_SCISSORTESTENABLE, on ? TRUE : FALSE);
	break;
	case AlphaTestState:
	device->SetRenderState(D3DRS_ALPHATESTENABLE, on ? TRUE : FALSE);
	device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
	break;
	default:
	throw Exception();
	}*/

	if (pipeline->depth_write) {
		glDepthMask(GL_TRUE);
	}
	else {
		glDepthMask(GL_FALSE);
	}

	if (pipeline->depth_mode != KINC_G4_COMPARE_ALWAYS) {
		glEnable(GL_DEPTH_TEST);
	}
	else {
		glDisable(GL_DEPTH_TEST);
	}

	GLenum func = GL_ALWAYS;
	switch (pipeline->depth_mode) {
	default:
	case KINC_G4_COMPARE_ALWAYS:
		func = GL_ALWAYS;
		break;
	case KINC_G4_COMPARE_NEVER:
		func = GL_NEVER;
		break;
	case KINC_G4_COMPARE_EQUAL:
		func = GL_EQUAL;
		break;
	case KINC_G4_COMPARE_NOT_EQUAL:
		func = GL_NOTEQUAL;
		break;
	case KINC_G4_COMPARE_LESS:
		func = GL_LESS;
		break;
	case KINC_G4_COMPARE_LESS_EQUAL:
		func = GL_LEQUAL;
		break;
	case KINC_G4_COMPARE_GREATER:
		func = GL_GREATER;
		break;
	case KINC_G4_COMPARE_GREATER_EQUAL:
		func = GL_GEQUAL;
		break;
	}
	glDepthFunc(func);
	glCheckErrors();

	switch (pipeline->cull_mode) {
	case KINC_G4_CULL_CLOCKWISE:
		glEnable(GL_CULL_FACE);
		glCullFace(GL_BACK);
		glCheckErrors();
		break;
	case KINC_G4_CULL_COUNTER_CLOCKWISE:
		glEnable(GL_CULL_FACE);
		glCullFace(GL_FRONT);
		glCheckErrors();
		break;
	case KINC_G4_CULL_NOTHING:
		glDisable(GL_CULL_FACE);
		glCheckErrors();
		break;
	default:
		break;
	}

	/*switch (state) {
	case DepthTestCompare:
	switch (v) {
	// TODO: Cmp-Konstanten systemabhaengig abgleichen
	default:
	case ZCmp_Always      : v = D3DCMP_ALWAYS; break;
	case ZCmp_Never       : v = D3DCMP_NEVER; break;
	case ZCmp_Equal       : v = D3DCMP_EQUAL; break;
	case ZCmp_NotEqual    : v = D3DCMP_NOTEQUAL; break;
	case ZCmp_Less        : v = D3DCMP_LESS; break;
	case ZCmp_LessEqual   : v = D3DCMP_LESSEQUAL; break;
	case ZCmp_Greater     : v = D3DCMP_GREATER; break;
	case ZCmp_GreaterEqual: v = D3DCMP_GREATEREQUAL; break;
	}
	device->SetRenderState(D3DRS_ZFUNC, v);
	break;
	case FogTypeState:
	switch (v) {
	case LinearFog:
	device->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
	}
	break;
	case AlphaReferenceState:
	device->SetRenderState(D3DRS_ALPHAREF, (DWORD)v);
	break;
	default:
	throw Exception();
	}*/

	if (pipeline->blend_source != KINC_G4_BLEND_ONE || pipeline->blend_destination != KINC_G4_BLEND_ZERO || pipeline->alpha_blend_source != KINC_G4_BLEND_ONE ||
	    pipeline->alpha_blend_destination != KINC_G4_BLEND_ZERO) {
		glEnable(GL_BLEND);
	}
	else {
		glDisable(GL_BLEND);
	}

	// glBlendFunc(convert(pipeline->blendSource), convert(pipeline->blendDestination));
	glBlendFuncSeparate(convertBlendingOperation(pipeline->blend_source), convertBlendingOperation(pipeline->blend_destination),
	                    convertBlendingOperation(pipeline->alpha_blend_source), convertBlendingOperation(pipeline->alpha_blend_destination));
}