ওপেনজিএল ইএস টেক্সচার ব্যবহার করে স্টেনসিল এফেক্ট তৈরি করে


10

পরিবেশ

এই পরিবেশে আমি কাজ করছি:

  • ওপেনজিএল ইএস ২.০
  • আইফোন সিমুলেটর এবং আইফোন 4
  • আইএম্যাক 27 "এনভিআইডিআইএ জিফর্স জিটিএক্স 680 এমএক্স 2048 এমবি ব্যবহার করে

আশা করি এইটি কাজ করবে.

সমস্যাটি

স্ট্যাকওভারফ্লো সহ একাধিক উত্স এবং একাধিক সাইটগুলি থেকে উচ্চ এবং নিম্ন সন্ধান করা হয়েছে তবে কার্যকর কোনও স্টেনসিল প্রভাব পাওয়া যায় নি।

আমার যা আছে তা হ'ল:

স্টেনসিল দৃশ্যের সেটআপ

কালো 'এস' জিনিসটি বহুভুজ নয় বরং একটি আয়তক্ষেত্রের চতুর্দিকে আঁকা একটি টেক্সচার যা পটভূমির চিত্রের মতো একই প্রস্থ এবং উচ্চতা।

আমি একটি স্টেনসিল এফেক্ট করার চেষ্টা করছি যেখানে সেই কালো 'এস' টেক্সচারের মধ্যেই ব্যাকগ্রাউন্ড এবং ছোট হলুদ লোকটি কেবল দৃশ্যমান হওয়া উচিত।

আমার টুকরো টুকরো টুকরো টুকরো শব্দটি

varying lowp vec4 destinationColor;

varying lowp vec2 TexCoordOut;
uniform sampler2D Texture;
uniform highp float TexScale;

void main()
{
    highp vec4 color = texture2D(Texture, TexCoordOut);

    if(color.a == 0.0)
    {
        discard;
    }

    gl_FragColor = color;
}

আমার সেটআপ ডেপথ স্টেনসিল বাফারের জন্য, আমি এটি এটি সেট আপ করেছি:

-(void)setupDepthStencilBuffer
{
    GLint width;
    GLint height;

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);

    glGenBuffers(1, &depthStencilBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, depthStencilBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
    //glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_COMPONENT24_OES, width, height);

    NSLog(@"depthStencilBuffer = %d", depthStencilBuffer);
}

অ্যাপলের ডকুমেন্টেশন অনুসারে (যা আমার মনে হয় পুরানো)

http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html#//apple_ref/doc/uid/TP40008793-CH103-SW1

জ্যাক_আরজিবিএ এনামের মতো কিছু জিনিস যখন আমি এক্সকোডে টাইপ করার চেষ্টা করেছি তখন তার অস্তিত্ব নেই (আমি মনে করি অ্যাপল অবশ্যই এটি অপসারণ করে এটিকে অপ্রচলিত করে তুলেছে)।

উপরের লিঙ্কে তথাকথিত "গভীরতা / স্টেনসিল" বাফারটি সংজ্ঞায়িত করার জন্য আমি অ্যাপলের উপায়ও চেষ্টা করেছি তবে এটি নীচে একই ত্রুটি দিয়েছে।

আমার উপরে কোডটি হ'ল আপনি কীভাবে স্টেনসিল বাফার তৈরি করবেন।

আমার সেটআপফ্রেমবফার () পদ্ধতিতে, আমি এটি এর মতো সংযুক্ত করি:

-(void)setupFrameBuffer
{
    GLuint frameBuffer;

    glGenBuffers(1, &frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilBuffer);

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

    if(status != GL_FRAMEBUFFER_COMPLETE)
    {
        NSLog(@"failed to make complete framebuffer object %x", status);
    }
}

উপরের মতো এটি সংযুক্ত করার সময় আমার যে ত্রুটি হয়েছিল তা হ'ল:

সম্পূর্ণ ফ্রেমবফার অবজেক্ট 8cd6 তৈরি করতে ব্যর্থ

আমার রেন্ডার পদ্ধতির জন্য, আমার এটি রয়েছে:

