Path: blob/main_old/samples/stencil_operations/StencilOperations.cpp
2573 views
//1// Copyright 2014 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// Based on Stencil_Test.c from7// Book: OpenGL(R) ES 2.0 Programming Guide8// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner9// ISBN-10: 032150279510// ISBN-13: 978032150279711// Publisher: Addison-Wesley Professional12// URLs: http://safari.informit.com/978032156383513// http://www.opengles-book.com1415#include "SampleApplication.h"1617#include "util/shader_utils.h"1819class StencilOperationsSample : public SampleApplication20{21public:22StencilOperationsSample(int argc, char **argv)23: SampleApplication("StencilOperations", argc, argv)24{}2526bool initialize() override27{28constexpr char kVS[] = R"(attribute vec4 a_position;29void main()30{31gl_Position = a_position;32})";3334constexpr char kFS[] = R"(precision mediump float;35uniform vec4 u_color;36void main()37{38gl_FragColor = u_color;39})";4041mProgram = CompileProgram(kVS, kFS);42if (!mProgram)43{44return false;45}4647// Get the attribute locations48mPositionLoc = glGetAttribLocation(mProgram, "a_position");4950// Get the sampler location51mColorLoc = glGetUniformLocation(mProgram, "u_color");5253// Set the clear color54glClearColor(0.0f, 0.0f, 0.0f, 0.0f);5556// Set the stencil clear value57glClearStencil(0x01);5859// Set the depth clear value60glClearDepthf(0.75f);6162// Enable the depth and stencil tests63glEnable(GL_DEPTH_TEST);64glEnable(GL_STENCIL_TEST);6566return true;67}6869void destroy() override { glDeleteProgram(mProgram); }7071void draw() override72{73GLfloat vertices[] = {74-0.75f, 0.25f, 0.50f, // Quad #075-0.25f, 0.25f, 0.50f, -0.25f, 0.75f, 0.50f, -0.75f, 0.75f, 0.50f,760.25f, 0.25f, 0.90f, // Quad #1770.75f, 0.25f, 0.90f, 0.75f, 0.75f, 0.90f, 0.25f, 0.75f, 0.90f,78-0.75f, -0.75f, 0.50f, // Quad #279-0.25f, -0.75f, 0.50f, -0.25f, -0.25f, 0.50f, -0.75f, -0.25f, 0.50f,800.25f, -0.75f, 0.50f, // Quad #3810.75f, -0.75f, 0.50f, 0.75f, -0.25f, 0.50f, 0.25f, -0.25f, 0.50f,82-1.00f, -1.00f, 0.00f, // Big Quad831.00f, -1.00f, 0.00f, 1.00f, 1.00f, 0.00f, -1.00f, 1.00f, 0.00f,84};8586GLubyte indices[][6] = {87{0, 1, 2, 0, 2, 3}, // Quad #088{4, 5, 6, 4, 6, 7}, // Quad #189{8, 9, 10, 8, 10, 11}, // Quad #290{12, 13, 14, 12, 14, 15}, // Quad #391{16, 17, 18, 16, 18, 19}, // Big Quad92};9394static const size_t testCount = 4;95GLfloat colors[testCount][4] = {96{1.0f, 0.0f, 0.0f, 1.0f},97{0.0f, 1.0f, 0.0f, 1.0f},98{0.0f, 0.0f, 1.0f, 1.0f},99{1.0f, 1.0f, 0.0f, 0.0f},100};101102GLuint stencilValues[testCount] = {1030x7, // Result of test 01040x0, // Result of test 11050x2, // Result of test 21060xff // Result of test 3. We need to fill this value in at run-time107};108109// Set the viewport110glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());111112// Clear the color, depth, and stencil buffers. At this point, the stencil113// buffer will be 0x1 for all pixels114glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);115116// Use the program object117glUseProgram(mProgram);118119// Load the vertex data120glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, vertices);121glEnableVertexAttribArray(mPositionLoc);122123// Test 0:124//125// Initialize upper-left region. In this case, the stencil-buffer values will126// be replaced because the stencil test for the rendered pixels will fail the127// stencil test, which is128//129// ref mask stencil mask130// ( 0x7 & 0x3 ) < ( 0x1 & 0x7 )131//132// The value in the stencil buffer for these pixels will be 0x7.133glStencilFunc(GL_LESS, 0x7, 0x3);134glStencilOp(GL_REPLACE, GL_DECR, GL_DECR);135glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[0]);136137// Test 1:138//139// Initialize the upper-right region. Here, we'll decrement the stencil-buffer140// values where the stencil test passes but the depth test fails. The stencil test is141//142// ref mask stencil mask143// ( 0x3 & 0x3 ) > ( 0x1 & 0x3 )144//145// but where the geometry fails the depth test. The stencil values for these pixels146// will be 0x0.147glStencilFunc(GL_GREATER, 0x3, 0x3);148glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);149glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[1]);150151// Test 2:152//153// Initialize the lower-left region. Here we'll increment (with saturation) the154// stencil value where both the stencil and depth tests pass. The stencil test for155// these pixels will be156//157// ref mask stencil mask158// ( 0x1 & 0x3 ) == ( 0x1 & 0x3 )159//160// The stencil values for these pixels will be 0x2.161glStencilFunc(GL_EQUAL, 0x1, 0x3);162glStencilOp(GL_KEEP, GL_INCR, GL_INCR);163glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[2]);164165// Test 3:166//167// Finally, initialize the lower-right region. We'll invert the stencil value168// where the stencil tests fails. The stencil test for these pixels will be169//170// ref mask stencil mask171// ( 0x2 & 0x1 ) == ( 0x1 & 0x1 )172//173// The stencil value here will be set to ~((2^s-1) & 0x1), (with the 0x1 being174// from the stencil clear value), where 's' is the number of bits in the stencil175// buffer176glStencilFunc(GL_EQUAL, 0x2, 0x1);177glStencilOp(GL_INVERT, GL_KEEP, GL_KEEP);178glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[3]);179180// Since we don't know at compile time how many stencil bits are present, we'll181// query, and update the value correct value in the stencilValues arrays for the182// fourth tests. We'll use this value later in rendering.183GLint stencilBitCount = 0;184glGetIntegerv(GL_STENCIL_BITS, &stencilBitCount);185stencilValues[3] = ~(((1 << stencilBitCount) - 1) & 0x1) & 0xff;186187// Use the stencil buffer for controlling where rendering will occur. We disable188// writing to the stencil buffer so we can test against them without modifying189// the values we generated.190glStencilMask(0x0);191192for (size_t i = 0; i < testCount; ++i)193{194glStencilFunc(GL_EQUAL, stencilValues[i], 0xff);195glUniform4fv(mColorLoc, 1, colors[i]);196glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices[4]);197}198199// Reset the stencil mask200glStencilMask(0xFF);201}202203private:204// Handle to a program object205GLuint mProgram;206207// Attribute locations208GLint mPositionLoc;209210// Uniform locations211GLint mColorLoc;212};213214int main(int argc, char **argv)215{216StencilOperationsSample app(argc, argv);217return app.run();218}219220221