void PixelNode::onDraw(const cocos2d::Mat4 &transform, uint32_t flags) { auto glProgram = _programState->getGLProgram(); glProgram->use(); auto loc = glProgram->getUniformLocation("u_cbf_opacity"); glProgram->setUniformLocationWith1f(loc, _opacityAsAlpha ? getOpacity()/255.f : 1.f); loc = glProgram->getUniformLocation("u_posexpand"); glProgram->setUniformLocationWith1f(loc, _opacityAsPosExpand ? _posexpand*(1.f - getOpacity()/255.f) : 0.f); loc = glProgram->getUniformLocation("u_mixcolor"); glProgram->setUniformLocationWith4fv(loc, &(_mixColor.x), 1); loc = glProgram->getUniformLocation("u_y_cut"); glProgram->setUniformLocationWith1f(loc, _yCut); glProgram->setUniformsForBuiltins(transform); glBindBuffer(GL_ARRAY_BUFFER, _vbo); if (Configuration::getInstance()->supportsShareableVAO()) { GL::bindVAO(_vao); } else { // TODO } if (_blend) { glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } glEnable(GL_CULL_FACE); // shadow cover打开depth test同时在fsh中对a为0的进行discard,以保证重合交叠处不会交叠而加深。 glEnable(GL_DEPTH_TEST); glDepthMask(true); if (_stencil) { glEnable(GL_STENCIL_TEST); // Draw floor glStencilFunc(GL_ALWAYS, 1, 0xFF); // Set any stencil to 1 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilMask(0xFF); // Write to stencil buffer glDepthMask(GL_FALSE); // Don't write to depth buffer glClear(GL_STENCIL_BUFFER_BIT); // Clear stencil buffer (0 by default) } if (_stenciled) { glEnable(GL_STENCIL_TEST); glStencilFunc(GL_EQUAL, 1, 0xFF); // Pass test if stencil value is 1 glStencilMask(0x00); // Don't write anything to stencil buffer glDepthMask(GL_TRUE); // Write to depth buffer } glDrawArrays(GL_TRIANGLES, 0, _count); if (Configuration::getInstance()->supportsShareableVAO()) { GL::bindVAO(0); } glDisable(GL_STENCIL_TEST); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisable(GL_DEPTH_TEST); glDepthMask(false); glEnable (GL_BLEND); CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,_count); CHECK_GL_ERROR_DEBUG(); }
void TestStage::onRender( float dFrame ) { glDisable( GL_DEPTH_TEST ); glDisable( GL_CULL_FACE ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); glEnable( GL_STENCIL_TEST ); GameWindow& window = Global::getDrawEngine()->getWindow(); int w = window.getWidth(); int h = window.getHeight(); for ( LightList::iterator iter = lights.begin(), itEnd = lights.end(); iter != itEnd ; ++iter ) { Light& light = *iter; #if 1 glColorMask(false, false, false, false); glStencilFunc(GL_ALWAYS, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); for( BlockList::iterator iter = blocks.begin(), itEnd = blocks.end(); iter != itEnd ; ++iter ) { Block& block = *iter; renderPolyShadow( light , block.pos , block.getVertices() , block.getVertexNum() ); } glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, 0, 1); glColorMask(true, true, true, true); #endif glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glUseProgram(program); glUniform2f( loc_lightLocation , light.pos.x , light.pos.y ); glUniform3f( loc_lightColor , light.color.x , light.color.y , light.color.z ); glUniform3f( loc_lightAttenuation , 0 , 1 / 5.0 , 0 ); glBegin( GL_QUADS ); glVertex2i( 0 , 0 ); glVertex2i( w , 0 ); glVertex2i( w , h ); glVertex2i( 0 , h ); glEnd(); glUseProgram(0); glDisable(GL_BLEND); glClear(GL_STENCIL_BUFFER_BIT); } glDisable( GL_STENCIL_TEST ); GLGraphics2D& g = ::Global::getDrawEngine()->getGLGraphics(); g.beginRender(); RenderUtility::setFont( g , FONT_S8 ); FixString< 256 > str; Vec2i pos = Vec2i( 10 , 10 ); g.drawText( pos , str.format( "Lights Num = %u" , lights.size() ) ); g.endRender(); }
void test_stencil(void) { GLint numStencilBits; GLuint stencilValues[NumTests] = { 0x7, // Result of test 0 0x0, // Result of test 1 0x2, // Result of test 2 0xff // Result of test 3. We need to fill this value in a run-time }; int i; RD_START("stencil", ""); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, 400, 240); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("Buffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "aPosition")); link_program(program); /* now set up our uniform. */ GCHK(uniform_location = glGetUniformLocation(program, "uColor")); GCHK(glClearColor(0.0, 0.0, 0.0, 0.0)); GCHK(glClearStencil(0x1)); GCHK(glClearDepthf(0.75)); GCHK(glEnable(GL_DEPTH_TEST)); GCHK(glEnable(GL_STENCIL_TEST)); // Set the viewport GCHK(glViewport(0, 0, width, height)); // Clear the color, depth, and stencil buffers. At this // point, the stencil buffer will be 0x1 for all pixels GCHK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); // Use the program object GCHK(glUseProgram(program)); // Load the vertex position GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices)); GCHK(glEnableVertexAttribArray(0)); // Test 0: // // Initialize upper-left region. In this case, the // stencil-buffer values will be replaced because the // stencil test for the rendered pixels will fail the // stencil test, which is // // ref mask stencil mask // ( 0x7 & 0x3 ) < ( 0x1 & 0x7 ) // // The value in the stencil buffer for these pixels will // be 0x7. // GCHK(glStencilFunc(GL_LESS, 0x7, 0x3)); GCHK(glStencilOp(GL_REPLACE, GL_DECR, GL_DECR)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[0])); // Test 1: // // Initialize the upper-right region. Here, we'll decrement // the stencil-buffer values where the stencil test passes // but the depth test fails. The stencil test is // // ref mask stencil mask // ( 0x3 & 0x3 ) > ( 0x1 & 0x3 ) // // but where the geometry fails the depth test. The // stencil values for these pixels will be 0x0. // GCHK(glStencilFunc(GL_GREATER, 0x3, 0x3)); GCHK(glStencilOp(GL_KEEP, GL_DECR, GL_KEEP)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[1])); // Test 2: // // Initialize the lower-left region. Here we'll increment // (with saturation) the stencil value where both the // stencil and depth tests pass. The stencil test for // these pixels will be // // ref mask stencil mask // ( 0x1 & 0x3 ) == ( 0x1 & 0x3 ) // // The stencil values for these pixels will be 0x2. // GCHK(glStencilFunc(GL_EQUAL, 0x1, 0x3)); GCHK(glStencilOp(GL_KEEP, GL_INCR, GL_INCR)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[2])); // Test 3: // // Finally, initialize the lower-right region. We'll invert // the stencil value where the stencil tests fails. The // stencil test for these pixels will be // // ref mask stencil mask // ( 0x2 & 0x1 ) == ( 0x1 & 0x1 ) // // The stencil value here will be set to ~((2^s-1) & 0x1), // (with the 0x1 being from the stencil clear value), // where 's' is the number of bits in the stencil buffer // GCHK(glStencilFunc(GL_EQUAL, 0x2, 0x1)); GCHK(glStencilOp(GL_INVERT, GL_KEEP, GL_KEEP)); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[3])); // Since we don't know at compile time how many stencil bits are present, // we'll query, and update the value correct value in the // stencilValues arrays for the fourth tests. We'll use this value // later in rendering. GCHK(glGetIntegerv(GL_STENCIL_BITS, &numStencilBits)); stencilValues[3] = ~(((1 << numStencilBits) - 1) & 0x1) & 0xff; // Use the stencil buffer for controlling where rendering will // occur. We disable writing to the stencil buffer so we // can test against them without modifying the values we // generated. GCHK(glStencilMask(0x0)); for (i = 0; i < NumTests; i++) { GCHK(glStencilFunc(GL_EQUAL, stencilValues[i], 0xff)); GCHK(glUniform4fv(uniform_location, 1, colors[i])); GCHK(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[4])); } ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); ECHK(eglDestroySurface(display, surface)); usleep(1000000); dump_bmp(display, surface, "stencil.bmp"); ECHK(eglTerminate(display)); RD_END(); }
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())); float range_near = rsx::method_registers.clip_min(); float range_far = rsx::method_registers.clip_max(); if (g_cfg.video.strict_rendering_mode) gl_state.depth_range(range_near, range_far); else { //Workaround to preserve depth precision but respect z direction //Ni no Kuni sets a very restricted z range (0.9x - 1.) and depth reads / tests are broken if (range_near <= range_far) gl_state.depth_range(0.f, 1.f); else gl_state.depth_range(1.f, 0.f); } } 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.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(); }
// Inherited from BatchRenderer void SceneObject_Decal_BatchRenderer::Execute() { if(!GetScene()->m_renderingDeferred) return; glEnable(GL_STENCIL_TEST); glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); glDepthFunc(GL_LEQUAL); glDepthMask(false); glEnable(GL_POLYGON_OFFSET_FILL); for(unsigned int i = 0, numDecals = m_pDecals.size(); i < numDecals;) { // Stencil in batches of 8 glColorMask(false, false, false, false); Shader::Unbind(); glPolygonOffset(2.0f, 2.0f); // Mark parts where depth test fails glStencilFunc(GL_ALWAYS, 0xff, 0xff); glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); unsigned int firstDecalInBatchIndex = i; // Stencil out regions with stencil mask for(unsigned int j = 0; j < 8 && i < numDecals; j++, i++) { glStencilMask(m_decalIndices[j]); m_pDecals[i]->Render_Batch_NoTexture(); } glColorMask(true, true, true, true); // Stencil test glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glPolygonOffset(-2.0f, -2.0f); // Re-render, second pass i = firstDecalInBatchIndex; GetScene()->RebindGBufferRenderShader(); for(unsigned int j = 0; j < 8 && i < numDecals; j++, i++) { glStencilFunc(GL_EQUAL, 0xff, m_decalIndices[j]); m_pDecals[i]->Render_Batch_Textured(); } glClear(GL_STENCIL_BUFFER_BIT); } GetScene()->SetCurrentGBufferRenderShader(Scene::e_plain); glDisable(GL_POLYGON_OFFSET_FILL); glDepthMask(true); glDepthFunc(GL_LESS); glDisable(GL_STENCIL_TEST); }
QSGRenderer::ClipType QSGRenderer::updateStencilClip(const QSGClipNode *clip) { if (!clip) { glDisable(GL_STENCIL_TEST); glDisable(GL_SCISSOR_TEST); return NoClip; } ClipType clipType = NoClip; glDisable(GL_SCISSOR_TEST); m_current_stencil_value = 0; m_current_scissor_rect = QRect(); while (clip) { QMatrix4x4 m = m_current_projection_matrix; if (clip->matrix()) m *= *clip->matrix(); // TODO: Check for multisampling and pixel grid alignment. bool isRectangleWithNoPerspective = clip->isRectangular() && qFuzzyIsNull(m(3, 0)) && qFuzzyIsNull(m(3, 1)); bool noRotate = qFuzzyIsNull(m(0, 1)) && qFuzzyIsNull(m(1, 0)); bool isRotate90 = qFuzzyIsNull(m(0, 0)) && qFuzzyIsNull(m(1, 1)); if (isRectangleWithNoPerspective && (noRotate || isRotate90)) { QRectF bbox = clip->clipRect(); qreal invW = 1 / m(3, 3); qreal fx1, fy1, fx2, fy2; if (noRotate) { fx1 = (bbox.left() * m(0, 0) + m(0, 3)) * invW; fy1 = (bbox.bottom() * m(1, 1) + m(1, 3)) * invW; fx2 = (bbox.right() * m(0, 0) + m(0, 3)) * invW; fy2 = (bbox.top() * m(1, 1) + m(1, 3)) * invW; } else { Q_ASSERT(isRotate90); fx1 = (bbox.bottom() * m(0, 1) + m(0, 3)) * invW; fy1 = (bbox.left() * m(1, 0) + m(1, 3)) * invW; fx2 = (bbox.top() * m(0, 1) + m(0, 3)) * invW; fy2 = (bbox.right() * m(1, 0) + m(1, 3)) * invW; } if (fx1 > fx2) qSwap(fx1, fx2); if (fy1 > fy2) qSwap(fy1, fy2); GLint ix1 = qRound((fx1 + 1) * m_device_rect.width() * qreal(0.5)); GLint iy1 = qRound((fy1 + 1) * m_device_rect.height() * qreal(0.5)); GLint ix2 = qRound((fx2 + 1) * m_device_rect.width() * qreal(0.5)); GLint iy2 = qRound((fy2 + 1) * m_device_rect.height() * qreal(0.5)); if (!(clipType & ScissorClip)) { m_current_scissor_rect = QRect(ix1, iy1, ix2 - ix1, iy2 - iy1); glEnable(GL_SCISSOR_TEST); clipType |= ScissorClip; } else { m_current_scissor_rect &= QRect(ix1, iy1, ix2 - ix1, iy2 - iy1); } glScissor(m_current_scissor_rect.x(), m_current_scissor_rect.y(), m_current_scissor_rect.width(), m_current_scissor_rect.height()); } else { if (!(clipType & StencilClip)) { if (!m_clip_program.isLinked()) { m_clip_program.addShaderFromSourceCode(QOpenGLShader::Vertex, "attribute highp vec4 vCoord; \n" "uniform highp mat4 matrix; \n" "void main() { \n" " gl_Position = matrix * vCoord; \n" "}"); m_clip_program.addShaderFromSourceCode(QOpenGLShader::Fragment, "void main() { \n" " gl_FragColor = vec4(0.81, 0.83, 0.12, 1.0); \n" // Trolltech green ftw! "}"); m_clip_program.bindAttributeLocation("vCoord", 0); m_clip_program.link(); m_clip_matrix_id = m_clip_program.uniformLocation("matrix"); } glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); glEnable(GL_STENCIL_TEST); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthMask(GL_FALSE); if (m_vertex_buffer_bound) { glBindBuffer(GL_ARRAY_BUFFER, 0); m_vertex_buffer_bound = false; } if (m_index_buffer_bound) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); m_index_buffer_bound = false; } m_clip_program.bind(); m_clip_program.enableAttributeArray(0); clipType |= StencilClip; } glStencilFunc(GL_EQUAL, m_current_stencil_value, 0xff); // stencil test, ref, test mask glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // stencil fail, z fail, z pass const QSGGeometry *g = clip->geometry(); Q_ASSERT(g->attributeCount() > 0); const QSGGeometry::Attribute *a = g->attributes(); glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), g->vertexData()); m_clip_program.setUniformValue(m_clip_matrix_id, m); if (g->indexCount()) { glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), g->indexData()); } else { glDrawArrays(g->drawingMode(), 0, g->vertexCount()); } ++m_current_stencil_value; } clip = clip->clipList(); } if (clipType & StencilClip) { m_clip_program.disableAttributeArray(0); glStencilFunc(GL_EQUAL, m_current_stencil_value, 0xff); // stencil test, ref, test mask glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // stencil fail, z fail, z pass bindable()->reactivate(); } else { glDisable(GL_STENCIL_TEST); } return clipType; }
void TextWidget::draw(const glm::mat4 &projection) { bool should_hover = (_hover_on && _hovering); if (_background_on || should_hover) { glm::mat4 bg_mvp = projection * _bg_model; glm::vec4 color = should_hover ? _hover_color : _background_color; gui_window->fill_rect(color, bg_mvp); } if (_icon_img) { glm::mat4 icon_mvp = projection * _icon_model; gui->draw_image(gui_window, _icon_img, icon_mvp); } glm::mat4 label_mvp = projection * _label_model; if (_text_interaction_on) { if (_placeholder_label.text().length() > 0 && _label.text().length() == 0) _placeholder_label.draw(label_mvp, _placeholder_color); } glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); glStencilMask(0xFF); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glClear(GL_STENCIL_BUFFER_BIT); gui_window->fill_rect(glm::vec4(1.0f, 1.0f, 1.0f, 1.0f), left + label_start_x(), top + label_start_y(), label_area_width(), _label.height()); glStencilFunc(GL_EQUAL, 1, 0xFF); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); _label.draw(label_mvp, _text_color); glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); glStencilMask(0xFF); glClear(GL_STENCIL_BUFFER_BIT); if (_text_interaction_on && _have_focus && _cursor_start != -1 && _cursor_end != -1) { if (_cursor_start == _cursor_end) { // draw cursor glm::mat4 cursor_mvp = projection * _cursor_model; gui_window->fill_rect(_selection_color, cursor_mvp); } else { // draw selection rectangle glm::mat4 sel_mvp = projection * _sel_model; gui_window->fill_rect(_selection_color, sel_mvp); glStencilFunc(GL_EQUAL, 1, 0xFF); glStencilMask(0x00); _label.draw(label_mvp, _sel_text_color); } } glDisable(GL_STENCIL_TEST); }
M(void, glStencilFunc, jint func, jint ref, jint mask) { glStencilFunc(func, ref, mask); }
void display(){ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glViewport(0, 0, glwidth, glheight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(1.5, (double)glwidth / (double)glheight, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(150.0,100.0,-200.0, 0.0,0.0,0.0, 0.0,1.0,0.0); glMultMatrixd(Rotate); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, gold_diff); glPushMatrix(); glTranslated(sin(t),cos(t),-3.); glRotatef(90, 1.0f, 0.0f, 0.0f); glutSolidSphere(.3,20,20); glPopMatrix(); glutSolidSphere(1.5,20,20); glLightfv(GL_LIGHT0, GL_POSITION, light0_pos); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red_light); if(!colormask_on){ glColorMask(0,0,0,0); glDepthMask(0); } glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); glStencilMask(~0); if(frontcull){ glCullFace(GL_FRONT); glStencilFunc(GL_ALWAYS, 1, ~0); glStencilOp(GL_REPLACE, GL_KEEP, GL_REPLACE); /* glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); */ /* glStencilOp(GL_KEEP, GL_INCR, GL_KEEP); */ glPushMatrix(); glTranslated(sin(t),cos(t),-3); glRotatef(90, 1.0f, 0.0f, 0.0f); /* glRotatef(90, 0.0f, 0.0f, 1.0f); */ cylinder(.3,100,20); glPopMatrix(); } if(backcull){ glCullFace(GL_BACK); glStencilFunc(GL_ALWAYS, 1, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); /* glStencilOp(GL_KEEP, GL_DECR, GL_KEEP); */ glPushMatrix(); glTranslated(sin(t),cos(t),-3.); glRotatef(90, 1.0f, 0.0f, 0.0f); /* glRotatef(90, 0.0f, 0.0f, 1.0f); */ cylinder(.3,100,20); glPopMatrix(); } glDisable(GL_CULL_FACE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_TRUE); glStencilFunc(GL_EQUAL, 1, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glDisable(GL_DEPTH_TEST); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,black_light); glBegin(GL_QUADS); glVertex2i(-10, -10); glVertex2i(-10, 10); glVertex2i(10, 10); glVertex2i(10, -10); glEnd(); glEnable(GL_DEPTH_TEST); /* glEnable(GL_DEPTH_TEST); */ glDisable(GL_STENCIL_TEST); console(); t+=1e-2; glFinish(); glutSwapBuffers(); }
void MapRenderer::draw(GameWorld* world, const MapInfo& mi) { renderer->pushDebugGroup("Map"); renderer->useProgram(rectProg); // World out the number of units per tile glm::vec2 worldSize(GAME_MAP_SIZE); const int mapBlockLine = 8; glm::vec2 tileSize = worldSize / (float)mapBlockLine; // Determine the scale to show the right number of world units on the screen float worldScale = mi.screenSize / mi.worldSize; auto proj = renderer->get2DProjection(); glm::mat4 view, model; renderer->setUniform(rectProg, "proj", proj); renderer->setUniform(rectProg, "model", glm::mat4()); renderer->setUniform(rectProg, "colour", glm::vec4(0.f, 0.f, 0.f, 1.f)); view = glm::translate(view, glm::vec3(mi.screenPosition, 0.f)); if (mi.clipToSize) { glBindVertexArray( circle.getVAOName() ); glBindTexture(GL_TEXTURE_2D, 0); glm::mat4 circleView = glm::scale(view, glm::vec3(mi.screenSize)); renderer->setUniform(rectProg, "view", circleView); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilMask(0xFF); glColorMask(0x00, 0x00, 0x00, 0x00); glDrawArrays(GL_TRIANGLE_FAN, 0, 182); glColorMask(0xFF, 0xFF, 0xFF, 0xFF); glStencilFunc(GL_EQUAL, 1, 0xFF); } view = glm::scale(view, glm::vec3(worldScale)); view = glm::rotate(view, mi.rotation, glm::vec3(0.f, 0.f, 1.f)); view = glm::translate(view, glm::vec3(glm::vec2(-1.f, 1.f) * mi.worldCenter, 0.f)); renderer->setUniform(rectProg, "view", view); glBindVertexArray( rect.getVAOName() ); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); // radar00 = -x, +y // incrementing in X, then Y int initX = -(mapBlockLine/2); int initY = -(mapBlockLine/2); for( int m = 0; m < MAP_BLOCK_SIZE; ++m ) { std::string num = (m < 10 ? "0" : ""); std::string name = "radar" + num + std::to_string(m); auto texture = world->data->textures[{name,""}]; glBindTexture(GL_TEXTURE_2D, texture->getName()); int mX = initX + (m % mapBlockLine); int mY = initY + (m / mapBlockLine); auto tc = glm::vec2(mX, mY) * tileSize + glm::vec2(tileSize/2.f); glm::mat4 tilemodel = model; tilemodel = glm::translate( tilemodel, glm::vec3( tc, 0.f ) ); tilemodel = glm::scale( tilemodel, glm::vec3( tileSize, 1.f ) ); renderer->setUniform(rectProg, "model", tilemodel); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); } // From here on out we will work in screenspace renderer->setUniform(rectProg, "view", glm::mat4()); if (mi.clipToSize) { glDisable(GL_STENCIL_TEST); // We only need the outer ring if we're clipping. glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ONE, GL_ZERO); TextureData::Handle radarDisc = data->findTexture("radardisc"); glm::mat4 model; model = glm::translate(model, glm::vec3(mi.screenPosition, 0.0f)); model = glm::scale(model, glm::vec3(mi.screenSize*1.07)); renderer->setUniform(rectProg, "model", model); glBindTexture(GL_TEXTURE_2D, radarDisc->getName()); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); } for(auto& blip : world->state->radarBlips) { glm::vec2 blippos( blip.second.coord ); if( blip.second.target > 0 ) { GameObject* object = nullptr; switch( blip.second.type ) { case BlipData::Vehicle: object = world->vehiclePool.find(blip.second.target); break; case BlipData::Character: object = world->pedestrianPool.find(blip.second.target); break; case BlipData::Pickup: object = world->pickupPool.find(blip.second.target); break; default: break; } if( object ) { blippos = glm::vec2( object->getPosition() ); } } drawBlip(blippos, view, mi, blip.second.texture); } // Draw the player blip auto player = world->pedestrianPool.find(world->state->playerObject); if( player ) { glm::vec2 plyblip(player->getPosition()); float hdg = glm::roll(player->getRotation()); drawBlip(plyblip, view, mi, "radar_centre", mi.rotation - hdg); } drawBlip(mi.worldCenter + glm::vec2(0.f, mi.worldSize), view, mi, "radar_north", 0.f, 24.f); glBindVertexArray( 0 ); glBindTexture(GL_TEXTURE_2D, 0); glUseProgram(0); /// @TODO migrate to using the renderer renderer->invalidate(); renderer->popDebugGroup(); }
static void new_ship(ModeInfo *mi) { commander_conf *cp = &commander[MI_SCREEN(mi)]; int i; GLfloat *this_v; GLint *p; /*GLfloat *this_n;*/ int count; #if 0 int wire = MI_IS_WIREFRAME(mi); GLfloat bcolor[4] = {0.2, 0.2, 0.2, 0.2}; GLfloat bspec[4] = {0.1, 0.1, 0.1, 0.1}; GLfloat bshiny = 32.0; GLfloat pos[4] = {-8.0, -8.0, -16.0, 0.0}; /* -6 -6 -16 */ GLfloat amb[4] = {0.2, 0.2, 0.2, 0.4}; GLfloat dif[4] = {0.2, 0.2, 0.2, 0.2}; GLfloat spc[4] = {0.0, 0.0, 0.0, 0.0}; if(!wire) { glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_AMBIENT, amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0, GL_SPECULAR, spc); glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, bcolor); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, bspec); glMateriali (GL_FRONT_AND_BACK, GL_SHININESS, bshiny); } #endif cp->list = glGenLists(1); glNewList(cp->list, GL_COMPILE); if(MI_IS_MONO(mi)) { /* FIXME support mono display */ abort(); } /* wireframe strategy: use stencil buffer, not polygon offset, * because it's impossible to get the right parameters for * glPolygonOffset() reliably */ /* hidden-line removal as per * http://glprogramming.com/red/chapter14.html#name16 */ /* TODO: - reinstate choice of wireframe vs filled - rationalise some of the duplicated code below */ glEnable(GL_STENCIL_TEST); glEnable(GL_DEPTH_TEST); glClear(GL_STENCIL_BUFFER_BIT); glStencilFunc(GL_ALWAYS, 0, 1); glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT); glColor3f(1.0, 1.0, 1.0); p=ship_f[cp->which]; this_v=ship_v[cp->which]; /* for debugging - draw axes */ #if 0 glLineWidth(1); glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(10,0,0); glEnd(); glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(0,10,0); glEnd(); glBegin(GL_LINES); glVertex3f(0.1,0,0); glVertex3f(0.1,10,0); glEnd(); glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(0,0,10); glEnd(); glBegin(GL_LINES); glVertex3f(0,0.1,0); glVertex3f(0,0.1,10); glEnd(); glBegin(GL_LINES); glVertex3f(0,0.2,0); glVertex3f(0,0.2,10); glEnd(); #endif /* draw the wireframe shape */ while(*p != 0) { count=*p; p++; /* draw outline polygon */ if(count==1) { glBegin(GL_POINTS); } else if(count==2) { /* chunky lines :-) */ glLineWidth(2); glBegin(GL_LINES); } else { glLineWidth(2); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_POLYGON); do_normal(this_v[p[0]*3], this_v[p[0]*3+1], this_v[p[0]*3+2], this_v[p[1]*3], this_v[p[1]*3+1], this_v[p[1]*3+2], this_v[p[2]*3], this_v[p[2]*3+1], this_v[p[2]*3+2]); } for (i = 0 ; i < count ; i++) { glVertex3f(this_v[p[i]*3], this_v[p[i]*3+1], this_v[p[i]*3+2]); } glEnd(); glColor3f(0.0, 0.0, 0.0); glStencilFunc(GL_EQUAL, 0, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); /* draw filled polygon */ if(count>=3) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glBegin(GL_POLYGON); do_normal(this_v[p[0]*3], this_v[p[0]*3+1], this_v[p[0]*3+2], this_v[p[1]*3], this_v[p[1]*3+1], this_v[p[1]*3+2], this_v[p[2]*3], this_v[p[2]*3+1], this_v[p[2]*3+2]); for (i = 0 ; i < count ; i++) { glVertex3f(this_v[p[i]*3], this_v[p[i]*3+1], this_v[p[i]*3+2]); } glEnd(); } glColor3f(1.0, 1.0, 1.0); glStencilFunc(GL_ALWAYS, 0, 1); glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT); /* draw outline polygon */ if(count==1) { glBegin(GL_POINTS); } else if(count==2) { /* chunky lines :-) */ glLineWidth(2); glBegin(GL_LINES); } else { glLineWidth(2); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_POLYGON); do_normal(this_v[p[0]*3], this_v[p[0]*3+1], this_v[p[0]*3+2], this_v[p[1]*3], this_v[p[1]*3+1], this_v[p[1]*3+2], this_v[p[2]*3], this_v[p[2]*3+1], this_v[p[2]*3+2]); } for (i = 0 ; i < count ; i++) { glVertex3f(this_v[p[i]*3], this_v[p[i]*3+1], this_v[p[i]*3+2]); } glEnd(); cp->npoints++; p+=count; } glEndList(); }
void RawStencilBufferTest::setupStencilForDrawingOnPlane(GLint plane) { GLint planeMask = 0x1 << plane; glStencilFunc(GL_EQUAL, planeMask, planeMask); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); }
static void pie_DrawShadows(void) { const float width = pie_GetVideoBufferWidth(); const float height = pie_GetVideoBufferHeight(); GLenum op_depth_pass_front = GL_INCR, op_depth_pass_back = GL_DECR; pie_SetTexturePage(TEXPAGE_NONE); glPushMatrix(); pie_SetAlphaTest(false); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthFunc(GL_LESS); glDepthMask(GL_FALSE); glEnable(GL_STENCIL_TEST); // Check if we have the required extensions if (GLEE_EXT_stencil_wrap) { op_depth_pass_front = GL_INCR_WRAP_EXT; op_depth_pass_back = GL_DECR_WRAP_EXT; } // generic 1-pass version if (GLEE_EXT_stencil_two_side) { glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); glDisable(GL_CULL_FACE); glStencilMask(~0); glActiveStencilFaceEXT(GL_BACK); glStencilOp(GL_KEEP, GL_KEEP, op_depth_pass_back); glStencilFunc(GL_ALWAYS, 0, ~0); glActiveStencilFaceEXT(GL_FRONT); glStencilOp(GL_KEEP, GL_KEEP, op_depth_pass_front); glStencilFunc(GL_ALWAYS, 0, ~0); pie_ShadowDrawLoop(); glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); } // check for ATI-specific 1-pass version else if (GLEE_ATI_separate_stencil) { glDisable(GL_CULL_FACE); glStencilMask(~0); glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, op_depth_pass_back); glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, op_depth_pass_front); glStencilFunc(GL_ALWAYS, 0, ~0); pie_ShadowDrawLoop(); } // fall back to default 2-pass version else { glStencilMask(~0); glStencilFunc(GL_ALWAYS, 0, ~0); glEnable(GL_CULL_FACE); // Setup stencil for front-facing polygons glCullFace(GL_BACK); glStencilOp(GL_KEEP, GL_KEEP, op_depth_pass_front); pie_ShadowDrawLoop(); // Setup stencil for back-facing polygons glCullFace(GL_FRONT); glStencilOp(GL_KEEP, GL_KEEP, op_depth_pass_back); pie_ShadowDrawLoop(); } pie_SetRendMode(REND_ALPHA); glEnable(GL_CULL_FACE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilMask(~0); glStencilFunc(GL_LESS, 0, ~0); glColor4f(0, 0, 0, 0.5); pie_PerspectiveEnd(); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glBegin(GL_TRIANGLE_STRIP); glVertex2f(0, 0); glVertex2f(width, 0); glVertex2f(0, height); glVertex2f(width, height); glEnd(); pie_PerspectiveBegin(); pie_SetRendMode(REND_OPAQUE); glDisable(GL_STENCIL_TEST); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glPopMatrix(); nb_scshapes = 0; }
enum piglit_result piglit_display(void) { GLboolean pass = GL_TRUE; int i; static float red[] = {1.0, 0.0, 0.0, 0.0}; static float green[] = {0.0, 1.0, 0.0, 0.0}; static float blue[] = {0.0, 0.0, 1.0, 0.0}; static float square[100]; piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); /* whole window gray -- none should be visible */ glClearColor(0.5, 0.5, 0.5, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* Clear stencil to 0, which will be drawn red */ glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); /* quad at 10, 10 that will be drawn green. */ for (i = 0; i < 100; i++) square[i] = 1.0; glRasterPos2i(10, 10); glDrawPixels(10, 10, GL_STENCIL_INDEX, GL_FLOAT, square); /* quad at 30, 10 that will be drawn blue. */ for (i = 0; i < 100; i++) square[i] = 2.0; glRasterPos2i(30, 10); glDrawPixels(10, 10, GL_STENCIL_INDEX, GL_FLOAT, square); glDisable(GL_SCISSOR_TEST); glEnable(GL_STENCIL_TEST); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); /* First quad -- stencil == 0 gets red */ glStencilFunc(GL_EQUAL, 0, ~0); glColor4fv(red); piglit_draw_rect(0, 0, piglit_width, piglit_height); /* Second quad -- stencil == 1 gets green */ glStencilFunc(GL_EQUAL, 1, ~0); glColor4fv(green); piglit_draw_rect(0, 0, piglit_width, piglit_height); /* Last quad -- stencil == 2 gets blue */ glStencilFunc(GL_EQUAL, 2, ~0); glColor4fv(blue); piglit_draw_rect(0, 0, piglit_width, piglit_height); assert(glGetError() == 0); pass &= piglit_probe_rect_rgb(0, 0, piglit_width, 10, red); pass &= piglit_probe_rect_rgb(0, 10, 10, 10, red); pass &= piglit_probe_rect_rgb(10, 10, 10, 10, green); pass &= piglit_probe_rect_rgb(20, 10, 10, 10, red); pass &= piglit_probe_rect_rgb(30, 10, 10, 10, blue); pass &= piglit_probe_rect_rgb(40, 10, piglit_width-40, 10, red); pass &= piglit_probe_rect_rgb(0, 20, piglit_width, piglit_height - 20, red); glutSwapBuffers(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
void Application::drawScene() { GLenum err; glViewport(0, 0, 2048, 2048); glBindFramebuffer(GL_FRAMEBUFFER, fbo); float back_color[] = { 1, 1, 1, 1 }; float zero[] = { 0.0f, 0.0f, 0.0f, -10.0f }; float one = 1.0f; int zero_int = 0; glClearBufferfv(GL_COLOR, 0, back_color); glClearBufferfv(GL_DEPTH, 0, &one); glClearBufferiv(GL_STENCIL, 0, &zero_int); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glm::mat4* transform_matrices = nullptr; GL_ERROR // ===================================================================== // ===================================================================== // == Rendering the mirror contents // ===================================================================== // ===================================================================== #define RENDER_MIRROR #ifdef RENDER_MIRROR glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); GL_ERROR // Do Masking //glColorMask(0, 0, 0, 0); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); GL_ERROR // Apply the mirror glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_transformation_buffer); transform_matrices = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 3 * sizeof(glm::mat4), GL_MAP_WRITE_BIT); transform_matrices[0] = m_projmat; transform_matrices[1] = m_viewmat; transform_matrices[2] = m_worldmat * glm::mat4( 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); glUnmapBuffer(GL_UNIFORM_BUFFER); drawMirror(); // Render Mirrored Triangle glDepthMask(GL_FALSE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_GREATER); glColorMask(1, 1, 1, 1); glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // Apply the mirror glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_transformation_buffer); transform_matrices = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 3 * sizeof(glm::mat4), GL_MAP_WRITE_BIT); transform_matrices[0] = m_projmat; transform_matrices[1] = m_viewmat; transform_matrices[2] = m_worldmat * glm::mat4( 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, -5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); glUnmapBuffer(GL_UNIFORM_BUFFER); drawTriangle(); GL_ERROR #endif // =================================================================== // =================================================================== // Render main triangle // =================================================================== // =================================================================== glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_transformation_buffer); transform_matrices = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 3 * sizeof(glm::mat4), GL_MAP_WRITE_BIT); transform_matrices[0] = m_projmat; transform_matrices[1] = m_viewmat; transform_matrices[2] = m_worldmat * glm::mat4( 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); glUnmapBuffer(GL_UNIFORM_BUFFER); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glDisable(GL_STENCIL_TEST); drawTriangle(); GL_ERROR glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_transformation_buffer); transform_matrices = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 3 * sizeof(glm::mat4), GL_MAP_WRITE_BIT); transform_matrices[0] = m_projmat; transform_matrices[1] = m_viewmat; transform_matrices[2] = m_worldmat; glUnmapBuffer(GL_UNIFORM_BUFFER); GL_ERROR }
void game_draw(int pose, float st) { float fov = view_fov; if (jump_b) fov *= 2.f * fabsf(jump_dt - 0.5); if (game_state) { config_push_persp(fov, 0.1f, FAR_DIST); glPushMatrix(); { float v[3], rx, ry; float pup[3]; float pdn[3]; v_cpy(pup, view_p); v_cpy(pdn, view_p); pdn[1] = -pdn[1]; /* Compute and apply the view. */ v_sub(v, view_c, view_p); rx = V_DEG(fatan2f(-v[1], fsqrtf(v[0] * v[0] + v[2] * v[2]))); ry = V_DEG(fatan2f(+v[0], -v[2])) + st; glTranslatef(0.f, 0.f, -v_len(v)); glRotatef(rx, 1.f, 0.f, 0.f); glRotatef(ry, 0.f, 1.f, 0.f); glTranslatef(-view_c[0], -view_c[1], -view_c[2]); #ifndef DREAMCAST_KGL_NOT_IMPLEMENT if (config_get_d(CONFIG_REFLECTION)) { /* Draw the mirror only into the stencil buffer. */ glDisable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); game_refl_all(0); /* Draw the scene reflected into color and depth buffers. */ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); glEnable(GL_DEPTH_TEST); glFrontFace(GL_CW); glPushMatrix(); { glScalef(+1.f, -1.f, +1.f); game_draw_light(); game_draw_back(pose, -1, pdn); game_draw_fore(pose, rx, ry, -1, pdn); } glPopMatrix(); glFrontFace(GL_CCW); glDisable(GL_STENCIL_TEST); } #endif /* Draw the scene normally. */ game_draw_light(); game_refl_all(pose ? 0 : config_get_d(CONFIG_SHADOW)); game_draw_back(pose, +1, pup); game_draw_fore(pose, rx, ry, +1, pup); } glPopMatrix(); config_pop_matrix(); /* Draw the fade overlay. */ fade_draw(fade_k); } }
void PaintView::initSetup() { #ifndef MESA // To avoid flicker on some machines. glDrawBuffer(GL_FRONT_AND_BACK); #endif // !MESA if (!valid()) { glClearColor(0.7f, 0.7f, 0.7f, 1.0); // We're only using 2-D, so turn off depth glDisable(GL_DEPTH_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); ortho(); glClear(GL_COLOR_BUFFER_BIT); } Point scrollpos;// = GetScrollPosition(); scrollpos.x = 0; scrollpos.y = 0; // Main window width and height m_nWindowWidth = w(); m_nWindowHeight = h(); int drawWidth, drawHeight; drawWidth = min(m_nWindowWidth, m_pDoc->m_nPaintWidth); drawHeight = min(m_nWindowHeight, m_pDoc->m_nPaintHeight); int startrow = m_pDoc->m_nPaintHeight - (scrollpos.y + drawHeight); if (startrow < 0) startrow = 0; m_pPaintBitstart = m_pDoc->m_ucPainting + 3 * ((m_pDoc->m_nPaintWidth * startrow) + scrollpos.x); m_nDrawWidth = drawWidth; m_nDrawHeight = drawHeight; m_nStartRow = startrow; m_nEndRow = startrow + drawHeight; m_nStartCol = scrollpos.x; m_nEndCol = m_nStartCol + drawWidth; // Implement edge clipping here using stencil buffer // There are two steps: // 1. Initialize stencil buffer by setting color buffer masks to false // and then setting appropriate ref value to stencil buffer by failing // the stencil test every time. // 2. Use the initialized stencil buffer and stencil test to write only // in the locations where stencil value is 1 if (!valid()) { // Quick explanation: // Stencil buffer gives an option to which // fragments should be drawn and which shouldn't // more info: https://en.wikipedia.org/wiki/Stencil_buffer /************** Step 1 **************/ glEnable(GL_STENCIL_TEST); /* Basically glStencilMask allows us to set a bitmask that is ANDed with the stencil value about to be written to the buffer */ /*----------------------------------------------------------------*/ // 0xFF means we set all stencil values to 1 per bit, no mask glStencilMask(0xFF); // clear stencil buffer witih 0s glClear(GL_STENCIL_BUFFER_BIT); /* Configure Stencil Testing*/ /* a. glStencilFunc describes what OpenGL should do with the content of the stencil buffer /* b. glStencilOp describes how we can update the stencil buffer /*------------------------------------------------*/ // Force drawing to stencil by declaring stencil test function fails // This means we draw 1s on test fail (always) glStencilFunc(GL_NEVER, 1, 0xFF); // replace stencil buffer values to ref=1, 2nd parameter of glStencilFunc glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); // Disable all color channels so stencil buffer won't affect // the content of the color buffer glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Draw stencil shape glBegin(GL_TRIANGLE_STRIP); // Get the vertices for the paint view glVertex2f(0, m_nWindowHeight - m_nDrawHeight); // bottom left glVertex2f(m_nDrawWidth, m_nWindowHeight - m_nDrawHeight); // bottom right glVertex2f(0, m_nWindowHeight); // top left glVertex2f(m_nDrawWidth, m_nWindowHeight); // top right glEnd(); /************** Step 2 **************/ // Enable color glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // no more modifying of stencil buffer on stencil glStencilMask(0); // stencil test: only pass stencil test at stencilValue less than 0 // and write actual content to color buffer only at stencil shape locations. glStencilFunc(GL_LESS, 0, 0xFF); } }
void RenderTextureTestDepthStencil::onBeforDraw() { glStencilFunc(GL_NOTEQUAL, 1, 0xFF); }
void glRenderer::render(const iClipState &rClipState) { glClipState result; result.reset(&rClipState); float alpha = result.alpha; const Point3f &color = result.color; const Rect &clip = result.clip; if (clip.GetWidth() && clip.GetHeight()) { glColorMask(0,0,0,0); // Set Color Mask glEnable(GL_STENCIL_TEST); // Enable Stencil Buffer For "marking" The Floor glStencilFunc(GL_ALWAYS, 1, 1); // Always Passes, 1 Bit Plane, 1 As Mask glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); // We Set The Stencil Buffer To 1 Where We Draw Any Polygon // Keep If Test Fails, Keep If Test Passes But Buffer Test Fails // Replace If Test Passes glDisable(GL_DEPTH_TEST); // Disable Depth Testing //DrawFloor(); // Draw The Floor (Draws To The Stencil Buffer) glBegin(GL_QUADS); glVertex3f(result.position.x + clip.leftTop.x, result.position.y + clip.leftTop.y, 0); glVertex3f(result.position.x + clip.rightBottom.x, result.position.y + clip.leftTop.y, 0); glVertex3f(result.position.x + clip.rightBottom.x, result.position.y + clip.rightBottom.y, 0); glVertex3f(result.position.x + clip.leftTop.x, result.position.y + clip.rightBottom.y, 0); glEnd(); // We Only Want To Mark It In The Stencil Buffer //glEnable(GL_DEPTH_TEST); // Enable Depth Testing glColorMask(1,1,1,1); // Set Color Mask to TRUE, TRUE, TRUE, TRUE glStencilFunc(GL_EQUAL, 1, 1); // We Draw Only Where The Stencil Is 1 // (I.E. Where The Floor Was Drawn) glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // Don't Change The Stencil Buffer } glColor4f(color.x, color.y, color.z, alpha); const Image &image = result.image; if (image.valid()) { Wm4::Matrix3f m33; result.getMatrix(m33, 1, 1, 1, 1); //glClipState::updateMatrix(m33, (const glClipState&)rClipState, (const glClipState&)rParentClipState); m33 = m33.Transpose(); glTexture &glTex = *(glTexture*)&image.getTexture(); unsigned int tex = glTex.getGlTexture(); glBindTexture(GL_TEXTURE_2D, tex); const Rect &texRect = image.getRect(); const float w_2 = texRect.GetWidth() * 0.5f; const float h_2 = texRect.GetHeight() * 0.5f; Wm4::Vector3f wmPosition0 = m33 * Wm4::Vector3f(-w_2, -h_2, 1.f); Wm4::Vector3f wmPosition1 = m33 * Wm4::Vector3f(w_2, -h_2, 1.f); Wm4::Vector3f wmPosition2 = m33 * Wm4::Vector3f(w_2, h_2, 1.f); Wm4::Vector3f wmPosition3 = m33 * Wm4::Vector3f(-w_2, h_2, 1.f); float left = (float)texRect.leftTop.x / glTex.getWidth(); float right = (float)texRect.rightBottom.x / glTex.getWidth(); float top = (float)texRect.leftTop.y / glTex.getHeight(); float bottom = (float)texRect.rightBottom.y / glTex.getHeight(); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin(GL_QUADS); glTexCoord2f(left, top); glVertex3f(wmPosition0.X(), wmPosition0.Y(), 0.5f);// x-,y- glTexCoord2f(right, top); glVertex3f(wmPosition1.X(), wmPosition1.Y(), 0.5f);// x+,y- glTexCoord2f(right, bottom); glVertex3f(wmPosition2.X(), wmPosition2.Y(), 0.5f);// x+,y+ glTexCoord2f(left, bottom); glVertex3f(wmPosition3.X(), wmPosition3.Y(), 0.5f);// x-,y+ glEnd(); } const std::string &text = result.text; if (text.length()) { glport::Font *pFont = fontmap->GetFont("Impact"); if (pFont) { glPushMatrix(); glTranslatef(result.position.x, result.position.y, 0); glScalef(result.scale.x, -result.scale.y, 1); // reverse y direciton glTranslatef(-result.anchorOffPos.x, -result.anchorOffPos.y, 0); glDisable(GL_TEXTURE_2D); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA); glLineWidth(0.3f); pFont->textOut(text.c_str()); glPopMatrix(); } } glDisable(GL_STENCIL_TEST); }
void set_gl_options (TRenderMode mode) { switch (mode) { case GUI: glEnable (GL_TEXTURE_2D); glDisable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glDisable (GL_LIGHTING); glDisable (GL_NORMALIZE); glDisable (GL_ALPHA_TEST); glEnable (GL_BLEND); glDisable (GL_STENCIL_TEST); glDisable (GL_TEXTURE_GEN_S); glDisable (GL_TEXTURE_GEN_T); glDisable (GL_COLOR_MATERIAL); glDepthMask (GL_TRUE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LESS); glDisable (GL_FOG); break; case GAUGE_BARS: glEnable (GL_TEXTURE_2D); glDisable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glDisable (GL_LIGHTING); glDisable (GL_NORMALIZE); glDisable (GL_ALPHA_TEST); glEnable (GL_BLEND); glDisable (GL_STENCIL_TEST); glEnable (GL_TEXTURE_GEN_S); glEnable (GL_TEXTURE_GEN_T); glDisable (GL_COLOR_MATERIAL); glDepthMask (GL_TRUE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LESS); glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); break; case TEXFONT: glEnable (GL_TEXTURE_2D); glDisable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glDisable (GL_LIGHTING); glDisable (GL_NORMALIZE); glDisable (GL_ALPHA_TEST); glEnable (GL_BLEND); glDisable (GL_STENCIL_TEST); glDisable (GL_TEXTURE_GEN_S); glDisable (GL_TEXTURE_GEN_T); glDisable (GL_COLOR_MATERIAL); glDepthMask (GL_TRUE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LESS); break; case COURSE: glEnable (GL_TEXTURE_2D); glEnable (GL_DEPTH_TEST); glEnable (GL_CULL_FACE); glEnable (GL_LIGHTING); glDisable (GL_NORMALIZE); glDisable (GL_ALPHA_TEST); glEnable (GL_BLEND); glDisable (GL_STENCIL_TEST); glEnable (GL_TEXTURE_GEN_S); glEnable (GL_TEXTURE_GEN_T); glEnable (GL_COLOR_MATERIAL); glDepthMask (GL_TRUE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LEQUAL); glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); break; case TREES: glEnable (GL_TEXTURE_2D); glEnable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glEnable (GL_LIGHTING); glDisable (GL_NORMALIZE); glEnable (GL_ALPHA_TEST); glEnable (GL_BLEND); glDisable (GL_STENCIL_TEST); glDisable (GL_TEXTURE_GEN_S); glDisable (GL_TEXTURE_GEN_T); glDisable (GL_COLOR_MATERIAL); glDepthMask (GL_TRUE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LESS); glAlphaFunc (GL_GEQUAL, 0.5); break; case PARTICLES: glEnable (GL_TEXTURE_2D); glEnable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glDisable (GL_LIGHTING); glDisable (GL_NORMALIZE); glEnable (GL_ALPHA_TEST); glEnable (GL_BLEND); glDisable (GL_STENCIL_TEST); glDisable (GL_TEXTURE_GEN_S); glDisable (GL_TEXTURE_GEN_T); glDisable (GL_COLOR_MATERIAL); glDepthMask (GL_TRUE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LESS); glAlphaFunc (GL_GEQUAL, 0.5); break; case SKY: glEnable (GL_TEXTURE_2D); glDisable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glDisable (GL_LIGHTING); glDisable (GL_NORMALIZE); glDisable (GL_ALPHA_TEST); glEnable (GL_BLEND); glDisable (GL_STENCIL_TEST); glDisable (GL_TEXTURE_GEN_S); glDisable (GL_TEXTURE_GEN_T); glDisable (GL_COLOR_MATERIAL); glDepthMask (GL_FALSE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LESS); break; case FOG_PLANE: glDisable (GL_TEXTURE_2D); glEnable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glDisable (GL_LIGHTING); glDisable (GL_NORMALIZE); glDisable (GL_ALPHA_TEST); glEnable (GL_BLEND); glDisable (GL_STENCIL_TEST); glDisable (GL_TEXTURE_GEN_S); glDisable (GL_TEXTURE_GEN_T); glDisable (GL_COLOR_MATERIAL); glDepthMask (GL_TRUE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LESS); break; case TUX: glDisable (GL_TEXTURE_2D); glEnable (GL_DEPTH_TEST); glEnable (GL_CULL_FACE); glEnable (GL_LIGHTING); glEnable (GL_NORMALIZE); glDisable (GL_ALPHA_TEST); glEnable (GL_BLEND); glDisable (GL_STENCIL_TEST); glDisable (GL_TEXTURE_GEN_S); glDisable (GL_TEXTURE_GEN_T); glDisable (GL_COLOR_MATERIAL); glDepthMask (GL_TRUE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LESS); break; case TUX_SHADOW: #ifdef USE_STENCIL_BUFFER glDisable (GL_TEXTURE_2D); glEnable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glDisable (GL_LIGHTING); glDisable (GL_NORMALIZE); glDisable (GL_ALPHA_TEST); glEnable (GL_BLEND); glEnable (GL_STENCIL_TEST); glDisable (GL_COLOR_MATERIAL); glDepthMask (GL_FALSE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LESS); glStencilFunc (GL_EQUAL, 0, ~0); glStencilOp (GL_KEEP, GL_KEEP, GL_INCR); #else glDisable (GL_TEXTURE_2D); glEnable (GL_DEPTH_TEST); glEnable (GL_CULL_FACE); glDisable (GL_LIGHTING); glDisable (GL_NORMALIZE); glDisable (GL_ALPHA_TEST); glEnable (GL_BLEND); glDisable (GL_STENCIL_TEST); glDisable (GL_COLOR_MATERIAL); glDepthMask (GL_TRUE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LESS); #endif break; case TRACK_MARKS: glEnable (GL_TEXTURE_2D); glEnable (GL_DEPTH_TEST); glDisable (GL_CULL_FACE); glEnable (GL_LIGHTING); glDisable (GL_NORMALIZE); glDisable (GL_ALPHA_TEST); glEnable (GL_BLEND); glDisable (GL_STENCIL_TEST); glDisable (GL_COLOR_MATERIAL); glDisable (GL_TEXTURE_GEN_S); glDisable (GL_TEXTURE_GEN_T); glDepthMask (GL_FALSE); glShadeModel (GL_SMOOTH); glDepthFunc (GL_LEQUAL); break; default: Message ("not a valid render mode", ""); } }
void e_beginpass(e_device_t* device,unsigned int pass) { glPushAttrib(GL_ENABLE_BIT|GL_STENCIL_BUFFER_BIT|GL_POLYGON_BIT); switch(pass) { case E_RENDER_MESHES: glBindProgramARB(GL_VERTEX_PROGRAM_ARB,e_programids[E_PROGRAM_PASSTOFRAGMENT]); glEnable(GL_VERTEX_PROGRAM_ARB); glEnable(GL_FRAGMENT_PROGRAM_ARB); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); break; case E_RENDER_SHADOWS: //The support of this extension depends on the 3D card if(glActiveStencilFaceEXT) { glActiveStencilFaceEXT(GL_BACK); glStencilOp(GL_KEEP,GL_INCR_WRAP_EXT,GL_KEEP); glActiveStencilFaceEXT(GL_FRONT); glStencilOp(GL_KEEP,GL_DECR_WRAP_EXT,GL_KEEP); glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); } else glEnable(GL_CULL_FACE); glBindProgramARB(GL_VERTEX_PROGRAM_ARB,e_programids[E_PROGRAM_SHADOW]); glEnable(GL_VERTEX_PROGRAM_ARB); glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); glDepthMask(GL_FALSE); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS,0,~0); glEnable(GL_DEPTH_TEST); break; case E_RENDER_SHADING: glBindProgramARB(GL_VERTEX_PROGRAM_ARB,e_programids[E_PROGRAM_PASSTOFRAGMENT]); glEnable(GL_VERTEX_PROGRAM_ARB); glEnable(GL_FRAGMENT_PROGRAM_ARB); glBlendFunc(GL_ONE,GL_ONE); glEnable(GL_BLEND); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_EQUAL,0,~0); glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); glDepthFunc(GL_LEQUAL); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); break; case E_RENDER_OUTLINES: glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); #ifdef E_OUTLINES_SMOOTH glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); #endif glLineWidth(E_OUTLINES_WIDTH); glPolygonOffset(1.0f,1.0f); glEnable(GL_POLYGON_OFFSET_LINE); glColor3ub(0,0,0); glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glEnable(GL_DEPTH_TEST); break; } }
void drawCam(Player *p, PlayerVisual* pV) { int i; float up[3] = { 0, 0, 1 }; Visual *d = & pV->display; float reflectivity = getReflectivity(); // compute shadow color based on glocal constant & reflectivity for(i = 0; i < 4; i++) gCurrentShadowColor[i] = gShadowColor[i] * (1 - reflectivity); glColor3f(0.0, 1.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); doPerspective(gSettingsCache.fov, (float) d->vp_w / (float) d->vp_h, gSettingsCache.znear, box2_Diameter(& game2->level->boundingBox) * 6.5f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); doLookAt(p->camera->cam, p->camera->target, up); glDisable(GL_LIGHTING); // initial config at frame start glDisable(GL_BLEND); // initial config at frame start // disable writes to alpha glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); /* skybox */ glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); drawSkybox( box2_Diameter( & game2->level->boundingBox ) * 2.5f ); glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); /* skybox done */ /* floor */ if(reflectivity == 0) { // draw floor to fb and stencil (set to 1), // using alpha-blending // TODO: draw floor alpha to fb video_Shader_Setup(& gWorld->floor_shader); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilFunc(GL_ALWAYS, 1, 255); glEnable(GL_STENCIL_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); nebu_Mesh_DrawGeometry( gWorld->floor ); glDisable(GL_BLEND); glDisable(GL_STENCIL_TEST); video_Shader_Cleanup(& gWorld->floor_shader); } else { /* reflections */ /* first draw reflector to stencil */ /* and reflector alpha to fb */ video_Shader_Setup(& gWorld->floor_shader); // store only reflector alpha in framebuffer glDepthMask(GL_FALSE); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilFunc(GL_ALWAYS, 1, 255); glEnable(GL_STENCIL_TEST); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); // glEnable(GL_ALPHA_TEST); // glAlphaFunc(GL_GREATER, 0.1f); nebu_Mesh_DrawGeometry( gWorld->floor ); // glDisable(GL_ALPHA_TEST); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_TRUE); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, 1, 255); video_Shader_Cleanup(& gWorld->floor_shader); /* then draw world & skybox reflected, where stencil is set */ /* protect the alpha buffer */ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); isRenderingReflection = 1; // hack: reverse lighting glPushMatrix(); glScalef(1,1,-1); glCullFace(GL_FRONT); // reverse culling // clip skybox & world to floor plane glEnable(GL_CLIP_PLANE0); { double plane[] = { 0, 0, 1, 0 }; glClipPlane(GL_CLIP_PLANE0, plane); } drawSkybox( box2_Diameter( & game2->level->boundingBox ) * 2.5f ); drawWorld(p, pV); glDisable(GL_CLIP_PLANE0); glCullFace(GL_BACK); glPopMatrix(); isRenderingReflection = 0; // hack: normal lighting /* then blend the skybox into the scene, where stencil is set */ /* modulate with the destination alpha */ glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA); drawSkybox( box2_Diameter( & game2->level->boundingBox ) * 2.5f ); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); /* then blend reflector into the scene */ glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(1, 1, 1, 1 - reflectivity); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_ALWAYS, 1, 255); video_Shader_Setup(& gWorld->floor_shader); nebu_Mesh_DrawGeometry( gWorld->floor ); video_Shader_Cleanup(& gWorld->floor_shader); glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); } /* floor done */ /* planar shadows */ glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); if(reflectivity != 1) // there are no shadows on perfect mirrors drawPlanarShadows(p); glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); /* planar shadows done */ drawWorld(p, pV); /* transparent stuff */ /* draw the glow around the other players: */ if (gSettingsCache.show_glow == 1) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for (i = 0; i < game->players; i++) { if (p != game->player + i && PLAYER_IS_ACTIVE(game->player + i)) { drawGlow(p->camera, game->player + i, gPlayerVisuals + i, d, TRAIL_HEIGHT * 4); } } glDisable(GL_BLEND); } }
// // Draw the reachable SHADED terrain glide amoeba // This is not the outlined perimeter // void MapWindow::DrawTerrainAbove(LKSurface& Surface, const RECT& rc) { // Lets try to make it better understandable with a goto. // If CAR or GA users dont want amoeba, they should disable it in config. // Otherwise we should paint it, not hide it automatically! // Here are the conditions we print this amoeba, otherwise we return; // First is we are in SIM mode and we changed the altitude; if (SIMMODE && DerivedDrawInfo.AltitudeAGL>100) goto _doit; // Second, if we are flying if (DerivedDrawInfo.Flying) goto _doit; return; _doit: #ifndef ENABLE_OPENGL LKColor whitecolor = LKColor(0xff,0xff,0xff); LKColor graycolor = LKColor(0xf0,0xf0,0xf0); LKColor origcolor = TempSurface.SetTextColor(whitecolor); TempSurface.SetBackgroundTransparent(); TempSurface.SetBkColor(whitecolor); TempSurface.SelectObject(LK_WHITE_PEN); TempSurface.SetTextColor(graycolor); TempSurface.SelectObject(hAboveTerrainBrush); TempSurface.Rectangle(rc.left,rc.top,rc.right,rc.bottom); TempSurface.SelectObject(LK_WHITE_PEN); TempSurface.SelectObject(LKBrush_White); TempSurface.Polygon(Groundline,NUMTERRAINSWEEPS+1); // need to do this to prevent drawing of colored outline TempSurface.SelectObject(LK_WHITE_PEN); #ifdef HAVE_HATCHED_BRUSH Surface.TransparentCopy( rc.left,rc.top, rc.right-rc.left,rc.bottom-rc.top, TempSurface, rc.left,rc.top); #else Surface.AlphaBlendNotWhite(rc, TempSurface, rc, 255/2); #endif // restore original color TempSurface.SetTextColor(origcolor); TempSurface.SetBackgroundOpaque(); #else Canvas& canvas = Surface; const GLEnable<GL_STENCIL_TEST> stencil; glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthMask(GL_FALSE); glStencilFunc(GL_NEVER, 1, 0xFF); glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); // draw 1s on test fail (always) // draw stencil pattern glStencilMask(0xFF); glClear(GL_STENCIL_BUFFER_BIT); // needs mask=0xFF canvas.DrawPolygon(Groundline,NUMTERRAINSWEEPS+1); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_TRUE); glStencilMask(0x00); // draw where stencil's value is 0 glStencilFunc(GL_EQUAL, 0, 0xFF); canvas.DrawFilledRectangle(rc.left,rc.top,rc.right,rc.bottom, AboveTerrainColor); #endif }
void ClippingNode::onBeforeVisit() { /////////////////////////////////// // INIT // increment the current layer s_layer++; // mask of the current layer (ie: for layer 3: 00000100) GLint mask_layer = 0x1 << s_layer; // mask of all layers less than the current (ie: for layer 3: 00000011) GLint mask_layer_l = mask_layer - 1; // mask of all layers less than or equal to the current (ie: for layer 3: 00000111) _mask_layer_le = mask_layer | mask_layer_l; // manually save the stencil state _currentStencilEnabled = glIsEnabled(GL_STENCIL_TEST); glGetIntegerv(GL_STENCIL_WRITEMASK, (GLint *)&_currentStencilWriteMask); glGetIntegerv(GL_STENCIL_FUNC, (GLint *)&_currentStencilFunc); glGetIntegerv(GL_STENCIL_REF, &_currentStencilRef); glGetIntegerv(GL_STENCIL_VALUE_MASK, (GLint *)&_currentStencilValueMask); glGetIntegerv(GL_STENCIL_FAIL, (GLint *)&_currentStencilFail); glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, (GLint *)&_currentStencilPassDepthFail); glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, (GLint *)&_currentStencilPassDepthPass); // enable stencil use glEnable(GL_STENCIL_TEST); // check for OpenGL error while enabling stencil test CHECK_GL_ERROR_DEBUG(); // all bits on the stencil buffer are readonly, except the current layer bit, // this means that operation like glClear or glStencilOp will be masked with this value glStencilMask(mask_layer); // manually save the depth test state glGetBooleanv(GL_DEPTH_WRITEMASK, &_currentDepthWriteMask); // disable depth test while drawing the stencil //glDisable(GL_DEPTH_TEST); // disable update to the depth buffer while drawing the stencil, // as the stencil is not meant to be rendered in the real scene, // it should never prevent something else to be drawn, // only disabling depth buffer update should do glDepthMask(GL_FALSE); /////////////////////////////////// // CLEAR STENCIL BUFFER // manually clear the stencil buffer by drawing a fullscreen rectangle on it // setup the stencil test func like this: // for each pixel in the fullscreen rectangle // never draw it into the frame buffer // if not in inverted mode: set the current layer value to 0 in the stencil buffer // if in inverted mode: set the current layer value to 1 in the stencil buffer glStencilFunc(GL_NEVER, mask_layer, mask_layer); glStencilOp(!_inverted ? GL_ZERO : GL_REPLACE, GL_KEEP, GL_KEEP); // draw a fullscreen solid rectangle to clear the stencil buffer //ccDrawSolidRect(Point::ZERO, ccpFromSize([[Director sharedDirector] winSize]), Color4F(1, 1, 1, 1)); drawFullScreenQuadClearStencil(); /////////////////////////////////// // DRAW CLIPPING STENCIL // setup the stencil test func like this: // for each pixel in the stencil node // never draw it into the frame buffer // if not in inverted mode: set the current layer value to 1 in the stencil buffer // if in inverted mode: set the current layer value to 0 in the stencil buffer glStencilFunc(GL_NEVER, mask_layer, mask_layer); glStencilOp(!_inverted ? GL_REPLACE : GL_ZERO, GL_KEEP, GL_KEEP); // enable alpha test only if the alpha threshold < 1, // indeed if alpha threshold == 1, every pixel will be drawn anyways if (_alphaThreshold < 1) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WINDOWS || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) // manually save the alpha test state _currentAlphaTestEnabled = glIsEnabled(GL_ALPHA_TEST); glGetIntegerv(GL_ALPHA_TEST_FUNC, (GLint *)&_currentAlphaTestFunc); glGetFloatv(GL_ALPHA_TEST_REF, &_currentAlphaTestRef); // enable alpha testing glEnable(GL_ALPHA_TEST); // check for OpenGL error while enabling alpha test CHECK_GL_ERROR_DEBUG(); // pixel will be drawn only if greater than an alpha threshold glAlphaFunc(GL_GREATER, _alphaThreshold); #else #endif } //Draw _stencil }
void SoGLStencilBufferElement::updategl( uint32_t updatebits ) const { if( updatebits & ENABLE ) { if (enable) { glEnable(GL_STENCIL_TEST); checkGLErrors(); } else { glDisable(GL_STENCIL_TEST); checkGLErrors(); } } if( updatebits & FUNC ) { GLint glref = ref; GLuint glmask = mask; switch(func) { case NEVER: glStencilFunc( GL_NEVER, glref, glmask ); break; case LESS: glStencilFunc( GL_LESS, glref, glmask ); break; case LEQUAL: glStencilFunc( GL_LEQUAL, glref, glmask ); break; case GREATER: glStencilFunc( GL_GREATER, glref, glmask ); break; case GEQUAL: glStencilFunc( GL_GEQUAL, glref, glmask ); break; case EQUAL: glStencilFunc( GL_EQUAL, glref, glmask ); break; case NOTEQUAL: glStencilFunc( GL_NOTEQUAL, glref, glmask ); break; case ALWAYS: glStencilFunc( GL_ALWAYS, glref, glmask ); break; default: assert(NULL && "SoGLStencilBufferElement undefined stencil function!"); } checkGLErrors(); } if( updatebits & MASK ) { glStencilMask( bits ); checkGLErrors(); } if ( updatebits & OP) { static const GLenum functions[6] = { GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT }; GLenum glfail = functions[fail]; GLenum glzfail = functions[zfail]; GLenum glzpass = functions[zpass]; glStencilOp( glfail, glzfail, glzpass ); checkGLErrors(); } }
void LLDrawPoolWater::render(S32 pass) { LLFastTimer ftm(LLFastTimer::FTM_RENDER_WATER); if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1) { return; } //do a quick 'n dirty depth sort for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { LLFace* facep = *iter; facep->mDistance = -facep->mCenterLocal.mV[2]; } std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater()); static const LLCachedControl<bool> render_transparent_water("RenderTransparentWater",false); if(!render_transparent_water) { // render water for low end hardware renderOpaqueLegacyWater(); return; } LLGLEnable blend(GL_BLEND); if ((mVertexShaderLevel > 0) && !sSkipScreenCopy) { shade(); return; } LLVOSky *voskyp = gSky.mVOSkyp; stop_glerror(); if (!gGLManager.mHasMultitexture) { // Ack! No multitexture! Bail! return; } LLFace* refl_face = voskyp->getReflFace(); gPipeline.disableLights(); LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); LLGLDisable cullFace(GL_CULL_FACE); // Set up second pass first mWaterImagep->addTextureStats(1024.f*1024.f); gGL.getTexUnit(1)->activate(); gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(1)->bind(mWaterImagep) ; LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); F32 up_dot = camera_up * LLVector3::z_axis; LLColor4 water_color; if (LLViewerCamera::getInstance()->cameraUnderWater()) { water_color.setVec(1.f, 1.f, 1.f, 0.4f); } else { water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); } glColor4fv(water_color.mV); // Automatically generate texture coords for detail map glEnable(GL_TEXTURE_GEN_S); //texture unit 1 glEnable(GL_TEXTURE_GEN_T); //texture unit 1 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); // Slowly move over time. F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f); F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f}; F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f}; glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA); gGL.getTexUnit(0)->activate(); glClearStencil(1); glClear(GL_STENCIL_BUFFER_BIT); LLGLEnable gls_stencil(GL_STENCIL_TEST); glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { LLFace *face = *iter; if (voskyp->isReflFace(face)) { continue; } gGL.getTexUnit(0)->bind(face->getTexture()); face->renderIndexed(); } // Now, disable texture coord generation on texture state 1 gGL.getTexUnit(1)->activate(); gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(1)->disable(); glDisable(GL_TEXTURE_GEN_S); //texture unit 1 glDisable(GL_TEXTURE_GEN_T); //texture unit 1 // Disable texture coordinate and color arrays gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); stop_glerror(); if (gSky.mVOSkyp->getCubeMap()) { gSky.mVOSkyp->getCubeMap()->enable(0); gSky.mVOSkyp->getCubeMap()->bind(); glMatrixMode(GL_TEXTURE); glLoadIdentity(); LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); LLMatrix4 camera_rot(camera_mat.getMat3()); camera_rot.invert(); glLoadMatrixf((F32 *)camera_rot.mMatrix); glMatrixMode(GL_MODELVIEW); LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f, 0.5f*up_dot); gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { LLFace *face = *iter; if (voskyp->isReflFace(face)) { //refl_face = face; continue; } if (face->getGeomCount() > 0) { face->renderIndexed(); } } gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); gSky.mVOSkyp->getCubeMap()->disable(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); } glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); if (refl_face) { glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); renderReflection(refl_face); } gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); }
// ********************************************************************* // render the scene void World::vrender(void) { Vec3D camPos = m_cam->getPosition(); Vec3D lookAt = m_cam->getLookAt(); gluLookAt(camPos[0], camPos[1], camPos[2], lookAt[0], lookAt[1], lookAt[2], 0.0f, 1.0f, 0.0f ); // draw the shadows first // used tutorial and adjusted as explained in the text (Hawkins 470). glPushMatrix(); glLightfv(GL_LIGHT0, GL_POSITION, m_lightPosition); setShadowMatrix(); // set up the stencil buffer so that we only draw the shadow // on the reflecting surface glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 3, 0xFFFFFFFF); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); m_floor->vrender(); glStencilFunc(GL_LESS, 2, 0xFFFFFFFF); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); glEnable(GL_POLYGON_OFFSET_FILL); // draw the shadow as half-blended black glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glDisable(GL_FOG); glColor4f(0.0, 0.0, 0.0, 0.5); // project the objects through the shadow matrix glMultMatrixf(m_shadowMatrix); m_dome->vrender(); m_lamp->vrender(); m_endTable->vrender(); m_torus->vrender(); m_pawn->vrender(); glDisable(GL_BLEND); glEnable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glEnable(GL_FOG); glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_STENCIL_TEST); glPopMatrix(); // now draw the real objects glPushMatrix(); glLightfv(GL_LIGHT0, GL_POSITION, m_lightPosition); glCallList(m_dList); // put in the boring walls //the floor gets drawn in the shadows section m_dome->vrender(); m_lamp->vrender(); m_endTable->vrender(); m_torus->vrender(); m_pawn->vrender(); glPopMatrix(); return; }
void OpenGLState::Apply() const { // Culling if (cull.enabled != cur_state.cull.enabled) { if (cull.enabled) { glEnable(GL_CULL_FACE); } else { glDisable(GL_CULL_FACE); } } if (cull.mode != cur_state.cull.mode) { glCullFace(cull.mode); } if (cull.front_face != cur_state.cull.front_face) { glFrontFace(cull.front_face); } // Depth test if (depth.test_enabled != cur_state.depth.test_enabled) { if (depth.test_enabled) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } } if (depth.test_func != cur_state.depth.test_func) { glDepthFunc(depth.test_func); } // Depth mask if (depth.write_mask != cur_state.depth.write_mask) { glDepthMask(depth.write_mask); } // Color mask if (color_mask.red_enabled != cur_state.color_mask.red_enabled || color_mask.green_enabled != cur_state.color_mask.green_enabled || color_mask.blue_enabled != cur_state.color_mask.blue_enabled || color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) { glColorMask(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled, color_mask.alpha_enabled); } // Stencil test if (stencil.test_enabled != cur_state.stencil.test_enabled) { if (stencil.test_enabled) { glEnable(GL_STENCIL_TEST); } else { glDisable(GL_STENCIL_TEST); } } if (stencil.test_func != cur_state.stencil.test_func || stencil.test_ref != cur_state.stencil.test_ref || stencil.test_mask != cur_state.stencil.test_mask) { glStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask); } if (stencil.action_depth_fail != cur_state.stencil.action_depth_fail || stencil.action_depth_pass != cur_state.stencil.action_depth_pass || stencil.action_stencil_fail != cur_state.stencil.action_stencil_fail) { glStencilOp(stencil.action_stencil_fail, stencil.action_depth_fail, stencil.action_depth_pass); } // Stencil mask if (stencil.write_mask != cur_state.stencil.write_mask) { glStencilMask(stencil.write_mask); } // Blending if (blend.enabled != cur_state.blend.enabled) { if (blend.enabled) { glEnable(GL_BLEND); cur_state.logic_op = GL_COPY; glLogicOp(cur_state.logic_op); glDisable(GL_COLOR_LOGIC_OP); } else { glDisable(GL_BLEND); glEnable(GL_COLOR_LOGIC_OP); } } if (blend.color.red != cur_state.blend.color.red || blend.color.green != cur_state.blend.color.green || blend.color.blue != cur_state.blend.color.blue || blend.color.alpha != cur_state.blend.color.alpha) { glBlendColor(blend.color.red, blend.color.green, blend.color.blue, blend.color.alpha); } if (blend.src_rgb_func != cur_state.blend.src_rgb_func || blend.dst_rgb_func != cur_state.blend.dst_rgb_func || blend.src_a_func != cur_state.blend.src_a_func || blend.dst_a_func != cur_state.blend.dst_a_func) { glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func); } if (blend.rgb_equation != cur_state.blend.rgb_equation || blend.a_equation != cur_state.blend.a_equation) { glBlendEquationSeparate(blend.rgb_equation, blend.a_equation); } if (logic_op != cur_state.logic_op) { glLogicOp(logic_op); } // Textures for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) { if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d); } if (texture_units[i].sampler != cur_state.texture_units[i].sampler) { glBindSampler(i, texture_units[i].sampler); } } // Lighting LUTs for (unsigned i = 0; i < ARRAY_SIZE(lighting_luts); ++i) { if (lighting_luts[i].texture_1d != cur_state.lighting_luts[i].texture_1d) { glActiveTexture(GL_TEXTURE3 + i); glBindTexture(GL_TEXTURE_1D, lighting_luts[i].texture_1d); } } // Fog LUT if (fog_lut.texture_1d != cur_state.fog_lut.texture_1d) { glActiveTexture(GL_TEXTURE9); glBindTexture(GL_TEXTURE_1D, fog_lut.texture_1d); } // Framebuffer if (draw.read_framebuffer != cur_state.draw.read_framebuffer) { glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); } if (draw.draw_framebuffer != cur_state.draw.draw_framebuffer) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw.draw_framebuffer); } // Vertex array if (draw.vertex_array != cur_state.draw.vertex_array) { glBindVertexArray(draw.vertex_array); } // Vertex buffer if (draw.vertex_buffer != cur_state.draw.vertex_buffer) { glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer); } // Uniform buffer if (draw.uniform_buffer != cur_state.draw.uniform_buffer) { glBindBuffer(GL_UNIFORM_BUFFER, draw.uniform_buffer); } // Shader program if (draw.shader_program != cur_state.draw.shader_program) { glUseProgram(draw.shader_program); } cur_state = *this; }
static void draw_edges(void) { /* * render the offset depth image */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); #ifdef GL_POLYGON_OFFSET_FILL glPolygonOffset(4.0, 1.0); #else /* XXX should change to use glPolygonOffset in OpenGL 1.1 */ glPolygonOffsetEXT(4.0, (1.0 / (1 << 22))); #endif glEnable(GL_POLYGON_OFFSET_FILL); /* glColorMask(0,0,0,0); */ glCallList(1); /* glColorMask(1,1,1,1); */ glDisable(GL_POLYGON_OFFSET_FILL); /* * make no further changes to the depth image */ glDepthMask(0); glDisable(GL_DEPTH_TEST); /* XXX */ glEnable(GL_DEPTH_TEST); /* XXX */ /* * cull all facets of one (arbitrary) orientation. render the * remaining facets in outline mode, toggling the stencil bit * at each pixel. */ glDisable(GL_LIGHTING); glColor3f(0.f, 0.f, 0.f); glLineWidth(2.0); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 0, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); glEnable(GL_CULL_FACE); glColorMask(0, 0, 0, 0); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glCallList(1); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glColorMask(1, 1, 1, 1); glDisable(GL_CULL_FACE); /* * color all pixels in the framebuffer with stencil value 1 */ glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); glColor3f(0, 0, 0); fill_window(); glDisable(GL_STENCIL_TEST); /* * draw all true edges, testing against the depth image */ glColor3f(0, 0, 0); glCallList(2); /* * return state to default values */ glDepthMask(1); glDisable(GL_DEPTH_TEST); /* XXX */ glEnable(GL_DEPTH_TEST); /* XXX */ if (lighting) glEnable(GL_LIGHTING); glLineWidth(1.0); glColor3f(1.f, 1.f, 1.f); }
void Robot::applyShadow(GLfloat rows, GLfloat columns) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glDisable(GL_LIGHTING); if (calculateAlpha(0, 0, rows, columns) >=0) { glPushMatrix(); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_EQUAL, 10, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); glTranslatef(xPos, 0.02f, zPos); TextureManager::getInstance()->toggleTextures(); shadowMatrix(0-xPos, 12, 0-zPos, 1.0f); glColor4f(0.0, 0.0, 0.0, calculateAlpha(0, 0, rows, columns)); model->draw(); //draw(); TextureManager::getInstance()->toggleTextures(); glDisable(GL_STENCIL_TEST); glPopMatrix(); } if (calculateAlpha(0, rows, rows, columns) >=0) { glPushMatrix(); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_EQUAL, 10, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); glTranslatef(xPos, 0.02f, zPos); TextureManager::getInstance()->toggleTextures(); shadowMatrix(0-xPos, 12, rows-zPos, 1.0f); glColor4f(0.0, 0.0, 0.0, calculateAlpha(0, rows, rows, columns)); model->draw(); //draw(); TextureManager::getInstance()->toggleTextures(); glDisable(GL_STENCIL_TEST); glPopMatrix(); } if (calculateAlpha(columns, 0, rows, columns) >=0) { glPushMatrix(); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_EQUAL, 10, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); glTranslatef(xPos, 0.02f, zPos); TextureManager::getInstance()->toggleTextures(); shadowMatrix(columns-xPos, 12, 0-zPos, 1.0f); glColor4f(0.0, 0.0, 0.0, calculateAlpha(columns, 0, rows, columns)); model->draw(); //draw(); TextureManager::getInstance()->toggleTextures(); glDisable(GL_STENCIL_TEST); glPopMatrix(); } if (calculateAlpha(columns, rows, rows, columns) >=0) { glPushMatrix(); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_EQUAL, 10, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); glTranslatef(xPos, 0.02f, zPos); TextureManager::getInstance()->toggleTextures(); shadowMatrix(columns-xPos, 12, rows-zPos, 1.0f); glColor4f(0.0, 0.0, 0.0, calculateAlpha(columns, rows, rows, columns)); model->draw(); //draw(); TextureManager::getInstance()->toggleTextures(); glDisable(GL_STENCIL_TEST); glPopMatrix(); } //} //glDisable(GL_TEXTURE_2D); //glDisable(GL_STENCIL_TEST); // glPopMatrix(); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); glEnable(GL_LIGHTING); //glEnable(GL_COLOR_MATERIAL); //} }