Рисование текстурированного куба в Android NDK с использованием opengl-es2 ничего не нарисует - PullRequest
1 голос
/ 06 июля 2019

Я пытаюсь нарисовать текстурированный куб с не чередующимися / отдельными буферами для каждой позиции / текстурных координат / нормальных буферов.

поскольку я использую opengles-2, я не использую VAO.

код выполняется без ошибок, но вывод пуст. Я попробовал несколько вариантов умножения матриц, но все еще безуспешно.

вся помощь приветствуется.

Я ограничил рисование одной инициализацией и вызовом отрисовки, так как хочу отладить одну итерацию цикла отрисовки.

    ///////////////////////////////BUFFERS///////////////////////////////

    private:
        std::vector<GLfloat> positions = {
        // Front face
        -1.0, -1.0, 1.0,
        1.0, -1.0, 1.0,
        1.0, 1.0, 1.0,
        -1.0, 1.0, 1.0,

        // Back face
        -1.0, -1.0, -1.0,
        -1.0, 1.0, -1.0,
        1.0, 1.0, -1.0,
        1.0, -1.0, -1.0,

        // Top face
        -1.0, 1.0, -1.0,
        -1.0, 1.0, 1.0,
        1.0, 1.0, 1.0,
        1.0, 1.0, -1.0,

        // Bottom face
        -1.0, -1.0, -1.0,
        1.0, -1.0, -1.0,
        1.0, -1.0, 1.0,
        -1.0, -1.0, 1.0,

        // Right face
        1.0, -1.0, -1.0,
        1.0, 1.0, -1.0,
        1.0, 1.0, 1.0,
        1.0, -1.0, 1.0,

        // Left face
        -1.0, -1.0, -1.0,
        -1.0, -1.0, 1.0,
        -1.0, 1.0, 1.0,
        -1.0, 1.0, -1.0,
};

std::vector<GLfloat>  vertexNormals = {
        // Front
        0.0, 0.0, 1.0,
        0.0, 0.0, 1.0,
        0.0, 0.0, 1.0,
        0.0, 0.0, 1.0,

        // Back
        0.0, 0.0, -1.0,
        0.0, 0.0, -1.0,
        0.0, 0.0, -1.0,
        0.0, 0.0, -1.0,

        // Top
        0.0, 1.0, 0.0,
        0.0, 1.0, 0.0,
        0.0, 1.0, 0.0,
        0.0, 1.0, 0.0,

        // Bottom
        0.0, -1.0, 0.0,
        0.0, -1.0, 0.0,
        0.0, -1.0, 0.0,
        0.0, -1.0, 0.0,

        // Right
        1.0, 0.0, 0.0,
        1.0, 0.0, 0.0,
        1.0, 0.0, 0.0,
        1.0, 0.0, 0.0,

        // Left
        -1.0, 0.0, 0.0,
        -1.0, 0.0, 0.0,
        -1.0, 0.0, 0.0,
        -1.0, 0.0, 0.0,
};


std::vector<GLfloat>  textureCoordinates = {
        // Front
        0.0, 0.0,
        1.0, 0.0,
        1.0, 1.0,
        0.0, 1.0,
        // Back
        0.0, 0.0,
        1.0, 0.0,
        1.0, 1.0,
        0.0, 1.0,
        // Top
        0.0, 0.0,
        1.0, 0.0,
        1.0, 1.0,
        0.0, 1.0,
        // Bottom
        0.0, 0.0,
        1.0, 0.0,
        1.0, 1.0,
        0.0, 1.0,
        // Right
        0.0, 0.0,
        1.0, 0.0,
        1.0, 1.0,
        0.0, 1.0,
        // Left
        0.0, 0.0,
        1.0, 0.0,
        1.0, 1.0,
        0.0, 1.0,
};

std::vector<GLuint> vertexIndices = {
        0, 1, 2, 0, 2, 3,    // front
        4, 5, 6, 4, 6, 7,    // back
        8, 9, 10, 8, 10, 11,   // top
        12, 13, 14, 12, 14, 15,   // bottom
        16, 17, 18, 16, 18, 19,   // right
        20, 21, 22, 20, 22, 23,   // left
};


GLuint vbo[4];
static enum BUFFERS {
    VERTEX_BUFFER,
    TEXCOORD_BUFFER,
    NORMAL_BUFFER,
    INDEX_BUFFER
};


    private:
//GLuint vao;
GLuint vbo[4];
static enum BUFFERS {
    VERTEX_BUFFER,
    TEXCOORD_BUFFER,
    NORMAL_BUFFER,
    INDEX_BUFFER
};
    public:
