HQ_FORCE_INLINE void HQStateManagerGL::ActiveDepthStencilState(const HQSharedPtr<HQDepthStencilStateGL> &state) { if (state->depthEnable != this->dsState->depthEnable) { if (state->depthEnable) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); } if (state->depthFunc != this->dsState->depthFunc) glDepthFunc(state->depthFunc); if (state->depthWriteEnable != this->dsState->depthWriteEnable) glDepthMask(state->depthWriteEnable); if (state->stencilEnable != this->dsState->stencilEnable) { if (state->stencilEnable) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST); } if (state->stencilEnable) { if (state->stwoSide)//two sided stencil { glStencilFuncSeparate(GL_FRONT , state->sfront.stencilFunc , state->sref, state->sreadMask); glStencilFuncSeparate(GL_BACK , state->sback.stencilFunc , state->sref, state->sreadMask); glStencilOpSeparate(GL_FRONT , state->sfront.stencilFailOp, state->sfront.depthFailOp, state->sfront.passOp); glStencilOpSeparate(GL_BACK , state->sback.stencilFailOp, state->sback.depthFailOp, state->sback.passOp); }//if (state->stwoSide) else { glStencilFunc(state->sfront.stencilFunc , state->sref, state->sreadMask); glStencilOp(state->sfront.stencilFailOp, state->sfront.depthFailOp, state->sfront.passOp); } }//if (state->stencilEnable) if (state->swriteMask != this->dsState->swriteMask) glStencilMask(state->swriteMask); }
void StateSystem::StencilState::applyGL() const { glStencilFuncSeparate(GL_FRONT, funcs[FACE_FRONT].func, funcs[FACE_FRONT].refvalue, funcs[FACE_FRONT].mask); glStencilFuncSeparate(GL_BACK, funcs[FACE_BACK ].func, funcs[FACE_BACK ].refvalue, funcs[FACE_BACK ].mask); glStencilOpSeparate(GL_FRONT, ops[FACE_FRONT].fail, ops[FACE_FRONT].zfail, ops[FACE_FRONT].zpass); glStencilOpSeparate(GL_BACK, ops[FACE_BACK ].fail, ops[FACE_BACK ].zfail, ops[FACE_BACK ].zpass); }
void apply_Rstate_stencil( const Rstate_stencil* stencil ) { if( stencil->enabled ) { glEnable( GL_STENCIL_TEST ); glStencilFuncSeparate( GL_FRONT, stencil->frontFunc, stencil->frontRef, stencil->frontMask ); glStencilFuncSeparate( GL_BACK, stencil->backFunc, stencil->backRef, stencil->backMask ); glStencilOpSeparate( GL_FRONT, stencil->frontFail, stencil->frontZpass, stencil->frontZfail ); glStencilOpSeparate( GL_BACK, stencil->backFail, stencil->backZpass, stencil->backZfail ); } else glDisable( GL_STENCIL_TEST ); }
//----------------------------------------------------------------------------- void CPUTRenderStateBlockOGL::SetRenderStates( CPUTRenderParameters &renderParams ) { // // Set Depth and Stencil render states // mStateDesc.DepthStencilDesc.DepthEnable ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST); mStateDesc.DepthStencilDesc.StencilEnable ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST); GL_CHECK("Set Depth Stencil States"); GL_CHECK(glDepthMask(mStateDesc.DepthStencilDesc.DepthWriteMask)); GL_CHECK(glDepthFunc(mStateDesc.DepthStencilDesc.DepthFunc)); GL_CHECK(glStencilMaskSeparate(GL_FRONT_AND_BACK, mStateDesc.DepthStencilDesc.StencilWriteMask)); GL_CHECK(glStencilOpSeparate(GL_FRONT, mStateDesc.DepthStencilDesc.FrontFaceStencilFailOp, mStateDesc.DepthStencilDesc.FrontFaceStencilDepthFailOp, mStateDesc.DepthStencilDesc.FrontFaceStencilPassOp)); GL_CHECK(glStencilOpSeparate(GL_BACK, mStateDesc.DepthStencilDesc.BackFaceStencilFailOp, mStateDesc.DepthStencilDesc.BackFaceStencilDepthFailOp, mStateDesc.DepthStencilDesc.BackFaceStencilPassOp)); GL_CHECK(glStencilFuncSeparate(GL_FRONT, mStateDesc.DepthStencilDesc.FrontFaceStencilFunc, mStateDesc.DepthStencilDesc.FrontFaceStencilFuncRef, mStateDesc.DepthStencilDesc.FrontFaceStencilFuncMask)); GL_CHECK(glStencilFuncSeparate(GL_BACK, mStateDesc.DepthStencilDesc.BackFaceStencilFunc, mStateDesc.DepthStencilDesc.BackFaceStencilFuncRef, mStateDesc.DepthStencilDesc.BackFaceStencilFuncMask)); // // Set Rasterization states // #ifndef CPUT_FOR_OGLES GL_CHECK(glPolygonMode(GL_FRONT_AND_BACK, mStateDesc.RasterizerDesc.FillMode)); #endif GL_CHECK(glCullFace(mStateDesc.RasterizerDesc.CullMode)); GL_CHECK(glFrontFace(mStateDesc.RasterizerDesc.FrontCounterClockwise)); //GL_CHECK(glPolygonOffset()); // used for depth bias mStateDesc.RasterizerDesc.CullingEnabled ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE); mStateDesc.RasterizerDesc.ScissorEnable ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST); // is glScissor needed here as well? #ifndef CPUT_FOR_OGLES mStateDesc.RasterizerDesc.DepthClipEnable ? glDisable(GL_DEPTH_CLAMP) : glEnable(GL_DEPTH_CLAMP); mStateDesc.RasterizerDesc.MultisampleEnable ? glEnable(GL_MULTISAMPLE) : glDisable(GL_MULTISAMPLE); // is glSampleCoverage() needed here as well? mStateDesc.RasterizerDesc.AntialiasedLineEnable ? glEnable(GL_LINE_SMOOTH) : glDisable(GL_LINE_SMOOTH); //NOTE: Could not find the rendertarget being set to SRGB anywhere else; this might not be the best place GL_CHECK(glEnable(GL_FRAMEBUFFER_SRGB)); #endif GL_CHECK("Set Rasterization States"); //glDisable(GL_CULL_FACE); // // Set Blend states // mStateDesc.RenderTargetBlendDesc.BlendEnable ? glEnable(GL_BLEND): glDisable(GL_BLEND); GL_CHECK(glBlendFuncSeparate(mStateDesc.RenderTargetBlendDesc.SrcBlend,mStateDesc.RenderTargetBlendDesc.DestBlend,mStateDesc.RenderTargetBlendDesc.SrcBlendAlpha,mStateDesc.RenderTargetBlendDesc.DestBlendAlpha)); GL_CHECK(glBlendEquationSeparate(mStateDesc.RenderTargetBlendDesc.BlendOp,mStateDesc.RenderTargetBlendDesc.BlendOpAlpha)); GL_CHECK("Set Blend States"); } // CPUTRenderStateBlockOGL::SetRenderState()
/*************************************************************//** * * @brief ステンシルの関数の設定を行う * @param 表面の関数 * @param 裏面の関数 * @param 比較値 * @param マスク * @return なし * ****************************************************************/ void C_OpenGlManager::SetStencilFunction(StencilEnum frontFaceFunction, StencilEnum backFaceFunction, int32_t comparisonValue, uint32_t mask) { glStencilFuncSeparate(frontFaceFunction, backFaceFunction, comparisonValue, mask); }
void CG3DGraphicsGL::ApplyStencil(CG3DStencilSet* set) { GLenum face; switch (set->m_Face) { case CG3DStencilSet::FRONT: face = GL_FRONT; break; case CG3DStencilSet::BACK: face = GL_BACK; break; case CG3DStencilSet::FRONT_AND_BACK: face = GL_FRONT_AND_BACK; break; } glStencilMaskSeparate(face, set->m_Mask); switch (set->m_Func) { case CG3DStencilSet::ALWAYS: glDisable(GL_STENCIL_TEST); break; case CG3DStencilSet::NEVER: glEnable(GL_STENCIL_TEST); glStencilFuncSeparate(face, GL_NEVER, set->m_FuncRef, set->m_FuncMask); break; case CG3DStencilSet::LESS: glEnable(GL_STENCIL_TEST); glStencilFuncSeparate(face, GL_LESS, set->m_FuncRef, set->m_FuncMask); break; case CG3DStencilSet::LEQUAL: glEnable(GL_STENCIL_TEST); glStencilFuncSeparate(face, GL_LEQUAL, set->m_FuncRef, set->m_FuncMask); break; case CG3DStencilSet::EQUAL: glEnable(GL_STENCIL_TEST); glStencilFuncSeparate(face, GL_EQUAL, set->m_FuncRef, set->m_FuncMask); break; case CG3DStencilSet::GREATER: glEnable(GL_STENCIL_TEST); glStencilFuncSeparate(face, GL_GREATER, set->m_FuncRef, set->m_FuncMask); break; case CG3DStencilSet::GEQUAL: glEnable(GL_STENCIL_TEST); glStencilFuncSeparate(face, GL_GEQUAL, set->m_FuncRef, set->m_FuncMask); break; case CG3DStencilSet::NOTEQUAL: glEnable(GL_STENCIL_TEST); glStencilFuncSeparate(face, GL_NOTEQUAL, set->m_FuncRef, set->m_FuncMask); break; } glStencilOpSeparate(face, GetOp(set->m_StencilFail), GetOp(set->m_DepthFail), GetOp(set->m_DepthPass)); if (set->m_OtherFace != NULL) ApplyStencil(set->m_OtherFace); }
void device_stencilfunction(device_t device, enum gs_stencil_side side, enum gs_depth_test test) { GLenum gl_side = convert_gs_stencil_side(side); GLenum gl_test = convert_gs_depth_test(test); glStencilFuncSeparate(gl_side, gl_test, 0, 0xFFFFFFFF); if (!gl_success("glStencilFuncSeparate")) blog(LOG_ERROR, "device_stencilfunction (GL) failed"); }
void ShadowVolume::draw(Vector4<float> lightPos, Vector3<float> cameraPos, const Vector3<float> *ownerVertex) { Vector3<double> cameraPosD; cameraPosD.x = (double)cameraPos.x; cameraPosD.y = (double)cameraPos.y; cameraPosD.z = (double)cameraPos.z; calcShadowVolume(lightPos, ownerVertex, shadowPos, 8); glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); //ここからステンシルシャドウの処理 glEnable(GL_STENCIL_TEST); glDepthMask(GL_FALSE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glStencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, 0, ~0); glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);//表面は「+1」 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);//裏面は「-1」 //シャドーボリュームを描画する glBegin(GL_TRIANGLE_FAN); glVertex3f(lightPos.x, lightPos.y, lightPos.z); for(int loop = 0; loop < 3;++loop) { glVertex3f(shadowPos[loop].x, shadowPos[loop].y, shadowPos[loop].z); } glVertex3f(shadowPos[0].x, shadowPos[0].y, shadowPos[0].z); glEnd(); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_TRUE); glStencilFunc(GL_NOTEQUAL, 0, ~0); //ステンシル値が0じゃない部分が影 glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); ////ステンシルバッファを可視化 glPushMatrix(); //Tracball::getInstance().applyOfShadow(); glDepthMask(GL_FALSE); glEnable(GL_BLEND); //ブレンド有効化 glColor4f(0.0f, 0.0f, 0.0f, 0.5f); drawScreen(30, cameraPosD, 1); //スクリーン描画(fovy,znearをわたす) glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glDisable(GL_BLEND); //ブレンド無効化 glDepthMask(GL_TRUE); glPopMatrix(); glDisable(GL_STENCIL_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); }
inline void VL_glStencilFuncSeparate( GLenum face, GLenum func, GLint ref, GLuint mask) { if (glStencilFuncSeparate) glStencilFuncSeparate( face, func, ref, mask ); else VL_UNSUPPORTED_FUNC(); // NOT SUPPORTED // see also http://www.opengl.org/registry/specs/ATI/separate_stencil.txt /*else if ( Has_GL_ATI_separate_stencil ) glStencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask ) */ }
void GLState::glsStencilFuncSeparate(const GLenum face, const GLenum func, const GLint ref, const GLuint mask) { switch (face) { case GL_FRONT_AND_BACK: /* if (setGLenumGLenum(GL_STENCIL_FUNC, func) || // Front setGLenumGLenum(GL_STENCIL_REF, ref) || // Front setGLenumGLenum(GL_STENCIL_VALUE_MASK, mask) || // Front setGLenumGLenum(GL_STENCIL_BACK_FUNC, func) || // back setGLenumGLenum(GL_STENCIL_BACK_REF, ref) || // back setGLenumGLenum(GL_STENCIL_BACK_VALUE_MASK, mask)) { // back glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); ERROR_CHECK; } break; */ glsStencilFuncSeparate(GL_FRONT, func, ref, mask); glsStencilFuncSeparate(GL_BACK, func, ref, mask); case GL_FRONT: if (setGLenum(GL_STENCIL_FUNC, &func, GLTYPE_ENUM_SIZE, GLTYPE_ENUM) || setGLenum(GL_STENCIL_REF, &ref, GLTYPE_ENUM_SIZE, GLTYPE_ENUM) || setGLenum(GL_STENCIL_VALUE_MASK, &mask, GLTYPE_ENUM_SIZE, GLTYPE_ENUM)) { glStencilFuncSeparate(GL_FRONT, func, ref, mask); ERROR_CHECK; } break; case GL_BACK: if (setGLenum(GL_STENCIL_BACK_FUNC, &func, GLTYPE_ENUM_SIZE, GLTYPE_ENUM) || setGLenum(GL_STENCIL_BACK_REF, &ref, GLTYPE_ENUM_SIZE, GLTYPE_ENUM) || setGLenum(GL_STENCIL_BACK_VALUE_MASK, &mask, GLTYPE_ENUM_SIZE, GLTYPE_ENUM)) { glStencilFuncSeparate(GL_BACK, func, ref, mask); ERROR_CHECK; } break; default: throw std::runtime_error("GLState::glsStencilFuncSeparate() - face" " invalid"); } }
static void RB_SetStencil( GLenum side, stencil_t *stencil ) { GLenum sfailOp, zfailOp, zpassOp; if( !side ) { glDisable( GL_STENCIL_TEST ); return; } if( !stencil->flags ) { return; } glEnable( GL_STENCIL_TEST ); switch( stencil->flags & STF_MASK ) { case STF_ALWAYS: glStencilFuncSeparate( side, GL_ALWAYS, stencil->ref, stencil->mask ); break; case STF_NEVER: glStencilFuncSeparate( side, GL_NEVER, stencil->ref, stencil->mask ); break; case STF_LESS: glStencilFuncSeparate( side, GL_LESS, stencil->ref, stencil->mask ); break; case STF_LEQUAL: glStencilFuncSeparate( side, GL_LEQUAL, stencil->ref, stencil->mask ); break; case STF_GREATER: glStencilFuncSeparate( side, GL_GREATER, stencil->ref, stencil->mask ); break; case STF_GEQUAL: glStencilFuncSeparate( side, GL_GEQUAL, stencil->ref, stencil->mask ); break; case STF_EQUAL: glStencilFuncSeparate( side, GL_EQUAL, stencil->ref, stencil->mask ); break; case STF_NEQUAL: glStencilFuncSeparate( side, GL_NOTEQUAL, stencil->ref, stencil->mask ); break; } sfailOp = RB_StencilOp( stencil->flags >> STS_SFAIL ); zfailOp = RB_StencilOp( stencil->flags >> STS_ZFAIL ); zpassOp = RB_StencilOp( stencil->flags >> STS_ZPASS ); glStencilOpSeparate( side, sfailOp, zfailOp, zpassOp ); glStencilMaskSeparate( side, (GLuint) stencil->writeMask ); }
void OpenGLDepthStencilState::apply() { if (changed_desc) { changed_desc = false; if (glStencilFuncSeparate) { CompareFunction front; int front_ref; int front_mask; CompareFunction back; int back_ref; int back_mask; unsigned char front_facing_mask, back_facing_mask; StencilOp fail_front, pass_depth_fail_front, pass_depth_pass_front; StencilOp fail_back, pass_depth_fail_back, pass_depth_pass_back; desc.get_stencil_compare_front(front, front_ref, front_mask); desc.get_stencil_compare_back(back, back_ref, back_mask); desc.get_stencil_write_mask(front_facing_mask, back_facing_mask); desc.get_stencil_op_front(fail_front, pass_depth_fail_front, pass_depth_pass_front); desc.get_stencil_op_back(fail_back, pass_depth_fail_back, pass_depth_pass_back); desc.is_stencil_test_enabled() ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST); glStencilFuncSeparate(GL_FRONT, OpenGL::to_enum(front), front_ref, front_mask); glStencilFuncSeparate(GL_BACK, OpenGL::to_enum(back), back_ref, back_mask); glStencilMaskSeparate(GL_FRONT, front_facing_mask); glStencilMaskSeparate(GL_BACK, back_facing_mask); glStencilOpSeparate(GL_FRONT, OpenGL::to_enum(fail_front), OpenGL::to_enum(pass_depth_fail_front), OpenGL::to_enum(pass_depth_pass_front)); glStencilOpSeparate(GL_BACK, OpenGL::to_enum(fail_back), OpenGL::to_enum(pass_depth_fail_back), OpenGL::to_enum(pass_depth_pass_back)); } desc.is_depth_test_enabled() ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST); glDepthMask(desc.is_depth_write_enabled() ? 1 : 0); glDepthFunc(OpenGL::to_enum(desc.get_depth_compare_function())); } }
static int StencilFunc(lua_State *L) { GLenum face; GLenum func = checkstencilfunc(L, 1); GLint ref = luaL_checkinteger(L, 2); GLuint mask = luaL_checkinteger(L, 3); if(lua_isstring(L, 4)) { face = checkface(L, 4); glStencilFuncSeparate(face, func, ref, mask); } else glStencilFunc(func, ref, mask); CheckError(L); return 0; }
void OpenGLES2Context::setStencilActions(TriangleFace triangleFace, CompareMode compareMode, StencilAction actionOnBothPass, StencilAction actionOnDepthFail, StencilAction actionOnDepthPassStencilFail) { if (compareMode != m_curStencilFunc) { m_curStencilFunc = compareMode; glStencilFuncSeparate(m_triangleFaces[triangleFace], m_compareFuncs[compareMode], m_curStencilRef, m_curStencilMask); } if (actionOnBothPass != m_curStencilBothPassOp || actionOnDepthFail != m_curStencilDepthFailOp || actionOnDepthPassStencilFail != m_curStencilDepthPassStencilFailOp) { m_curStencilBothPassOp = actionOnBothPass; m_curStencilDepthFailOp = actionOnDepthFail; m_curStencilDepthPassStencilFailOp = actionOnDepthPassStencilFail; glStencilOpSeparate(m_triangleFaces[triangleFace], m_stencilActions[actionOnDepthFail], m_stencilActions[actionOnDepthPassStencilFail], m_stencilActions[actionOnBothPass]); } }
void StencilScopeOGL::applySettings(const StencilSettings& settings) { if(settings.enabled()) { glEnable(GL_STENCIL_TEST); glStencilOpSeparate(convert_face(settings.face()), convert_stencil_op(settings.sfail()), convert_stencil_op(settings.dpfail()), convert_stencil_op(settings.dppass())); glStencilFuncSeparate(convert_face(settings.face()), convert_func(settings.func()), settings.ref(), settings.ref_mask()); glStencilMaskSeparate(convert_face(settings.face()), settings.mask()); } else { glDisable(GL_STENCIL_TEST); glStencilMask(0); } }
void GLStateManager::setStencilFuncSeparate(gl::GLenum face, gl::GLenum func, int ref, unsigned int mask) { auto index = face == GL_FRONT ? 0 : 1; if ( m_glStencilFunc[index] == func && m_glStencilRef[index] == ref && m_glStencilReadMask[index] == mask ) { return; } m_glStencilFunc[index] = func; m_glStencilRef[index] = ref; m_glStencilReadMask[index] = mask; glStencilFuncSeparate(face, m_glStencilFunc[index], m_glStencilRef[index], m_glStencilReadMask[index]); }
enum piglit_result piglit_display(void) { GLboolean pass = GL_TRUE; GLint max_stencil; GLint stencil_bits; unsigned i; float expected[4] = {0.5, 0.5, 0.5, 0.5}; int w = piglit_width / (6 * 2 + 1); int h = w; int start_y = (piglit_height - h) / 2; piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glGetIntegerv(GL_STENCIL_BITS, & stencil_bits); max_stencil = (1U << stencil_bits) - 1; printf("Stencil bits = %u, maximum stencil value = 0x%08x\n", stencil_bits, max_stencil); glClearStencil(1); glClearColor(0.2, 0.2, 0.8, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); /* This is the "reference" square. */ glDisable(GL_STENCIL_TEST); glColor3f(0.5, 0.5, 0.5); piglit_draw_rect(w * 1, start_y, w, h); glEnable(GL_STENCIL_TEST); /* Draw the first two squares using incr for the affected face */ /* 2nd square */ if (use20syntax) { glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0, ~0); glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, ~0); glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR); glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR); } else { glStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0); glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR); glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR); } glColor3f(0.9, 0.9, 0.9); for (i = 0 ; i < (max_stencil + 5) ; i++) { /* this should be front facing */ piglit_draw_rect(w * 3, start_y, w, h); } /* stencil vals should be equal to max_stencil */ glStencilFunc(GL_EQUAL, max_stencil, ~0); glColor3f(0.5, 0.5, 0.5); piglit_draw_rect(w * 3, start_y, w, h); /* 3rd square */ if (use20syntax) { glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0, ~0); glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, ~0); glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR); glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR); } else { glStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0); glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR); glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR); } glColor3f(0.9, 0.9, 0.9); for (i = 0 ; i < (max_stencil + 5) ; i++) { /* this should be back facing */ piglit_draw_rect(w * 5, start_y + h, w, -h); } /* stencil vals should be equal to max_stencil */ glStencilFunc(GL_EQUAL, max_stencil, ~0); glColor3f(0.5, 0.5, 0.5); piglit_draw_rect(w * 5, start_y, w, h); /* 4th square */ if (use20syntax) { glStencilFuncSeparate(GL_FRONT, GL_NEVER, 0, ~0); glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, ~0); glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR); glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR); } else { glStencilFuncSeparateATI(GL_NEVER, GL_ALWAYS, 0, ~0); glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR); glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR); } glColor3f(0.9, 0.9, 0.9); for (i = 0 ; i < (max_stencil + 5) ; i++) { /* this should be back facing */ piglit_draw_rect(w * 7, start_y + h, w, -h); /* this should be front facing */ piglit_draw_rect(w * 7, start_y, w, h); } /* stencil vals should be equal to max_stencil */ glStencilFunc(GL_EQUAL, max_stencil, ~0); glColor3f(0.5, 0.5, 0.5); piglit_draw_rect(w * 7, start_y, w, h); /* 5th square */ if (use20syntax) { glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0, ~0); glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, ~0); glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR); glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR); } else { glStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0); glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR); glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR); } glColor3f(0.9, 0.9, 0.9); for (i = 0 ; i < (max_stencil + 5) ; i++) { /* this should be back facing */ piglit_draw_rect(w * 9, start_y + h, w, -h); /* this should be front facing */ piglit_draw_rect(w * 9, start_y, w, h); } glStencilFunc(GL_EQUAL, 1, ~0); glColor3f(0.5, 0.5, 0.5); piglit_draw_rect(w * 9, start_y, w, h); /* 6th square */ if (piglit_is_extension_supported("GL_EXT_stencil_wrap")) { if (use20syntax) { glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0, ~0); glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, ~0); glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP); glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP); } else { glStencilFuncSeparateATI(GL_ALWAYS, GL_ALWAYS, 0, ~0); glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP); glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP); } glColor3f(0.9, 0.9, 0.9); for (i = 0 ; i < (max_stencil + 5) ; i++) { /* this should be back facing */ piglit_draw_rect(w * 11, start_y + h, w, -h); /* this should be front facing */ piglit_draw_rect(w * 11, start_y, w, h); } glStencilFunc(GL_EQUAL, 260 - 255, ~0); glColor3f(0.5, 0.5, 0.5); piglit_draw_rect(w * 11, start_y, w, h); } pass = piglit_probe_pixel_rgb(w * 1.5, piglit_height / 2, expected); pass = piglit_probe_pixel_rgb(w * 3.5, piglit_height / 2, expected); pass = piglit_probe_pixel_rgb(w * 5.5, piglit_height / 2, expected); pass = piglit_probe_pixel_rgb(w * 7.5, piglit_height / 2, expected); pass = piglit_probe_pixel_rgb(w * 9.5, piglit_height / 2, expected); pass = piglit_probe_pixel_rgb(w * 11.5, piglit_height / 2, expected); glutSwapBuffers(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL20_nglStencilFuncSeparate(JNIEnv *env, jclass clazz, jint face, jint func, jint ref, jint mask, jlong function_pointer) { glStencilFuncSeparatePROC glStencilFuncSeparate = (glStencilFuncSeparatePROC)((intptr_t)function_pointer); glStencilFuncSeparate(face, func, ref, mask); }
void GLGSRender::begin() { rsx::thread::begin(); init_buffers(); std::chrono::time_point<std::chrono::system_clock> then = std::chrono::system_clock::now(); bool color_mask_b = rsx::method_registers.color_mask_b(); bool color_mask_g = rsx::method_registers.color_mask_g(); bool color_mask_r = rsx::method_registers.color_mask_r(); bool color_mask_a = rsx::method_registers.color_mask_a(); __glcheck glColorMask(color_mask_r, color_mask_g, color_mask_b, color_mask_a); __glcheck glDepthMask(rsx::method_registers.depth_write_enabled()); __glcheck glStencilMask(rsx::method_registers.stencil_mask()); if (__glcheck enable(rsx::method_registers.depth_test_enabled(), GL_DEPTH_TEST)) { __glcheck glDepthFunc(comparison_op(rsx::method_registers.depth_func())); __glcheck glDepthMask(rsx::method_registers.depth_write_enabled()); } if (glDepthBoundsEXT && (__glcheck enable(rsx::method_registers.depth_bounds_test_enabled(), GL_DEPTH_BOUNDS_TEST_EXT))) { __glcheck glDepthBoundsEXT(rsx::method_registers.depth_bounds_min(), rsx::method_registers.depth_bounds_max()); } __glcheck glDepthRange(rsx::method_registers.clip_min(), rsx::method_registers.clip_max()); __glcheck enable(rsx::method_registers.dither_enabled(), GL_DITHER); if (__glcheck enable(rsx::method_registers.blend_enabled(), GL_BLEND)) { __glcheck glBlendFuncSeparate(blend_factor(rsx::method_registers.blend_func_sfactor_rgb()), blend_factor(rsx::method_registers.blend_func_dfactor_rgb()), blend_factor(rsx::method_registers.blend_func_sfactor_a()), blend_factor(rsx::method_registers.blend_func_dfactor_a())); if (rsx::method_registers.surface_color() == rsx::surface_color_format::w16z16y16x16) //TODO: check another color formats { u16 blend_color_r = rsx::method_registers.blend_color_16b_r(); u16 blend_color_g = rsx::method_registers.blend_color_16b_g(); u16 blend_color_b = rsx::method_registers.blend_color_16b_b(); u16 blend_color_a = rsx::method_registers.blend_color_16b_a(); __glcheck glBlendColor(blend_color_r / 65535.f, blend_color_g / 65535.f, blend_color_b / 65535.f, blend_color_a / 65535.f); } else { u8 blend_color_r = rsx::method_registers.blend_color_8b_r(); u8 blend_color_g = rsx::method_registers.blend_color_8b_g(); u8 blend_color_b = rsx::method_registers.blend_color_8b_b(); u8 blend_color_a = rsx::method_registers.blend_color_8b_a(); __glcheck glBlendColor(blend_color_r / 255.f, blend_color_g / 255.f, blend_color_b / 255.f, blend_color_a / 255.f); } __glcheck glBlendEquationSeparate(blend_equation(rsx::method_registers.blend_equation_rgb()), blend_equation(rsx::method_registers.blend_equation_a())); } if (__glcheck enable(rsx::method_registers.stencil_test_enabled(), GL_STENCIL_TEST)) { __glcheck glStencilFunc(comparison_op(rsx::method_registers.stencil_func()), rsx::method_registers.stencil_func_ref(), rsx::method_registers.stencil_func_mask()); __glcheck glStencilOp(stencil_op(rsx::method_registers.stencil_op_fail()), stencil_op(rsx::method_registers.stencil_op_zfail()), stencil_op(rsx::method_registers.stencil_op_zpass())); if (rsx::method_registers.two_sided_stencil_test_enabled()) { __glcheck glStencilMaskSeparate(GL_BACK, rsx::method_registers.back_stencil_mask()); __glcheck glStencilFuncSeparate(GL_BACK, comparison_op(rsx::method_registers.back_stencil_func()), rsx::method_registers.back_stencil_func_ref(), rsx::method_registers.back_stencil_func_mask()); __glcheck glStencilOpSeparate(GL_BACK, stencil_op(rsx::method_registers.back_stencil_op_fail()), stencil_op(rsx::method_registers.back_stencil_op_zfail()), stencil_op(rsx::method_registers.back_stencil_op_zpass())); } } __glcheck enable(rsx::method_registers.blend_enabled_surface_1(), GL_BLEND, 1); __glcheck enable(rsx::method_registers.blend_enabled_surface_2(), GL_BLEND, 2); __glcheck enable(rsx::method_registers.blend_enabled_surface_3(), GL_BLEND, 3); if (__glcheck enable(rsx::method_registers.logic_op_enabled(), GL_COLOR_LOGIC_OP)) { __glcheck glLogicOp(logic_op(rsx::method_registers.logic_operation())); } __glcheck glLineWidth(rsx::method_registers.line_width()); __glcheck enable(rsx::method_registers.line_smooth_enabled(), GL_LINE_SMOOTH); //TODO //NV4097_SET_ANISO_SPREAD __glcheck enable(rsx::method_registers.poly_offset_point_enabled(), GL_POLYGON_OFFSET_POINT); __glcheck enable(rsx::method_registers.poly_offset_line_enabled(), GL_POLYGON_OFFSET_LINE); __glcheck enable(rsx::method_registers.poly_offset_fill_enabled(), GL_POLYGON_OFFSET_FILL); __glcheck glPolygonOffset(rsx::method_registers.poly_offset_scale(), rsx::method_registers.poly_offset_bias()); //NV4097_SET_SPECULAR_ENABLE //NV4097_SET_TWO_SIDE_LIGHT_EN //NV4097_SET_FLAT_SHADE_OP //NV4097_SET_EDGE_FLAG auto set_clip_plane_control = [&](int index, rsx::user_clip_plane_op control) { int value = 0; int location; if (m_program->uniforms.has_location("uc_m" + std::to_string(index), &location)) { switch (control) { default: LOG_ERROR(RSX, "bad clip plane control (0x%x)", (u8)control); case rsx::user_clip_plane_op::disable: value = 0; break; case rsx::user_clip_plane_op::greater_or_equal: value = 1; break; case rsx::user_clip_plane_op::less_than: value = -1; break; } __glcheck m_program->uniforms[location] = value; } __glcheck enable(value, GL_CLIP_DISTANCE0 + index); }; load_program(); set_clip_plane_control(0, rsx::method_registers.clip_plane_0_enabled()); set_clip_plane_control(1, rsx::method_registers.clip_plane_1_enabled()); set_clip_plane_control(2, rsx::method_registers.clip_plane_2_enabled()); set_clip_plane_control(3, rsx::method_registers.clip_plane_3_enabled()); set_clip_plane_control(4, rsx::method_registers.clip_plane_4_enabled()); set_clip_plane_control(5, rsx::method_registers.clip_plane_5_enabled()); if (__glcheck enable(rsx::method_registers.cull_face_enabled(), GL_CULL_FACE)) { __glcheck glCullFace(cull_face(rsx::method_registers.cull_face_mode())); } __glcheck glFrontFace(front_face(rsx::method_registers.front_face_mode())); __glcheck enable(rsx::method_registers.poly_smooth_enabled(), GL_POLYGON_SMOOTH); //NV4097_SET_COLOR_KEY_COLOR //NV4097_SET_SHADER_CONTROL //NV4097_SET_ZMIN_MAX_CONTROL //NV4097_SET_ANTI_ALIASING_CONTROL //NV4097_SET_CLIP_ID_TEST_ENABLE std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now(); m_begin_time += (u32)std::chrono::duration_cast<std::chrono::microseconds>(now - then).count(); m_draw_calls++; }
void stencil_func_separate(stencil_face_direction_t face, stencil_function_t func, gl::int_t ref, gl::uint_t mask) { glStencilFuncSeparate(static_cast<GLenum>(face), static_cast<GLenum>(func), ref, mask); }
void GLGSRender::begin() { rsx::thread::begin(); if (skip_frame) return; if (conditional_render_enabled && conditional_render_test_failed) return; init_buffers(); if (!framebuffer_status_valid) return; std::chrono::time_point<steady_clock> then = steady_clock::now(); bool color_mask_b = rsx::method_registers.color_mask_b(); bool color_mask_g = rsx::method_registers.color_mask_g(); bool color_mask_r = rsx::method_registers.color_mask_r(); bool color_mask_a = rsx::method_registers.color_mask_a(); gl_state.color_mask(color_mask_r, color_mask_g, color_mask_b, color_mask_a); gl_state.depth_mask(rsx::method_registers.depth_write_enabled()); gl_state.stencil_mask(rsx::method_registers.stencil_mask()); if (gl_state.enable(rsx::method_registers.depth_test_enabled(), GL_DEPTH_TEST)) { gl_state.depth_func(comparison_op(rsx::method_registers.depth_func())); } if (glDepthBoundsEXT && (gl_state.enable(rsx::method_registers.depth_bounds_test_enabled(), GL_DEPTH_BOUNDS_TEST_EXT))) { gl_state.depth_bounds(rsx::method_registers.depth_bounds_min(), rsx::method_registers.depth_bounds_max()); } gl_state.depth_range(rsx::method_registers.clip_min(), rsx::method_registers.clip_max()); gl_state.enable(rsx::method_registers.dither_enabled(), GL_DITHER); if (gl_state.enable(rsx::method_registers.blend_enabled(), GL_BLEND)) { glBlendFuncSeparate(blend_factor(rsx::method_registers.blend_func_sfactor_rgb()), blend_factor(rsx::method_registers.blend_func_dfactor_rgb()), blend_factor(rsx::method_registers.blend_func_sfactor_a()), blend_factor(rsx::method_registers.blend_func_dfactor_a())); auto blend_colors = rsx::get_constant_blend_colors(); glBlendColor(blend_colors[0], blend_colors[1], blend_colors[2], blend_colors[3]); glBlendEquationSeparate(blend_equation(rsx::method_registers.blend_equation_rgb()), blend_equation(rsx::method_registers.blend_equation_a())); } if (gl_state.enable(rsx::method_registers.stencil_test_enabled(), GL_STENCIL_TEST)) { glStencilFunc(comparison_op(rsx::method_registers.stencil_func()), rsx::method_registers.stencil_func_ref(), rsx::method_registers.stencil_func_mask()); glStencilOp(stencil_op(rsx::method_registers.stencil_op_fail()), stencil_op(rsx::method_registers.stencil_op_zfail()), stencil_op(rsx::method_registers.stencil_op_zpass())); if (rsx::method_registers.two_sided_stencil_test_enabled()) { glStencilMaskSeparate(GL_BACK, rsx::method_registers.back_stencil_mask()); glStencilFuncSeparate(GL_BACK, comparison_op(rsx::method_registers.back_stencil_func()), rsx::method_registers.back_stencil_func_ref(), rsx::method_registers.back_stencil_func_mask()); glStencilOpSeparate(GL_BACK, stencil_op(rsx::method_registers.back_stencil_op_fail()), stencil_op(rsx::method_registers.back_stencil_op_zfail()), stencil_op(rsx::method_registers.back_stencil_op_zpass())); } } gl_state.enablei(rsx::method_registers.blend_enabled_surface_1(), GL_BLEND, 1); gl_state.enablei(rsx::method_registers.blend_enabled_surface_2(), GL_BLEND, 2); gl_state.enablei(rsx::method_registers.blend_enabled_surface_3(), GL_BLEND, 3); if (gl_state.enable(rsx::method_registers.logic_op_enabled(), GL_COLOR_LOGIC_OP)) { gl_state.logic_op(logic_op(rsx::method_registers.logic_operation())); } gl_state.line_width(rsx::method_registers.line_width()); gl_state.enable(rsx::method_registers.line_smooth_enabled(), GL_LINE_SMOOTH); gl_state.enable(rsx::method_registers.poly_offset_point_enabled(), GL_POLYGON_OFFSET_POINT); gl_state.enable(rsx::method_registers.poly_offset_line_enabled(), GL_POLYGON_OFFSET_LINE); gl_state.enable(rsx::method_registers.poly_offset_fill_enabled(), GL_POLYGON_OFFSET_FILL); gl_state.polygon_offset(rsx::method_registers.poly_offset_scale(), rsx::method_registers.poly_offset_bias()); if (gl_state.enable(rsx::method_registers.cull_face_enabled(), GL_CULL_FACE)) { gl_state.cull_face(cull_face(rsx::method_registers.cull_face_mode())); } gl_state.front_face(front_face(rsx::method_registers.front_face_mode())); //TODO //NV4097_SET_ANISO_SPREAD //NV4097_SET_SPECULAR_ENABLE //NV4097_SET_TWO_SIDE_LIGHT_EN //NV4097_SET_FLAT_SHADE_OP //NV4097_SET_EDGE_FLAG //NV4097_SET_COLOR_KEY_COLOR //NV4097_SET_SHADER_CONTROL //NV4097_SET_ZMIN_MAX_CONTROL //NV4097_SET_ANTI_ALIASING_CONTROL //NV4097_SET_CLIP_ID_TEST_ENABLE std::chrono::time_point<steady_clock> now = steady_clock::now(); m_begin_time += (u32)std::chrono::duration_cast<std::chrono::microseconds>(now - then).count(); }
void GraphicsContext3D::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask) { makeContextCurrent(); glStencilFuncSeparate(face, func, ref, mask); }
void GLGSRender::ExecCMD() { if(!LoadProgram()) { ConLog.Error("LoadProgram failed."); Emu.Pause(); return; } if(!m_fbo.IsCreated() || m_width != last_width || m_height != last_height || last_depth_format != m_surface_depth_format) { ConLog.Warning("New FBO (%dx%d)", m_width, m_height); last_width = m_width; last_height = m_height; last_depth_format = m_surface_depth_format; m_fbo.Create(); checkForGlError("m_fbo.Create"); m_fbo.Bind(); m_rbo.Create(4 + 1); checkForGlError("m_rbo.Create"); for(int i=0; i<4; ++i) { m_rbo.Bind(i); m_rbo.Storage(GL_RGBA, m_width, m_height); checkForGlError("m_rbo.Storage(GL_RGBA)"); } m_rbo.Bind(4); switch(m_surface_depth_format) { case 1: m_rbo.Storage(GL_DEPTH_COMPONENT16, m_width, m_height); checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)"); break; case 2: m_rbo.Storage(GL_DEPTH24_STENCIL8, m_width, m_height); checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)"); break; default: ConLog.Error("Bad depth format! (%d)", m_surface_depth_format); assert(0); break; } for(int i=0; i<4; ++i) { m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0 + i, m_rbo.GetId(i)); checkForGlError(wxString::Format("m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT%d)", i)); } m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); if(m_surface_depth_format == 2) { m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT, m_rbo.GetId(4)); checkForGlError("m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT)"); } } if(!m_set_surface_clip_horizontal) { m_surface_clip_x = 0; m_surface_clip_w = m_width; } if(!m_set_surface_clip_vertical) { m_surface_clip_y = 0; m_surface_clip_h = m_height; } m_fbo.Bind(); if(Ini.GSDumpDepthBuffer.GetValue()) WriteDepthBuffer(); static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; switch(m_surface_colour_target) { case 0x0: break; case 0x1: glDrawBuffer(draw_buffers[0]); break; case 0x2: glDrawBuffer(draw_buffers[1]); break; case 0x13: glDrawBuffers(2, draw_buffers); break; case 0x17: glDrawBuffers(3, draw_buffers); break; case 0x1f: glDrawBuffers(4, draw_buffers); break; default: ConLog.Error("Bad surface colour target: %d", m_surface_colour_target); break; } if(m_set_color_mask) { glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); checkForGlError("glColorMask"); } if(m_set_viewport_horizontal && m_set_viewport_vertical) { glViewport(m_viewport_x, m_height-m_viewport_y-m_viewport_h, m_viewport_w, m_viewport_h); checkForGlError("glViewport"); } if(m_set_scissor_horizontal && m_set_scissor_vertical) { glScissor(m_scissor_x, m_height-m_scissor_y-m_scissor_h, m_scissor_w, m_scissor_h); checkForGlError("glScissor"); } if(m_clear_surface_mask) { GLbitfield f = 0; if (m_clear_surface_mask & 0x1) { glClearDepth(m_clear_surface_z / (float)0xffffff); f |= GL_DEPTH_BUFFER_BIT; } if (m_clear_surface_mask & 0x2) { glClearStencil(m_clear_surface_s); f |= GL_STENCIL_BUFFER_BIT; } if (m_clear_surface_mask & 0xF0) { glClearColor( m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); f |= GL_COLOR_BUFFER_BIT; } glClear(f); } if(m_set_front_polygon_mode) { glPolygonMode(GL_FRONT, m_front_polygon_mode); checkForGlError("glPolygonMode"); } Enable(m_depth_test_enable, GL_DEPTH_TEST); Enable(m_set_alpha_test, GL_ALPHA_TEST); Enable(m_set_depth_bounds_test, GL_DEPTH_CLAMP); Enable(m_set_blend, GL_BLEND); Enable(m_set_logic_op, GL_LOGIC_OP); Enable(m_set_cull_face_enable, GL_CULL_FACE); Enable(m_set_dither, GL_DITHER); Enable(m_set_stencil_test, GL_STENCIL_TEST); Enable(m_set_line_smooth, GL_LINE_SMOOTH); Enable(m_set_poly_smooth, GL_POLYGON_SMOOTH); if(m_set_clip_plane) { Enable(m_clip_plane_0, GL_CLIP_PLANE0); Enable(m_clip_plane_1, GL_CLIP_PLANE1); Enable(m_clip_plane_2, GL_CLIP_PLANE2); Enable(m_clip_plane_3, GL_CLIP_PLANE3); Enable(m_clip_plane_4, GL_CLIP_PLANE4); Enable(m_clip_plane_5, GL_CLIP_PLANE5); checkForGlError("m_set_clip_plane"); } checkForGlError("glEnable"); if(m_set_two_sided_stencil_test_enable) { if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) { glStencilOpSeparate(GL_FRONT, m_stencil_fail, m_stencil_zfail, m_stencil_zpass); checkForGlError("glStencilOpSeparate"); } if(m_set_stencil_mask) { glStencilMaskSeparate(GL_FRONT, m_stencil_mask); checkForGlError("glStencilMaskSeparate"); } if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) { glStencilFuncSeparate(GL_FRONT, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); checkForGlError("glStencilFuncSeparate"); } if(m_set_back_stencil_fail && m_set_back_stencil_zfail && m_set_back_stencil_zpass) { glStencilOpSeparate(GL_BACK, m_back_stencil_fail, m_back_stencil_zfail, m_back_stencil_zpass); checkForGlError("glStencilOpSeparate(GL_BACK)"); } if(m_set_back_stencil_mask) { glStencilMaskSeparate(GL_BACK, m_back_stencil_mask); checkForGlError("glStencilMaskSeparate(GL_BACK)"); } if(m_set_back_stencil_func && m_set_back_stencil_func_ref && m_set_back_stencil_func_mask) { glStencilFuncSeparate(GL_BACK, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask); checkForGlError("glStencilFuncSeparate(GL_BACK)"); } } else { if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) { glStencilOp(m_stencil_fail, m_stencil_zfail, m_stencil_zpass); checkForGlError("glStencilOp"); } if(m_set_stencil_mask) { glStencilMask(m_stencil_mask); checkForGlError("glStencilMask"); } if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) { glStencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); checkForGlError("glStencilFunc"); } } if(m_set_shade_mode) { glShadeModel(m_shade_mode); checkForGlError("glShadeModel"); } if(m_set_depth_mask) { glDepthMask(m_depth_mask); checkForGlError("glDepthMask"); } if(m_set_depth_func) { glDepthFunc(m_depth_func); checkForGlError("glDepthFunc"); } if(m_set_clip) { glDepthRangef(m_clip_min, m_clip_max); checkForGlError("glDepthRangef"); } if(m_set_line_width) { glLineWidth(m_line_width / 255.f); checkForGlError("glLineWidth"); } if(m_set_blend_equation) { glBlendEquationSeparate(m_blend_equation_rgb, m_blend_equation_alpha); checkForGlError("glBlendEquationSeparate"); } if(m_set_blend_sfactor && m_set_blend_dfactor) { glBlendFuncSeparate(m_blend_sfactor_rgb, m_blend_dfactor_rgb, m_blend_sfactor_alpha, m_blend_dfactor_alpha); checkForGlError("glBlendFuncSeparate"); } if(m_set_blend_color) { glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); checkForGlError("glBlendColor"); } if(m_set_cull_face) { glCullFace(m_cull_face); checkForGlError("glCullFace"); } if(m_set_alpha_func && m_set_alpha_ref) { glAlphaFunc(m_alpha_func, m_alpha_ref); checkForGlError("glAlphaFunc"); } if(m_set_fog_mode) { glFogi(GL_FOG_MODE, m_fog_mode); checkForGlError("glFogi(GL_FOG_MODE)"); } if(m_set_fog_params) { glFogf(GL_FOG_START, m_fog_param0); checkForGlError("glFogf(GL_FOG_START)"); glFogf(GL_FOG_END, m_fog_param1); checkForGlError("glFogf(GL_FOG_END)"); } if(m_indexed_array.m_count && m_draw_array_count) { ConLog.Warning("m_indexed_array.m_count && draw_array_count"); } for(u32 i=0; i<m_textures_count; ++i) { if(!m_textures[i].IsEnabled()) continue; glActiveTexture(GL_TEXTURE0 + i); checkForGlError("glActiveTexture"); m_gl_textures[i].Create(); m_gl_textures[i].Bind(); checkForGlError(wxString::Format("m_gl_textures[%d].Bind", i)); m_program.SetTex(i); m_gl_textures[i].Init(m_textures[i]); checkForGlError(wxString::Format("m_gl_textures[%d].Init", i)); } m_vao.Bind(); if(m_indexed_array.m_count) { LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1); } EnableVertexData(m_indexed_array.m_count ? true : false); InitVertexData(); InitFragmentData(); if(m_indexed_array.m_count) { switch(m_indexed_array.m_type) { case 0: glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_INT, nullptr); checkForGlError("glDrawElements #4"); break; case 1: glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_SHORT, nullptr); checkForGlError("glDrawElements #2"); break; default: ConLog.Error("Bad indexed array type (%d)", m_indexed_array.m_type); break; } DisableVertexData(); m_indexed_array.Reset(); } if(m_draw_array_count) { glDrawArrays(m_draw_mode - 1, 0, m_draw_array_count); checkForGlError("glDrawArrays"); DisableVertexData(); m_draw_array_count = 0; } if(Ini.GSDumpColorBuffers.GetValue()) WriteBuffers(); }
void GLGSRender::ExecCMD() { //return; if(!LoadProgram()) { ConLog.Error("LoadProgram failed."); Emu.Pause(); return; } if(!m_fbo.IsCreated() || RSXThread::m_width != last_width || RSXThread::m_height != last_height || last_depth_format != m_surface_depth_format) { ConLog.Warning("New FBO (%dx%d)", RSXThread::m_width, RSXThread::m_height); last_width = RSXThread::m_width; last_height = RSXThread::m_height; last_depth_format = m_surface_depth_format; m_fbo.Create(); checkForGlError("m_fbo.Create"); m_fbo.Bind(); m_rbo.Create(4 + 1); checkForGlError("m_rbo.Create"); for(int i=0; i<4; ++i) { m_rbo.Bind(i); m_rbo.Storage(GL_RGBA, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_RGBA)"); } m_rbo.Bind(4); switch(m_surface_depth_format) { // case 0 found in BLJM60410-[Suzukaze no Melt - Days in the Sanctuary] // [E : RSXThread]: Bad depth format! (0) // [E : RSXThread]: glEnable: opengl error 0x0506 // [E : RSXThread]: glDrawArrays: opengl error 0x0506 case 0: m_rbo.Storage(GL_DEPTH_COMPONENT, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT)"); break; case CELL_GCM_SURFACE_Z16: m_rbo.Storage(GL_DEPTH_COMPONENT16, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)"); break; case CELL_GCM_SURFACE_Z24S8: m_rbo.Storage(GL_DEPTH24_STENCIL8, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH24_STENCIL8)"); break; default: ConLog.Error("Bad depth format! (%d)", m_surface_depth_format); assert(0); break; } for(int i=0; i<4; ++i) { m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0 + i, m_rbo.GetId(i)); checkForGlError(fmt::Format("m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT%d)", i)); } m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT, m_rbo.GetId(4)); checkForGlError("m_fbo.Renderbuffer(GL_DEPTH_ATTACHMENT)"); if(m_surface_depth_format == 2) { m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT, m_rbo.GetId(4)); checkForGlError("m_fbo.Renderbuffer(GL_STENCIL_ATTACHMENT)"); } } if(!m_set_surface_clip_horizontal) { m_surface_clip_x = 0; m_surface_clip_w = RSXThread::m_width; } if(!m_set_surface_clip_vertical) { m_surface_clip_y = 0; m_surface_clip_h = RSXThread::m_height; } m_fbo.Bind(); if(Ini.GSDumpDepthBuffer.GetValue()) WriteDepthBuffer(); static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; switch(m_surface_colour_target) { case CELL_GCM_SURFACE_TARGET_NONE: break; case CELL_GCM_SURFACE_TARGET_0: glDrawBuffer(draw_buffers[0]); break; case CELL_GCM_SURFACE_TARGET_1: glDrawBuffer(draw_buffers[1]); break; case CELL_GCM_SURFACE_TARGET_MRT1: glDrawBuffers(2, draw_buffers); break; case CELL_GCM_SURFACE_TARGET_MRT2: glDrawBuffers(3, draw_buffers); break; case CELL_GCM_SURFACE_TARGET_MRT3: glDrawBuffers(4, draw_buffers); break; default: ConLog.Error("Bad surface colour target: %d", m_surface_colour_target); break; } if(m_set_color_mask) { glColorMask(m_color_mask_r, m_color_mask_g, m_color_mask_b, m_color_mask_a); checkForGlError("glColorMask"); } if(m_set_viewport_horizontal && m_set_viewport_vertical) { //glViewport(m_viewport_x, m_viewport_y, m_viewport_w, m_viewport_h); //checkForGlError("glViewport"); } if (m_set_scissor_horizontal && m_set_scissor_vertical) { glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); checkForGlError("glScissor"); } if(m_clear_surface_mask) { GLbitfield f = 0; if (m_clear_surface_mask & 0x1) { glClearDepth(m_clear_surface_z / (float)0xffffff); f |= GL_DEPTH_BUFFER_BIT; } if (m_clear_surface_mask & 0x2) { glClearStencil(m_clear_surface_s); f |= GL_STENCIL_BUFFER_BIT; } if (m_clear_surface_mask & 0xF0) { glClearColor( m_clear_surface_color_r / 255.0f, m_clear_surface_color_g / 255.0f, m_clear_surface_color_b / 255.0f, m_clear_surface_color_a / 255.0f); f |= GL_COLOR_BUFFER_BIT; } glClear(f); } Enable(m_set_depth_test, GL_DEPTH_TEST); Enable(m_set_alpha_test, GL_ALPHA_TEST); Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT); Enable(m_set_blend, GL_BLEND); Enable(m_set_logic_op, GL_LOGIC_OP); Enable(m_set_cull_face, GL_CULL_FACE); Enable(m_set_dither, GL_DITHER); Enable(m_set_stencil_test, GL_STENCIL_TEST); Enable(m_set_line_smooth, GL_LINE_SMOOTH); Enable(m_set_poly_smooth, GL_POLYGON_SMOOTH); Enable(m_set_point_sprite_control, GL_POINT_SPRITE); Enable(m_set_specular, GL_LIGHTING); Enable(m_set_poly_offset_fill, GL_POLYGON_OFFSET_FILL); Enable(m_set_poly_offset_line, GL_POLYGON_OFFSET_LINE); Enable(m_set_poly_offset_point, GL_POLYGON_OFFSET_POINT); Enable(m_set_restart_index, GL_PRIMITIVE_RESTART); Enable(m_set_line_stipple, GL_LINE_STIPPLE); if(m_set_clip_plane) { Enable(m_clip_plane_0, GL_CLIP_PLANE0); Enable(m_clip_plane_1, GL_CLIP_PLANE1); Enable(m_clip_plane_2, GL_CLIP_PLANE2); Enable(m_clip_plane_3, GL_CLIP_PLANE3); Enable(m_clip_plane_4, GL_CLIP_PLANE4); Enable(m_clip_plane_5, GL_CLIP_PLANE5); checkForGlError("m_set_clip_plane"); } checkForGlError("glEnable"); if (m_set_front_polygon_mode) { glPolygonMode(GL_FRONT, m_front_polygon_mode); checkForGlError("glPolygonMode(Front)"); } if (m_set_back_polygon_mode) { glPolygonMode(GL_BACK, m_back_polygon_mode); checkForGlError("glPolygonMode(Back)"); } if (m_set_point_size) { glPointSize(m_point_size); checkForGlError("glPointSize"); } if (m_set_poly_offset_mode) { glPolygonOffset(m_poly_offset_scale_factor, m_poly_offset_bias); checkForGlError("glPolygonOffset"); } if (m_set_logic_op) { glLogicOp(m_logic_op); checkForGlError("glLogicOp"); } if(m_set_two_sided_stencil_test_enable) { if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) { glStencilOpSeparate(GL_FRONT, m_stencil_fail, m_stencil_zfail, m_stencil_zpass); checkForGlError("glStencilOpSeparate"); } if(m_set_stencil_mask) { glStencilMaskSeparate(GL_FRONT, m_stencil_mask); checkForGlError("glStencilMaskSeparate"); } if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) { glStencilFuncSeparate(GL_FRONT, m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); checkForGlError("glStencilFuncSeparate"); } if(m_set_back_stencil_fail && m_set_back_stencil_zfail && m_set_back_stencil_zpass) { glStencilOpSeparate(GL_BACK, m_back_stencil_fail, m_back_stencil_zfail, m_back_stencil_zpass); checkForGlError("glStencilOpSeparate(GL_BACK)"); } if(m_set_back_stencil_mask) { glStencilMaskSeparate(GL_BACK, m_back_stencil_mask); checkForGlError("glStencilMaskSeparate(GL_BACK)"); } if(m_set_back_stencil_func && m_set_back_stencil_func_ref && m_set_back_stencil_func_mask) { glStencilFuncSeparate(GL_BACK, m_back_stencil_func, m_back_stencil_func_ref, m_back_stencil_func_mask); checkForGlError("glStencilFuncSeparate(GL_BACK)"); } } else { if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) { glStencilOp(m_stencil_fail, m_stencil_zfail, m_stencil_zpass); checkForGlError("glStencilOp"); } if(m_set_stencil_mask) { glStencilMask(m_stencil_mask); checkForGlError("glStencilMask"); } if(m_set_stencil_func && m_set_stencil_func_ref && m_set_stencil_func_mask) { glStencilFunc(m_stencil_func, m_stencil_func_ref, m_stencil_func_mask); checkForGlError("glStencilFunc"); } } if(m_set_shade_mode) { glShadeModel(m_shade_mode); checkForGlError("glShadeModel"); } if(m_set_depth_mask) { glDepthMask(m_depth_mask); checkForGlError("glDepthMask"); } if(m_set_depth_func) { //ConLog.Warning("glDepthFunc(0x%x)", m_depth_func); glDepthFunc(m_depth_func); checkForGlError("glDepthFunc"); } if(m_set_depth_bounds) { //ConLog.Warning("glDepthBounds(%f, %f)", m_depth_bounds_min, m_depth_bounds_max); glDepthBoundsEXT(m_depth_bounds_min, m_depth_bounds_max); checkForGlError("glDepthBounds"); } if(m_set_clip) { //ConLog.Warning("glDepthRangef(%f, %f)", m_clip_min, m_clip_max); glDepthRangef(m_clip_min, m_clip_max); checkForGlError("glDepthRangef"); } if(m_set_line_width) { glLineWidth(m_line_width); checkForGlError("glLineWidth"); } if (m_set_line_stipple) { glLineStipple(m_line_stipple_factor, m_line_stipple_pattern); checkForGlError("glLineStipple"); } if(m_set_blend_equation) { glBlendEquationSeparate(m_blend_equation_rgb, m_blend_equation_alpha); checkForGlError("glBlendEquationSeparate"); } if(m_set_blend_sfactor && m_set_blend_dfactor) { glBlendFuncSeparate(m_blend_sfactor_rgb, m_blend_dfactor_rgb, m_blend_sfactor_alpha, m_blend_dfactor_alpha); checkForGlError("glBlendFuncSeparate"); } if(m_set_blend_color) { glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); checkForGlError("glBlendColor"); } if(m_set_cull_face) { glCullFace(m_cull_face); checkForGlError("glCullFace"); } if (m_set_front_face) { glFrontFace(m_front_face); checkForGlError("glFrontFace"); } if(m_set_alpha_func && m_set_alpha_ref) { glAlphaFunc(m_alpha_func, m_alpha_ref); checkForGlError("glAlphaFunc"); } if(m_set_fog_mode) { glFogi(GL_FOG_MODE, m_fog_mode); checkForGlError("glFogi(GL_FOG_MODE)"); } if(m_set_fog_params) { glFogf(GL_FOG_START, m_fog_param0); checkForGlError("glFogf(GL_FOG_START)"); glFogf(GL_FOG_END, m_fog_param1); checkForGlError("glFogf(GL_FOG_END)"); } if(m_set_restart_index) { glPrimitiveRestartIndex(m_restart_index); checkForGlError("glPrimitiveRestartIndex"); } if(m_indexed_array.m_count && m_draw_array_count) { ConLog.Warning("m_indexed_array.m_count && draw_array_count"); } for(u32 i=0; i<m_textures_count; ++i) { if(!m_textures[i].IsEnabled()) continue; glActiveTexture(GL_TEXTURE0 + i); checkForGlError("glActiveTexture"); m_gl_textures[i].Create(); m_gl_textures[i].Bind(); checkForGlError(fmt::Format("m_gl_textures[%d].Bind", i)); m_program.SetTex(i); m_gl_textures[i].Init(m_textures[i]); checkForGlError(fmt::Format("m_gl_textures[%d].Init", i)); } m_vao.Bind(); if(m_indexed_array.m_count) { LoadVertexData(m_indexed_array.index_min, m_indexed_array.index_max - m_indexed_array.index_min + 1); } EnableVertexData(m_indexed_array.m_count ? true : false); InitVertexData(); InitFragmentData(); if(m_indexed_array.m_count) { switch(m_indexed_array.m_type) { case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_INT, nullptr); checkForGlError("glDrawElements #4"); break; case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: glDrawElements(m_draw_mode - 1, m_indexed_array.m_count, GL_UNSIGNED_SHORT, nullptr); checkForGlError("glDrawElements #2"); break; default: ConLog.Error("Bad indexed array type (%d)", m_indexed_array.m_type); break; } DisableVertexData(); m_indexed_array.Reset(); } if(m_draw_array_count) { //ConLog.Warning("glDrawArrays(%d,%d,%d)", m_draw_mode - 1, m_draw_array_first, m_draw_array_count); glDrawArrays(m_draw_mode - 1, 0, m_draw_array_count); checkForGlError("glDrawArrays"); DisableVertexData(); } if (Ini.GSDumpColorBuffers.GetValue()) { WriteColorBuffers(); } }
void OGLRenderState::apply(const RenderState& _stateCaptured) noexcept { const auto& blendState = this->getBlendState(); const auto& rasterState = this->getRasterState(); const auto& depthState = this->getDepthState(); const auto& stencilState = this->getStencilState(); auto& _blendState = _stateCaptured.getBlendState(); auto& _rasterState = _stateCaptured.getRasterState(); auto& _depthState = _stateCaptured.getDepthState(); auto& _stencilState = _stateCaptured.getStencilState(); if (blendState.blendEnable) { if (!_blendState.blendEnable) { #if _USE_RENDER_COMMAND BlendEnableCommand command; command.header = GL_BLEND_ENABLE_COMMAND; _renderCommands.write(&command, sizeof(command)); #else glEnable(GL_BLEND); #endif } if (blendState.blendSeparateEnable) { if (_blendState.blendSrc != blendState.blendSrc || _blendState.blendDest != blendState.blendDest || _blendState.blendAlphaSrc != blendState.blendAlphaSrc || _blendState.blendAlphaDest != blendState.blendAlphaDest) { GLenum sfactorRGB = OGLTypes::asBlendFactor(blendState.blendSrc); GLenum dfactorRGB = OGLTypes::asBlendFactor(blendState.blendDest); GLenum sfactorAlpha = OGLTypes::asBlendFactor(blendState.blendAlphaSrc); GLenum dfactorAlpha = OGLTypes::asBlendFactor(blendState.blendAlphaDest); glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); } if (_blendState.blendOp != blendState.blendOp || _blendState.blendAlphaOp != blendState.blendAlphaOp) { GLenum modeRGB = OGLTypes::asBlendOperation(blendState.blendOp); GLenum modeAlpha = OGLTypes::asBlendOperation(blendState.blendAlphaOp); glBlendEquationSeparate(modeRGB, modeAlpha); } } else { if (_blendState.blendSrc != blendState.blendSrc || _blendState.blendDest != blendState.blendDest) { GLenum sfactorRGB = OGLTypes::asBlendFactor(blendState.blendSrc); GLenum dfactorRGB = OGLTypes::asBlendFactor(blendState.blendDest); glBlendFunc(sfactorRGB, dfactorRGB); } if (_blendState.blendOp != blendState.blendOp) { GLenum modeRGB = OGLTypes::asBlendOperation(blendState.blendOp); glBlendEquation(modeRGB); } } } else { if (_blendState.blendEnable) { glDisable(GL_BLEND); } } if (_rasterState.cullMode != rasterState.cullMode) { if (rasterState.cullMode != GPU_CULL_NONE) { GLenum mode = OGLTypes::asCullMode(rasterState.cullMode); glEnable(GL_CULL_FACE); glCullFace(mode); } else { glDisable(GL_CULL_FACE); } } #if !defined(EGLAPI) if (_rasterState.fillMode != rasterState.fillMode) { GLenum mode = OGLTypes::asFillMode(rasterState.fillMode); glPolygonMode(GL_FRONT_AND_BACK, mode); } #endif if (_rasterState.scissorTestEnable != rasterState.scissorTestEnable) { if (rasterState.scissorTestEnable) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); } if (_rasterState.srgbEnable != rasterState.srgbEnable) { if (rasterState.srgbEnable) glEnable(GL_FRAMEBUFFER_SRGB); else glDisable(GL_FRAMEBUFFER_SRGB); } if (depthState.depthEnable) { if (!_depthState.depthEnable) { glEnable(GL_DEPTH_TEST); } if (_depthState.depthFunc != depthState.depthFunc) { GLenum func = OGLTypes::asCompareFunction(depthState.depthFunc); glDepthFunc(func); } } else { if (_depthState.depthEnable) { glDisable(GL_DEPTH_TEST); } } if (_depthState.depthWriteMask != depthState.depthWriteMask) { GLboolean enable = depthState.depthWriteMask ? GL_TRUE : GL_FALSE; glDepthMask(enable); } if (depthState.depthBiasEnable) { if (!_depthState.depthBiasEnable) { glEnable(GL_POLYGON_OFFSET_FILL); } if (_depthState.depthBias != depthState.depthBias || _depthState.depthSlopScaleBias != depthState.depthSlopScaleBias) { glPolygonOffset(depthState.depthSlopScaleBias, depthState.depthBias); } } else { if (_depthState.depthBiasEnable) { glDisable(GL_POLYGON_OFFSET_FILL); } } if (stencilState.stencilEnable) { if (!_stencilState.stencilEnable) { glEnable(GL_STENCIL_TEST); } if (stencilState.stencilTwoEnable) { if (_stencilState.stencilFunc != stencilState.stencilFunc || _stencilState.stencilRef != stencilState.stencilRef || _stencilState.stencilReadMask != stencilState.stencilReadMask) { GLenum frontfunc = OGLTypes::asCompareFunction(stencilState.stencilFunc); glStencilFuncSeparate(GL_FRONT, frontfunc, stencilState.stencilRef, stencilState.stencilReadMask); GLenum backfunc = OGLTypes::asCompareFunction(stencilState.stencilTwoFunc); glStencilFuncSeparate(GL_BACK, backfunc, stencilState.stencilRef, stencilState.stencilTwoReadMask); } if (_stencilState.stencilFail != _stencilState.stencilFail || _stencilState.stencilZFail != _stencilState.stencilZFail || _stencilState.stencilPass != _stencilState.stencilPass) { GLenum frontfail = OGLTypes::asStencilOperation(_stencilState.stencilFail); GLenum frontzfail = OGLTypes::asStencilOperation(_stencilState.stencilZFail); GLenum frontpass = OGLTypes::asStencilOperation(_stencilState.stencilPass); glStencilOpSeparate(GL_FRONT, frontfail, frontzfail, frontpass); GLenum backfail = OGLTypes::asStencilOperation(_stencilState.stencilTwoFail); GLenum backzfail = OGLTypes::asStencilOperation(_stencilState.stencilTwoZFail); GLenum backpass = OGLTypes::asStencilOperation(_stencilState.stencilTwoPass); glStencilOpSeparate(GL_BACK, backfail, backzfail, backpass); } if (_stencilState.stencilWriteMask != stencilState.stencilWriteMask || _stencilState.stencilTwoWriteMask != stencilState.stencilTwoWriteMask) { glStencilMaskSeparate(GL_FRONT, stencilState.stencilWriteMask); glStencilMaskSeparate(GL_BACK, stencilState.stencilTwoWriteMask); } } else { if (_stencilState.stencilFunc != stencilState.stencilFunc || _stencilState.stencilRef != stencilState.stencilRef || _stencilState.stencilReadMask != stencilState.stencilReadMask) { GLenum func = OGLTypes::asCompareFunction(stencilState.stencilFunc); glStencilFunc(func, stencilState.stencilRef, stencilState.stencilReadMask); } if (_stencilState.stencilFail != stencilState.stencilFail || _stencilState.stencilZFail != stencilState.stencilZFail || _stencilState.stencilPass != stencilState.stencilPass) { GLenum fail = OGLTypes::asStencilOperation(stencilState.stencilFail); GLenum zfail = OGLTypes::asStencilOperation(stencilState.stencilZFail); GLenum pass = OGLTypes::asStencilOperation(stencilState.stencilPass); glStencilOp(fail, zfail, pass); } if (_stencilState.stencilWriteMask != stencilState.stencilWriteMask) { glStencilMask(stencilState.stencilWriteMask); } } } else { if (_stencilState.stencilEnable) { glDisable(GL_STENCIL_TEST); } } }
GLboolean UtilResetState(void) { // Do we need to delete textures, shaders, and programs? #if 0 GLint i, val; int windowWidth = atoi(flagWidthValue.cstring); int windowHeight = atoi(flagHeightValue.cstring); glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, &val ); for( i = 0; i < val; ++i ) { glDisableVertexAttribArray( i ); glVertexAttribPointer( i , 4, GL_FLOAT, GL_FALSE, 0, NULL ); } glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); glViewport( 0, 0, windowWidth, windowHeight ); glDepthRangef( 0, 1 ); glLineWidth( 1.f ); glDisable( GL_CULL_FACE ); glCullFace( GL_BACK ); glFrontFace( GL_CCW ); glPolygonOffset( 0, 0 ); glDisable( GL_SAMPLE_ALPHA_TO_COVERAGE ); glDisable( GL_SAMPLE_COVERAGE ); glSampleCoverage( 1, GL_FALSE ); glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS, &val ); for ( i = 0; i < val; ++i ) { glActiveTexture( GL_TEXTURE0+i ); glBindTexture( GL_TEXTURE_2D, 0 ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); //glBindTexture( GL_TEXTURE_3D, 0 ); // Need to check to see if extension is supported //glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR ); //glTexParameteri( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); //glTexParameteri( GL_TEXTURE_3D, GL_WRAP_S, GL_REPEAT ); //glTexParameteri( GL_TEXTURE_3D, GL_WRAP_T, GL_REPEAT ); glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ); glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR ); glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT ); } glActiveTexture( GL_TEXTURE0 ); glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); glDepthMask( GL_TRUE ); glStencilMaskSeparate( GL_FRONT_AND_BACK, 0xffffffff ); glClearColor( 0, 0, 0, 0 ); glClearDepthf( 1 ); glClearStencil( 0 ); glDisable( GL_SCISSOR_TEST ); glScissor( 0, 0, windowWidth, windowHeight ); glDisable( GL_STENCIL_TEST ); glStencilFuncSeparate( GL_FRONT_AND_BACK, GL_ALWAYS, 0, 0xffffffff ); glStencilOpSeparate( GL_FRONT_AND_BACK, GL_KEEP, GL_KEEP, GL_KEEP ); glDisable( GL_DEPTH_TEST ); glDepthFunc( GL_LESS ); glDisable( GL_BLEND ); glBlendFuncSeparate( GL_ONE, GL_ZERO, GL_ONE, GL_ZERO ); glBlendEquationSeparate( GL_FUNC_ADD, GL_FUNC_ADD ); glBlendColor( 0, 0, 0, 0 ); glEnable( GL_DITHER ); glPixelStorei( GL_UNPACK_ALIGNMENT, 4 ); glPixelStorei( GL_PACK_ALIGNMENT, 4 ); glUseProgram(0); glGetError(); #endif return GL_TRUE; }
uintptr_t processFn(struct fnargs* args, char* parg) { uintptr_t ret = 0; switch (args->fn) { case glfnUNDEFINED: abort(); // bad glfn break; case glfnActiveTexture: glActiveTexture((GLenum)args->a0); break; case glfnAttachShader: glAttachShader((GLint)args->a0, (GLint)args->a1); break; case glfnBindAttribLocation: glBindAttribLocation((GLint)args->a0, (GLint)args->a1, (GLchar*)args->a2); break; case glfnBindBuffer: glBindBuffer((GLenum)args->a0, (GLuint)args->a1); break; case glfnBindFramebuffer: glBindFramebuffer((GLenum)args->a0, (GLint)args->a1); break; case glfnBindRenderbuffer: glBindRenderbuffer((GLenum)args->a0, (GLint)args->a1); break; case glfnBindTexture: glBindTexture((GLenum)args->a0, (GLint)args->a1); break; case glfnBlendColor: glBlendColor(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnBlendEquation: glBlendEquation((GLenum)args->a0); break; case glfnBlendEquationSeparate: glBlendEquationSeparate((GLenum)args->a0, (GLenum)args->a1); break; case glfnBlendFunc: glBlendFunc((GLenum)args->a0, (GLenum)args->a1); break; case glfnBlendFuncSeparate: glBlendFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3); break; case glfnBufferData: glBufferData((GLenum)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg, (GLenum)args->a2); break; case glfnBufferSubData: glBufferSubData((GLenum)args->a0, (GLint)args->a1, (GLsizeiptr)args->a2, (GLvoid*)parg); break; case glfnCheckFramebufferStatus: ret = glCheckFramebufferStatus((GLenum)args->a0); break; case glfnClear: glClear((GLenum)args->a0); break; case glfnClearColor: glClearColor(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnClearDepthf: glClearDepthf(*(GLfloat*)&args->a0); break; case glfnClearStencil: glClearStencil((GLint)args->a0); break; case glfnColorMask: glColorMask((GLboolean)args->a0, (GLboolean)args->a1, (GLboolean)args->a2, (GLboolean)args->a3); break; case glfnCompileShader: glCompileShader((GLint)args->a0); break; case glfnCompressedTexImage2D: glCompressedTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLsizeiptr)args->a6, (GLvoid*)parg); break; case glfnCompressedTexSubImage2D: glCompressedTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLenum)args->a6, (GLsizeiptr)args->a7, (GLvoid*)parg); break; case glfnCopyTexImage2D: glCopyTexImage2D((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7); break; case glfnCopyTexSubImage2D: glCopyTexSubImage2D((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4, (GLint)args->a5, (GLint)args->a6, (GLint)args->a7); break; case glfnCreateProgram: ret = glCreateProgram(); break; case glfnCreateShader: ret = glCreateShader((GLenum)args->a0); break; case glfnCullFace: glCullFace((GLenum)args->a0); break; case glfnDeleteBuffer: glDeleteBuffers(1, (const GLuint*)(&args->a0)); break; case glfnDeleteFramebuffer: glDeleteFramebuffers(1, (const GLuint*)(&args->a0)); break; case glfnDeleteProgram: glDeleteProgram((GLint)args->a0); break; case glfnDeleteRenderbuffer: glDeleteRenderbuffers(1, (const GLuint*)(&args->a0)); break; case glfnDeleteShader: glDeleteShader((GLint)args->a0); break; case glfnDeleteTexture: glDeleteTextures(1, (const GLuint*)(&args->a0)); break; case glfnDepthFunc: glDepthFunc((GLenum)args->a0); break; case glfnDepthMask: glDepthMask((GLboolean)args->a0); break; case glfnDepthRangef: glDepthRangef(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1); break; case glfnDetachShader: glDetachShader((GLint)args->a0, (GLint)args->a1); break; case glfnDisable: glDisable((GLenum)args->a0); break; case glfnDisableVertexAttribArray: glDisableVertexAttribArray((GLint)args->a0); break; case glfnDrawArrays: glDrawArrays((GLenum)args->a0, (GLint)args->a1, (GLint)args->a2); break; case glfnDrawElements: glDrawElements((GLenum)args->a0, (GLint)args->a1, (GLenum)args->a2, (void*)args->a3); break; case glfnEnable: glEnable((GLenum)args->a0); break; case glfnEnableVertexAttribArray: glEnableVertexAttribArray((GLint)args->a0); break; case glfnFinish: glFinish(); break; case glfnFlush: glFlush(); break; case glfnFramebufferRenderbuffer: glFramebufferRenderbuffer((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint)args->a3); break; case glfnFramebufferTexture2D: glFramebufferTexture2D((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint)args->a3, (GLint)args->a4); break; case glfnFrontFace: glFrontFace((GLenum)args->a0); break; case glfnGenBuffer: glGenBuffers(1, (GLuint*)&ret); break; case glfnGenFramebuffer: glGenFramebuffers(1, (GLuint*)&ret); break; case glfnGenRenderbuffer: glGenRenderbuffers(1, (GLuint*)&ret); break; case glfnGenTexture: glGenTextures(1, (GLuint*)&ret); break; case glfnGenerateMipmap: glGenerateMipmap((GLenum)args->a0); break; case glfnGetActiveAttrib: glGetActiveAttrib( (GLuint)args->a0, (GLuint)args->a1, (GLsizei)args->a2, NULL, (GLint*)&ret, (GLenum*)args->a3, (GLchar*)parg); break; case glfnGetActiveUniform: glGetActiveUniform( (GLuint)args->a0, (GLuint)args->a1, (GLsizei)args->a2, NULL, (GLint*)&ret, (GLenum*)args->a3, (GLchar*)parg); break; case glfnGetAttachedShaders: glGetAttachedShaders((GLuint)args->a0, (GLsizei)args->a1, (GLsizei*)&ret, (GLuint*)parg); break; case glfnGetAttribLocation: ret = glGetAttribLocation((GLint)args->a0, (GLchar*)args->a1); break; case glfnGetBooleanv: glGetBooleanv((GLenum)args->a0, (GLboolean*)parg); break; case glfnGetBufferParameteri: glGetBufferParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetFloatv: glGetFloatv((GLenum)args->a0, (GLfloat*)parg); break; case glfnGetIntegerv: glGetIntegerv((GLenum)args->a0, (GLint*)parg); break; case glfnGetError: ret = glGetError(); break; case glfnGetFramebufferAttachmentParameteriv: glGetFramebufferAttachmentParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLint*)&ret); break; case glfnGetProgramiv: glGetProgramiv((GLint)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetProgramInfoLog: glGetProgramInfoLog((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg); break; case glfnGetRenderbufferParameteriv: glGetRenderbufferParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetShaderiv: glGetShaderiv((GLint)args->a0, (GLenum)args->a1, (GLint*)&ret); break; case glfnGetShaderInfoLog: glGetShaderInfoLog((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg); break; case glfnGetShaderPrecisionFormat: glGetShaderPrecisionFormat((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg, &((GLint*)parg)[2]); break; case glfnGetShaderSource: glGetShaderSource((GLuint)args->a0, (GLsizei)args->a1, 0, (GLchar*)parg); break; case glfnGetString: ret = (uintptr_t)glGetString((GLenum)args->a0); break; case glfnGetTexParameterfv: glGetTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)parg); break; case glfnGetTexParameteriv: glGetTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg); break; case glfnGetUniformfv: glGetUniformfv((GLuint)args->a0, (GLint)args->a1, (GLfloat*)parg); break; case glfnGetUniformiv: glGetUniformiv((GLuint)args->a0, (GLint)args->a1, (GLint*)parg); break; case glfnGetUniformLocation: ret = glGetUniformLocation((GLint)args->a0, (GLchar*)args->a1); break; case glfnGetVertexAttribfv: glGetVertexAttribfv((GLuint)args->a0, (GLenum)args->a1, (GLfloat*)parg); break; case glfnGetVertexAttribiv: glGetVertexAttribiv((GLuint)args->a0, (GLenum)args->a1, (GLint*)parg); break; case glfnHint: glHint((GLenum)args->a0, (GLenum)args->a1); break; case glfnIsBuffer: ret = glIsBuffer((GLint)args->a0); break; case glfnIsEnabled: ret = glIsEnabled((GLenum)args->a0); break; case glfnIsFramebuffer: ret = glIsFramebuffer((GLint)args->a0); break; case glfnIsProgram: ret = glIsProgram((GLint)args->a0); break; case glfnIsRenderbuffer: ret = glIsRenderbuffer((GLint)args->a0); break; case glfnIsShader: ret = glIsShader((GLint)args->a0); break; case glfnIsTexture: ret = glIsTexture((GLint)args->a0); break; case glfnLineWidth: glLineWidth(*(GLfloat*)&args->a0); break; case glfnLinkProgram: glLinkProgram((GLint)args->a0); break; case glfnPixelStorei: glPixelStorei((GLenum)args->a0, (GLint)args->a1); break; case glfnPolygonOffset: glPolygonOffset(*(GLfloat*)&args->a0, *(GLfloat*)&args->a1); break; case glfnReadPixels: glReadPixels((GLint)args->a0, (GLint)args->a1, (GLsizei)args->a2, (GLsizei)args->a3, (GLenum)args->a4, (GLenum)args->a5, (void*)parg); break; case glfnReleaseShaderCompiler: glReleaseShaderCompiler(); break; case glfnRenderbufferStorage: glRenderbufferStorage((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2, (GLint)args->a3); break; case glfnSampleCoverage: glSampleCoverage(*(GLfloat*)&args->a0, (GLboolean)args->a1); break; case glfnScissor: glScissor((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3); break; case glfnShaderSource: #if defined(os_ios) || defined(os_osx) glShaderSource((GLuint)args->a0, (GLsizei)args->a1, (const GLchar *const *)args->a2, NULL); #else glShaderSource((GLuint)args->a0, (GLsizei)args->a1, (const GLchar **)args->a2, NULL); #endif break; case glfnStencilFunc: glStencilFunc((GLenum)args->a0, (GLint)args->a1, (GLuint)args->a2); break; case glfnStencilFuncSeparate: glStencilFuncSeparate((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2, (GLuint)args->a3); break; case glfnStencilMask: glStencilMask((GLuint)args->a0); break; case glfnStencilMaskSeparate: glStencilMaskSeparate((GLenum)args->a0, (GLuint)args->a1); break; case glfnStencilOp: glStencilOp((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2); break; case glfnStencilOpSeparate: glStencilOpSeparate((GLenum)args->a0, (GLenum)args->a1, (GLenum)args->a2, (GLenum)args->a3); break; case glfnTexImage2D: glTexImage2D( (GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLsizei)args->a3, (GLsizei)args->a4, 0, // border (GLenum)args->a5, (GLenum)args->a6, (const GLvoid*)parg); break; case glfnTexSubImage2D: glTexSubImage2D( (GLenum)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLsizei)args->a4, (GLsizei)args->a5, (GLenum)args->a6, (GLenum)args->a7, (const GLvoid*)parg); break; case glfnTexParameterf: glTexParameterf((GLenum)args->a0, (GLenum)args->a1, *(GLfloat*)&args->a2); break; case glfnTexParameterfv: glTexParameterfv((GLenum)args->a0, (GLenum)args->a1, (GLfloat*)parg); break; case glfnTexParameteri: glTexParameteri((GLenum)args->a0, (GLenum)args->a1, (GLint)args->a2); break; case glfnTexParameteriv: glTexParameteriv((GLenum)args->a0, (GLenum)args->a1, (GLint*)parg); break; case glfnUniform1f: glUniform1f((GLint)args->a0, *(GLfloat*)&args->a1); break; case glfnUniform1fv: glUniform1fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform1i: glUniform1i((GLint)args->a0, (GLint)args->a1); break; case glfnUniform1iv: glUniform1iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform2f: glUniform2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2); break; case glfnUniform2fv: glUniform2fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform2i: glUniform2i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2); break; case glfnUniform2iv: glUniform2iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform3f: glUniform3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnUniform3fv: glUniform3fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform3i: glUniform3i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3); break; case glfnUniform3iv: glUniform3iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform4f: glUniform4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4); break; case glfnUniform4fv: glUniform4fv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniform4i: glUniform4i((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3, (GLint)args->a4); break; case glfnUniform4iv: glUniform4iv((GLint)args->a0, (GLsizeiptr)args->a1, (GLvoid*)parg); break; case glfnUniformMatrix2fv: glUniformMatrix2fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg); break; case glfnUniformMatrix3fv: glUniformMatrix3fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg); break; case glfnUniformMatrix4fv: glUniformMatrix4fv((GLint)args->a0, (GLsizeiptr)args->a1, 0, (GLvoid*)parg); break; case glfnUseProgram: glUseProgram((GLint)args->a0); break; case glfnValidateProgram: glValidateProgram((GLint)args->a0); break; case glfnVertexAttrib1f: glVertexAttrib1f((GLint)args->a0, *(GLfloat*)&args->a1); break; case glfnVertexAttrib1fv: glVertexAttrib1fv((GLint)args->a0, (GLfloat*)parg); break; case glfnVertexAttrib2f: glVertexAttrib2f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2); break; case glfnVertexAttrib2fv: glVertexAttrib2fv((GLint)args->a0, (GLfloat*)parg); break; case glfnVertexAttrib3f: glVertexAttrib3f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3); break; case glfnVertexAttrib3fv: glVertexAttrib3fv((GLint)args->a0, (GLfloat*)parg); break; case glfnVertexAttrib4f: glVertexAttrib4f((GLint)args->a0, *(GLfloat*)&args->a1, *(GLfloat*)&args->a2, *(GLfloat*)&args->a3, *(GLfloat*)&args->a4); break; case glfnVertexAttrib4fv: glVertexAttrib4fv((GLint)args->a0, (GLfloat*)parg); break; case glfnVertexAttribPointer: glVertexAttribPointer((GLuint)args->a0, (GLint)args->a1, (GLenum)args->a2, (GLboolean)args->a3, (GLsizei)args->a4, (const GLvoid*)args->a5); break; case glfnViewport: glViewport((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3); break; } return ret; }