-(void)render:(CADisplayLink *)displayLink
{
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);



    glClearStencil(0);
    glEnable(GL_STENCIL_TEST);

    // ----------------------------------------
    // Don't write to color or depth buffer
    // ----------------------------------------
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glDepthMask(GL_FALSE);

    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

    // ----------------------------------------
    // First set the alpha test so that
    // fragments greather than threshold
    // will pass thus will set nonzero
    // bits masked by 1 in stencil
    // ----------------------------------------
    glStencilFunc(GL_ALWAYS, 1, 1);

    // ----------------------------------------------------------------
    // Drawing our stencil
    // ----------------------------------------------------------------

    glBindBuffer(GL_ARRAY_BUFFER, bgVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bgIBO);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, stencilTexture);
    glUniform1i(textureUniform, 0);

    glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
    glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void *)(sizeof(GLfloat) * 3));
    glVertexAttribPointer(texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void *)(sizeof(GLfloat) * 7));

    glDrawElements(GL_TRIANGLE_FAN, sizeof(bgIndices)/sizeof(bgIndices[0]), GL_UNSIGNED_BYTE, 0);

    /*
    // -----------------------------------------
    // Second pass of the fragments less
    // or equal than the threshold will pass
    // thus will set zero bits masked by 1
    // in stencil
    // -----------------------------------------
    glStencilFunc(GL_ALWAYS, 0, 1);

    glBindBuffer(GL_ARRAY_BUFFER, bgVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bgIBO);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, stencilTexture);
    glUniform1i(textureUniform, 0);

    glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
    glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void *)(sizeof(GLfloat) * 3));
    glVertexAttribPointer(texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void *)(sizeof(GLfloat) * 7));

    glDrawElements(GL_TRIANGLE_STRIP, sizeof(bgIndices)/sizeof(bgIndices[0]), GL_UNSIGNED_BYTE, 0);
    */


    // ---------------------------------------------------
    // RE-ENABLING THE COLOR AND DEPTH MASK AGAIN
    // TO DRAW REST OF THE SCENE AFTER STENCIL
    // ---------------------------------------------------
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glDepthMask(GL_TRUE);




    Mat4 frustrumMatrix = [CameraMatrix createOrthographicMatrixUsingLeft:-(self.bounds.size.width / 2.0)
                                                                       Right:(self.bounds.size.width / 2.0)
                                                                      Bottom:-(self.bounds.size.height / 2.0)
                                                                         Top:(self.bounds.size.height / 2.0)
                                                                        Near:-1.0f
                                                                         Far:1.0f];

    glUniformMatrix4fv(projectionUniform, 1, 0, frustrumMatrix.matrix);

    glViewport(0, 0, self.bounds.size.width * self.contentScaleFactor, self.bounds.size.height * self.contentScaleFactor);

    // ----------------------------------------------------------------
    // Drawing our background first
    // ----------------------------------------------------------------

    glBindBuffer(GL_ARRAY_BUFFER, bgVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bgIBO);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, bgTexture);
    glUniform1i(textureUniform, 0);

    glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
    glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void *)(sizeof(GLfloat) * 3));
    glVertexAttribPointer(texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void *)(sizeof(GLfloat) * 7));

    glDrawElements(GL_TRIANGLE_FAN, sizeof(bgIndices)/sizeof(bgIndices[0]), GL_UNSIGNED_BYTE, 0);



    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);


    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, floorTexture);
    glUniform1i(textureUniform, 0);


    glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
    glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void *)(sizeof(GLfloat) * 3));

    glVertexAttribPointer(texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void *)(sizeof(GLfloat) * 7));

    glDrawElements(GL_TRIANGLE_FAN, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

    [context presentRenderbuffer:GL_RENDERBUFFER];
}

এর ফলাফলটি অবশ্যই গোলাপী পর্দা যার মানে আমার সেটআপটি ভুল:

এখানে চিত্র বর্ণনা লিখুন

কেউ কেউ কিছু আলোকপাত করতে পারছেন দয়া করে?


সঠিক সমস্যাটি কীভাবে সমাধান করবেন সে সম্পর্কে কোনও ধারণা নেই, তবে কেন সামান্য হলুদ লোক আঁকার সময় কেবল "স্টেনসিল টেক্সচার" ব্যবহার করবেন না, এবং যদি টেক্সেলের মানটি মেলে না তবে তা বাতিল করবেন?
জারি কম্প্পা