void load_geometry(){
    LOGD("in %s",__func__);
    vbo[VERTEX_BUFFER] = NULL;
    vbo[TEXCOORD_BUFFER] = NULL;
    vbo[NORMAL_BUFFER] = NULL;
    vbo[INDEX_BUFFER] = NULL;

        glGenBuffers(1, &vbo[VERTEX_BUFFER]);
        glBindBuffer(GL_ARRAY_BUFFER, vbo[VERTEX_BUFFER]);

        glBufferData(GL_ARRAY_BUFFER, positions.size() * sizeof(GLfloat), positions.data(), GL_STATIC_DRAW);


        glGenBuffers(1, &vbo[TEXCOORD_BUFFER]);
        glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]);

        glBufferData(GL_ARRAY_BUFFER, textureCoordinates.size() * sizeof(GLfloat), textureCoordinates.data(), GL_STATIC_DRAW);


        glGenBuffers(1, &vbo[NORMAL_BUFFER]);
        glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]);

        glBufferData(GL_ARRAY_BUFFER, vertexNormals.size() * sizeof(GLfloat), vertexNormals.data(), GL_STATIC_DRAW);


        glGenBuffers(1, &vbo[INDEX_BUFFER]);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDEX_BUFFER]);

        glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexIndices.size() * sizeof(GLuint), vertexIndices.data(), GL_STATIC_DRAW);


    glBindBuffer(GL_ARRAY_BUFFER, 0);
}


    ///////////////////////////////PROGRAM///////////////////////////////


    private:
GLuint program;
    public:
void load_shader(){
    LOGD("in %s",__func__);
    const char* vertex_shader = "attribute vec4 aVertexPosition;\n"
                                 "    attribute vec3 aVertexNormal;\n"
                                 "    attribute vec2 aTextureCoord;\n"
                                 "    uniform mat4 uNormalMatrix;\n"
                                 "    uniform mat4 uModelViewMatrix;\n"
                                 "    uniform mat4 uProjectionMatrix;\n"
                                 "    varying highp vec2 vTextureCoord;\n"
                                 "    varying highp vec3 vLighting;\n"
                                 "    void main(void) {\n"
                                 "      gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;\n"
                                 "      vTextureCoord = aTextureCoord;\n"
                                 "      // Apply lighting effect\n"
                                 "      highp vec3 ambientLight = vec3(0.3, 0.3, 0.3);\n"
                                 "      highp vec3 directionalLightColor = vec3(1, 1, 1);\n"
                                 "      highp vec3 directionalVector = normalize(vec3(0.85, 0.8, 0.75));\n"
                                 "      highp vec4 transformedNormal = uNormalMatrix * vec4(aVertexNormal, 1.0);\n"
                                 "      highp float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0);\n"
                                 "      vLighting = ambientLight + (directionalLightColor * directional);\n"
                                 "    }";

    const char* fragment_shader = "    varying highp vec2 vTextureCoord;\n"
                                  "    varying highp vec3 vLighting;\n"
                                  "    uniform sampler2D uSampler;\n"
                                  "    void main(void) {\n"
                                  "      highp vec4 texelColor = texture2D(uSampler, vTextureCoord);\n"
                                  "      gl_FragColor = vec4(texelColor.rgb * vLighting, texelColor.a);\n"
                                  "    }";

    GLuint gl_vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(gl_vs, 1, &vertex_shader, NULL);
    glCompileShader(gl_vs);

    GLint status = 0;
    glGetShaderiv(gl_vs, GL_COMPILE_STATUS, &status);
    if (status == 0) {
        LOGE("*** Vertex shader compilation failed.");
        ABORT_GAME;
    }
    LOGD("Vertex shader compilation succeeded.");


    GLuint gl_fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(gl_fs, 1, &fragment_shader, NULL);
    glCompileShader(gl_fs);
    glGetShaderiv(gl_fs, GL_COMPILE_STATUS, &status);
    if (status == 0) {
        LOGE("*** Fragment shader compilation failed, %d", status);
        ABORT_GAME;
    }
    LOGD("Fragment shader compilation succeeded.");


    program = glCreateProgram();
    glAttachShader(program, gl_vs);
    glAttachShader(program, gl_fs);
    glLinkProgram(program);

    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (status == 0) {
        LOGE("*** Shader program link failed, %d", status);
        ABORT_GAME;
    }
    LOGD("Program linking succeeded.");

}

    ///////////////////////////////TEXTURE///////////////////////////////
    private:
GLuint tbo;
    public:
void load_texture(cv::Mat frame){

    if(frame.empty()){
        frame = cv::Mat(4,4,CV_MAKETYPE(CV_8U,4),cv::Scalar::all(255));
    }
    GLenum format = frame.channels()==4 ? GL_RGBA : GL_RGB;

    glGenTextures(1, &tbo);
    glBindTexture(GL_TEXTURE_2D, tbo);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    cv::cvtColor(frame,frame, cv::COLOR_RGB2BGR);
    glTexImage2D(GL_TEXTURE_2D, 0, format, frame.cols,frame.rows, 0, format, GL_UNSIGNED_BYTE, frame.ptr());
    glBindTexture(GL_TEXTURE_2D, 0);
}

    ///////////////////////////////RENDER///////////////////////////////

    public:
