ओपनजीएल / जीएलएसएल: क्यूब मैप में रेंडर?


13

मैं यह जानने की कोशिश कर रहा हूं कि मेरे दृश्य को क्यूब मैप में कैसे रेंडर किया जाए। मैं इस पर थोड़ा अटक गया हूं और लगा कि मैं आप लोगों से कुछ मदद मांगूंगा। मैं OpenGL के लिए नया हूं और यह पहली बार है जब मैं FBO का उपयोग कर रहा हूं।

वर्तमान में मेरे पास एक क्यूबैप bmp फ़ाइल का उपयोग करने का एक कार्यशील उदाहरण है, और टुकड़ा shader में samplerCube नमूना प्रकार GL_TEXTURE1 से जुड़ा हुआ है। मैं shader कोड बिल्कुल नहीं बदल रहा हूँ। मैं सिर्फ इस तथ्य को बदल रहा हूं कि मैं उस फ़ंक्शन को कॉल नहीं कर रहा हूं जो क्यूबमैप बीएमपी फ़ाइल को लोड कर रहा था और क्यूबमैप को प्रस्तुत करने के लिए नीचे दिए गए कोड का उपयोग करने की कोशिश कर रहा था।

आप नीचे देख सकते हैं कि मैं भी फिर से GL_TEXTURE1 की बनावट संलग्न कर रहा हूं। ऐसा तब है जब मैंने वर्दी सेट की है:

glUniform1i(getUniLoc(myProg, "Cubemap"), 1);

यह के माध्यम से मेरे टुकड़े shader में यह उपयोग कर सकते हैं uniform samplerCube Cubemap

मैं नीचे दिए गए फ़ंक्शन को पसंद कर रहा हूं:

cubeMapTexture = renderToCubeMap(150, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);

अब, मैं नीचे दिए गए ड्रा लूप में महसूस करता हूं कि मैं + x, -x, + y, -y, + z, -z अक्ष को देखने के लिए दृश्य दिशा नहीं बदल रहा हूं। मैं वास्तव में सिर्फ लागू करने से पहले कुछ काम कर देखना चाहता था। मुझे लगा कि मुझे कम से कम अपनी वस्तु पर कुछ देखना चाहिए जिस तरह से कोड है।

मुझे कुछ दिखाई नहीं दे रहा है, बस सीधे काले। मैंने अपना बैकग्राउंड सफ़ेद कर लिया है फिर भी वस्तु काली है। मैंने लाइटिंग हटा दी है, और सिर्फ क्यूबैप बनावट और अभी भी काले रंग का नमूना लेने के लिए रंग कर रहा हूं।

मुझे लगता है कि समस्या मेरी बनावट सेट करते समय प्रारूप प्रकार हो सकती है जो GL_RGB8, GL_RGBA है, लेकिन मैंने भी कोशिश की है:

GL_RGBA, GL_RGBA GL_RGB, GL_RGB

मैंने सोचा था कि यह मानक होगा क्योंकि हम एक फ्रेमबफ़र से जुड़ी बनावट को प्रस्तुत कर रहे हैं, लेकिन मैंने अलग-अलग उदाहरणों को देखा है जो विभिन्न एनम मूल्यों का उपयोग करते हैं।

मैंने हर ड्रॉ कॉल में क्यूब मैप टेक्सचर को बाँधने की कोशिश की है जो मैं क्यूब मैप का उपयोग करना चाहता हूँ:

glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMapTexture);

इसके अलावा, मैं FBO के लिए एक गहराई बफ़र नहीं बना रहा हूँ जिसे मैंने ज्यादातर उदाहरणों में देखा है, क्योंकि मैं केवल अपने क्यूब मैप के लिए रंगीन बफ़र चाहता हूँ। मैंने वास्तव में एक को यह देखने के लिए जोड़ा कि क्या यह समस्या थी और अभी भी वही परिणाम मिले हैं। मैं कोशिश कर रहा था कि जब मैं कोशिश कर सकता था।

कोई भी मदद जो मुझे सही दिशा में इंगित कर सके, की सराहना की जाएगी।

GLuint renderToCubeMap(int size, GLenum InternalFormat, GLenum Format, GLenum Type)
    {

    // color cube map
    GLuint textureObject;
    int face;
    GLenum status;

    //glEnable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE1);
    glGenTextures(1, &textureObject);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureObject);
    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    for (face = 0; face < 6; face++) {
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, InternalFormat, size, size, 0, Format, Type, NULL);
    }

    // framebuffer object
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, textureObject, 0);

    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    printf("%d\"\n", status);
        printf("%d\n", GL_FRAMEBUFFER_COMPLETE);

    glViewport(0,0,size, size);

    for (face = 1; face < 6; face++) {

        drawSpheres();
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, textureObject, 0);

    }

     //Bind 0, which means render to back buffer, as a result, fb is unbound
       glBindFramebuffer(GL_FRAMEBUFFER, 0);

       return textureObject;
    }