স্টেনসিলটি ছোট লোককে মাস্ক করার জন্য নয়, ছোট্ট লোকটি যে অঞ্চলটি দাঁড়িয়েছে (এটি আপনি উপরে যে পটভূমির চিত্র দেখছেন না) সেই অঞ্চলটি সনাক্ত করার জন্য এটি ব্যবহার করার জন্য খুব আগ্রহজনক। কীট গেমের কথা চিন্তা করুন, আপনি ব্যাকগ্রাউন্ড পেয়েছেন, তারপরে আপনি এই ভূখণ্ডটি মাঝখানে পেয়েছেন, যা অঞ্চলটিকে মুছে ফেলতে এবং পর্দার খেলোয়াড়দের (সংক্ষিপ্ত হলুদ লোক) সংঘর্ষ সনাক্ত করার জন্য স্টেনসিল দ্বারা মুখোশযুক্ত।
ঝাং

উত্তর:


7

সমাধান

হ্যাঁ হ্যা !!!

আমি এখন একটি সুখী চ্যাপ! : ডি

ঠিক আছে, আমি শেষ পর্যন্ত স্টেনসিল টেক্সচারের সাথে কাজ করার জন্য পরিচালনা করি :)

(সেই সাথে বেশ কয়েকটি জিনিস শিখেছি, যেমন আমরা রঙ.এলফা চেক করতে পারি এবং স্বচ্ছ পিক্সেল এবং GLBlend (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) মুছে ফেলার উপায় হিসাবে বাতিল ব্যবহার করতে পারি) ট্রিকটি অপ্রচলিত হয়ে যায়)

সুতরাং আমি যে বিষয়টি প্রথম লক্ষ্য করেছি আমি ভুল করেছিলাম তা আমার স্টেনসিল বাফারের জন্য ভুলভাবে নাম তৈরি করা হয়েছিল।

আমার প্রশ্নের উপরের উত্স কোডটিতে, আমি টাইপ করেছি:

glGenBuffers(1, &depthStencilBuffer);

এটি সত্যই হওয়া উচিত:

glGenRenderbuffers(1, &depthStencilBuffer);

d'আহা!

সর্বোপরি, আমি গুরুত্বপূর্ণ দ্বিতীয় glStencilFunc () বলা প্রয়োজন যে মন্তব্য:

glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

// draw black 'S' textured quad here

. . .

// -----------------------------------
// I WAS MISSING THIS IMPORTANT LINE
// -----------------------------------
glStencilFunc(GL_ALWAYS, 0, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

/* draw the rest of the scene here (the background and yellow guy) */

চূড়ান্ত ফলাফল:

এখানে চিত্র বর্ণনা লিখুন

আশা করি এটি এই টেক্সচার বৈশিষ্ট্যের সাহায্যে যারা এই শীতল স্টেনসিলটি চেষ্টা করছেন তাদের প্রত্যেককে সহায়তা করবে: ডি

আমি বেশ কয়েকটি অন্যান্য উত্স কোডও সংশোধন করেছিলাম কিন্তু এই দুটি এটিই মূল পরিবর্তন ছিল যা এটি কাজ করে।

কিছু সহায়ক পরিবর্তন আমাকে সমস্যার ডিবাগ করতেও সহায়তা করেছিল:

  • আমি খুঁজে পেয়েছি যে এটি আমার কাজ করতে আমার ফ্রেমবফারের সাথে গভীরতার বাফার লাগানোর দরকার নেই
  • আমারও GL_DEPTH_BUFFER_BIT সাফ করার দরকার নেই
  • আমি অতিরিক্ত সেট-আপ শর্তাদি আমাকে সম্ভাব্য ত্রুটিগুলি পরিষ্কারভাবে নির্দেশ করার জন্য সেটআপফ্রেমবফার () পদ্ধতিটি এটিকে পরিবর্তিত করেছি।

নতুন সেটআপফ্রেমবফার () পদ্ধতি:

-(void)setupFrameBuffer
{
    GLuint frameBuffer;

    glGenBuffers(1, &frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderBuffer);
    //glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilBuffer);

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

    if(status == GL_FRAMEBUFFER_COMPLETE)
    {
        NSLog(@"framebuffer complete");
        //NSLog(@"failed to make complete framebuffer object %x", status);
    }
    else if(status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
    {
        NSLog(@"incomplete framebuffer attachments");
    }
    else if(status == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
    {
        NSLog(@"incomplete missing framebuffer attachments");
    }
    else if(status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS)
    {
        NSLog(@"incomplete framebuffer attachments dimensions");
    }
    else if(status == GL_FRAMEBUFFER_UNSUPPORTED)
    {
        NSLog(@"combination of internal formats used by attachments in thef ramebuffer results in a nonrednerable target");
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.