void render(GLuint PROGRAM){
    LOGD("Ruby_vault in %s %d",__func__,__LINE__);

    glm::mat4 projection_matrix = glm::perspective((float)(45.0f * M_PI / 180), 2,0f, 0.1f,200.0f);


    glm::mat4 view_matrix = glm::mat4(1.0f);
    glm::vec3 Eye       = glm::vec3(0.0f,0.0f,-50.0f);
    glm::vec3 Center    = glm::vec3(0.0f,0.0f,0.0f);
    glm::vec3 Up        = glm::vec3(0.0f,1.0f,0.0f);
    view_matrix = glm::lookAt(Eye, Center, Up);


    glm::mat4 model_matrix = glm::mat4(1.0f);
    model_matrix = glm::translate(model_matrix, glm::vec3(0.0f, 0.0f, 0.0f));
    model_matrix = glm::scale(model_matrix, glm::vec3(1.0f, 1.0f, 1.0f));

    model_matrix = view_matrix * model_matrix;

    glm::mat4 normal_matrix = glm::mat4(1.0f);
    normal_matrix = glm::inverseTranspose(model_matrix*view_matrix);




    glBindBuffer(GL_ARRAY_BUFFER, vbo[VERTEX_BUFFER]);
    GLint attribute_1 = glGetAttribLocation(PROGRAM,"aVertexPosition");
    GLint attribute_2 = glGetAttribLocation(PROGRAM,"aTextureCoord");
    GLint attribute_3 = glGetAttribLocation(PROGRAM,"aVertexNormal");

    glVertexAttribPointer(attribute_1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray (attribute_1);

    glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]);
    glVertexAttribPointer(attribute_2, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray (attribute_2);

    glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]);
    glVertexAttribPointer(attribute_3, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray (attribute_3);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDEX_BUFFER]);
    glUseProgram(PROGRAM);



    GLint uniform_1 = glGetUniformLocation(PROGRAM, "uProjectionMatrix");
    GLint uniform_2 = glGetUniformLocation(PROGRAM, "uModelViewMatrix");
    GLint uniform_3 = glGetUniformLocation(PROGRAM, "uNormalMatrix");
    GLint uniform_4 = glGetUniformLocation(PROGRAM, "uSampler");

    glUniformMatrix4fv(uniform_1, 1, GL_FALSE, glm::value_ptr(projection_matrix));
    glUniformMatrix4fv(uniform_2, 1, GL_FALSE, glm::value_ptr(model_matrix));
    glUniformMatrix4fv(uniform_3, 1, GL_FALSE, glm::value_ptr(normal_matrix));

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, tbo);

    glUniform1i(uniform_4,1);

    //glDrawElements(GL_TRIANGLES, mesh->mNumFaces * 3  , GL_UNSIGNED_INT, NULL);
    glDrawElements(GL_TRIANGLES, vertexIndices.size() , GL_UNSIGNED_INT, NULL);



}

   //////////////////////////////INITIALIZATION/+DRAW CALL///////////////////////////////
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);

    Element element = new Element();
    element->load_geometry();
    element->load_shader();
    element->load_texture(cv::imread("/storage/emulated/0/Ruby.jpg"));
    element->render(element->get_program());

что не так с кодом? Что я должен сделать, чтобы использовать отдельные буферы?

edit: вызывается один раз перед инициализацией и первым вызовом.

////////////////////////////////////////////////////////////////////////
GLuint * m_RenderToTextureFBO = new GLuint[1];
GLuint * textureIds = new GLuint[1];
GLuint m_CubeFBOTextureId;
int width_4k = 3840;
int height_4k = 2160;
void PlayScene::frame_buffer() {
    /** Create the texture, setup its properties for the FBO */
    glGenTextures(1, textureIds);
    m_CubeFBOTextureId = textureIds[0];

    /** Bind the texture for FBO and Setup its properties */
    glBindTexture(GL_TEXTURE_2D, m_CubeFBOTextureId);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    cv::Mat frame(height_4k,width_4k,CV_MAKETYPE(CV_8U,4),cv::Scalar::all(255));
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_4k, height_4k, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame.data);


    glGenFramebuffers(1, m_RenderToTextureFBO);

    /** Bind our frame buffer */
    glBindFramebuffer(GL_FRAMEBUFFER, m_RenderToTextureFBO[0]);

    /** Attach texture to the frame buffer */
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_CubeFBOTextureId, 0);

    /** Check FBO is complete and OK */
    int iResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if(iResult != GL_FRAMEBUFFER_COMPLETE)
    {
        LOGE("Framebuffer incomplete");
    }

    /** Un-bind frame buffer */
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

}

и до розыгрыша ..

    glViewport(0,0,width_4k,height_4k);
    /** set the Texture unit 0 active and bind the texture to it */
    glActiveTexture(GL_TEXTURE0);

    /** Enable frame buffer to start rendering into it */
    glBindFramebuffer(GL_FRAMEBUFFER, m_RenderToTextureFBO[0]);

    /** Create an Orange back ground */
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
...