क्या आपने यह देखने के लिए परीक्षण किया है कि आपका drawSpheresफ़ंक्शन वास्तव में कुछ दिखाई देता है? क्या फ़ंक्शन वास्तव में कुछ आकर्षित करता है? क्या होता है यदि आप drawSpheresकेवल फ़्रेमबफ़र को बदलने के लिए बदलते हैं ?
निकोल बोलस

हाँ। मैं दो पास कर रहा हूं। उपरोक्त कोड में से एक, वास्तव में ऊपर 6 कॉल। फिर मैं drawSpheres को कॉल कर रहा हूं जब फ्रेमबफ़र 0 पर रेंडर किया गया है और यह दिखाई देता है।
जोए ग्रीन

इसके अलावा, मैंने अपनी पृष्ठभूमि को सफेद में सेट किया है। कम से कम बनावट में सफेद रंग दिखाई नहीं देगा?
जोए ग्रीन

क्या आपका कोड एक सामान्य FBO के लिए ठीक काम करता है? जिस तरह से मैं इसे समझता हूं, एक घन नक्शा सिर्फ छह बनावट होना चाहिए, और आपको प्रत्येक को अलग से प्रस्तुत करना होगा ..
जरी कोम्पा

जवाबों:


10

खैर, मैं गारंटी नहीं दे सकता कि इससे आपको पता चल जाएगा कि क्या चल रहा है। आपने किसी विशेष त्रुटि को ट्रैक करने के लिए क्या कर रहे हैं, इसके बारे में आपने पर्याप्त जानकारी पोस्ट नहीं की है। हालाँकि मैं आपकी एक बात को जल्दी सच कर सकता हूँ:

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, textureObject, 0);

...

for (face = 1; face < 6; face++) {
    drawSpheres();
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, textureObject, 0);
}

यह केवल drawSpheres पांच बार कॉल करेगा । मैं अनुमान लगा रहा हूं कि आप इसे 6 बार कॉल करना चाहते थे।

लेकिन मैं एक काम का जवाब पोस्ट कर सकता हूं ध्यान दें कि इस कोड को मेरी ट्यूटोरियल श्रृंखला के साथ चलाने के लिए डिज़ाइन किया गया है , इसलिए यह उस कोड का संदर्भ देता है जो मौजूद नहीं है। लेकिन यह मुख्य रूप से मेष और आगे बनाने जैसी चीजें हैं; वास्तव में महत्वपूर्ण कुछ भी नहीं।

यहाँ मुख्य बिंदु हैं। मुख्य क्षेत्र वस्तु के लिए शेड।

वर्टेक्स शेडर:

#version 330

layout(std140) uniform;

layout(location = 0) in vec4 position;
layout(location = 2) in vec3 normal;

out vec3 modelSpaceNormal;

uniform Projection
{
    mat4 cameraToClipMatrix;
};

uniform mat4 modelToCameraMatrix;

void main()
{
    gl_Position = cameraToClipMatrix * (modelToCameraMatrix * position);
    modelSpaceNormal = normal;
}

टुकड़े टुकड़े करना:

#version 330

in vec3 modelSpaceNormal;

uniform samplerCube cubeTexture;

out vec4 outputColor;

void main()
{
    outputColor = texture(cubeTexture, modelSpaceNormal);
//  outputColor = vec4(normalize(modelSpaceNormal), 1.0);
}

क्यूबैप बनावट का निर्माण जो एक रेंडर टारगेट के रूप में इस्तेमाल किया जाएगा:

void CreateCubeTexture()
{
    glGenTextures(1, &g_cubeTexture);
    glBindTexture(GL_TEXTURE_CUBE_MAP, g_cubeTexture);

    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    std::vector<GLubyte> testData(CUBE_TEXTURE_SIZE * CUBE_TEXTURE_SIZE * 256, 128);
    std::vector<GLubyte> xData(CUBE_TEXTURE_SIZE * CUBE_TEXTURE_SIZE * 256, 255);

    for(int loop = 0; loop < 6; ++loop)
    {
        if(loop)
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + loop, 0, GL_RGBA8,
                CUBE_TEXTURE_SIZE, CUBE_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, &testData[0]);
        }
        else
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + loop, 0, GL_RGBA8,
                CUBE_TEXTURE_SIZE, CUBE_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, &xData[0]);
        }
    }

    glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}

मैं वास्तव में डेटा को डिबगिंग सहायता के रूप में डेटा (बल्कि NULL से glTexImage2D को पास करने) में भरता हूं। यह सुनिश्चित करता है कि रेंडर टारगेट के रूप में बनावट का उपयोग शुरू करने से पहले सब कुछ काम कर रहा था।

इसके अलावा, ध्यान दें कि मैं एक BASE_LEVEL और MAX_LEVEL प्रदान करता हूं। मैं हमेशा रचना के तुरंत बाद अपने बनावट के साथ ऐसा करता हूं। यह सिर्फ एक अच्छी आदत है, क्योंकि ओपेन वील कभी-कभी बनावट की पूर्णता और मिपमैप पिरामिड के बारे में चुन सकती है। नियमों को याद करने के बजाय, मैंने उन्हें धार्मिक रूप से सही मूल्यों के लिए निर्धारित किया है।

