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(); }
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)); }