यहाँ मुख्य ड्राइंग समारोह है:

void display()
{
    //Draw the cubemap.
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, g_framebuffer);
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, g_depthbuffer);

    for(int loop = 0; loop < 6; ++loop)
        DrawFace(loop);

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

    //Draw the main scene.
    //The projection matrix is in a uniform buffer.
    ProjectionBlock projData;
    projData.cameraToClipMatrix = glm::perspective(90.0f,
        (g_viewportSize.x / (float)g_viewportSize.y), g_fzNear, g_fzFar);

    glBindBuffer(GL_UNIFORM_BUFFER, g_projectionUniformBuffer);
    glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(ProjectionBlock), &projData);
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    glViewport(0, 0, (GLsizei)g_viewportSize.x, (GLsizei)g_viewportSize.y);

    glClearColor(0.75f, 0.75f, 1.0f, 1.0f);
    glClearDepth(1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glutil::MatrixStack modelMatrix;
    modelMatrix.ApplyMatrix(g_viewPole.CalcMatrix());

    if(g_pSphere)
    {
        glutil::PushStack push(modelMatrix);

        glUseProgram(g_progMain.theProgram);
        glUniformMatrix4fv(g_progMain.modelToCameraMatrixUnif, 1, GL_FALSE,
            glm::value_ptr(modelMatrix.Top()));

        glActiveTexture(GL_TEXTURE0 + g_cubeTexUnit);
        glBindTexture(GL_TEXTURE_CUBE_MAP, g_cubeTexture);

        g_pSphere->Render("lit");

        glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

        glUseProgram(0);
    }

    glutPostRedisplay();
    glutSwapBuffers();
}

यह संदर्भित करता है DrawFace, जो क्यूबैप के दिए गए चेहरे को खींचता है। इसे निम्नानुसार लागू किया गया है:

void DrawFace(int iFace)
{
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
        GL_TEXTURE_CUBE_MAP_POSITIVE_X + iFace, g_cubeTexture, 0);

    GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
    if(status != GL_FRAMEBUFFER_COMPLETE)
        printf("Status error: %08x\n", status);

    //The projection matrix is in a uniform buffer.
    ProjectionBlock projData;
    projData.cameraToClipMatrix = glm::perspective(90.0f, 1.0f, g_fzNear, g_fzFar);

    glBindBuffer(GL_UNIFORM_BUFFER, g_projectionUniformBuffer);
    glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(ProjectionBlock), &projData);
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    glViewport(0, 0, (GLsizei)CUBE_TEXTURE_SIZE, (GLsizei)CUBE_TEXTURE_SIZE);

    const glm::vec4 &faceColor = g_faceColors[iFace];
    glClearColor(faceColor.x, faceColor.y, faceColor.z, faceColor.w);
    glClearDepth(1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if(g_pSphere)
    {
        glutil::MatrixStack modelMatrix;
        modelMatrix.Translate(g_faceSphereLocs[iFace]);

        glUseProgram(g_progUnlit.theProgram);
        glUniformMatrix4fv(g_progUnlit.modelToCameraMatrixUnif, 1, GL_FALSE,
            glm::value_ptr(modelMatrix.Top()));

        const glm::vec4 &sphereColor = g_faceSphereColors[iFace];
        glUniform4fv(g_progUnlit.objectColorUnif, 1, glm::value_ptr(sphereColor));

        glActiveTexture(GL_TEXTURE0 + g_cubeTexUnit);
        glBindTexture(GL_TEXTURE_CUBE_MAP, g_cubeTexture);

        g_pSphere->Render("flat");

        glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
        glUseProgram(0);
    }
}

यह फ़ंक्शन वैश्विक तालिकाओं के एक सेट का संदर्भ देता है जिसका उपयोग मैं प्रत्येक चेहरे को एक अलग पृष्ठभूमि का रंग, एक अलग क्षेत्र का रंग, और उस चेहरे के लिए क्षेत्र (कैमरा-स्पेस में) को ठीक से करने के लिए करता हूं।

DrawFaceइन के लिए मुख्य बिंदु हैं।

एक सामान्य नियम के रूप में, जब तक कि मुझे कुछ ज्ञान नहीं है कि राज्य निर्धारित है, मैंने उस राज्य को निर्धारित किया है। जब भी मैं कॉल करता हूं, मैं व्यूपोर्ट सेट करता हूं DrawFace। मैं हर बार प्रोजेक्शन मैट्रिक्स सेट करता हूं। वे अतिशय हैं; मैं उन्हें displayलूप से पहले सेट कर सकता था जो कॉल करता है DrawFace, जैसा कि मैं वर्तमान एफबीओ और गहराई रेंडरबफ़र के साथ करता हूं।

लेकिन मैं बफ़र्स भी साफ़ करता हूं , जो प्रत्येक चेहरे के लिए अलग है (क्योंकि प्रत्येक चेहरे का एक अलग रंग है)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.