2014-12-01 7 views
0

렌더링 된 텍스처 (FBO를 통해)를 큐브와 텍스처로 사용하려고합니다. 불행히도, 나는 그것을 할 수 없다. 텍스처는 완전히 검은 색이지만 한 사이트 함수 (drawObjects)에서 복사 붙여 넣기를 사용하면 다른 방법으로 시도해 볼 때 크기가 아주 좋은 텍스처를 렌더링합니다. 내 드로잉 코드 (Model3D :: draw())와 복사 붙여 넣기 함수 drawObjects의 차이를 확인할 수 없습니다.FBO 렌더링 텍스처 - 검정 텍스처

일반 텍스처를 사용할 때 텍스처 형식이 다르기 때문에 f.e. 모델 : loadTexture ("데이터/스프라이트/floor4.png") 질감이 잘 표현되어

#include "worldrender.h" 

WorldRender::WorldRender() : world() 
{ 
} 

WorldRender::WorldRender(int argc, char **argv) : world(argc, argv) 

{ 

} 


void WorldRender::init() 
{ 

    world::init(); 


    glGenFramebuffers(1, &frameBo); DEBUG; 
    glBindFramebuffer(GL_FRAMEBUFFER, frameBo); DEBUG; 


    glGenTextures(1, &renderedTexture); DEBUG; 
    glBindTexture(GL_TEXTURE_2D, renderedTexture); DEBUG; 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIN_WIDTH, WIN_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); DEBUG; 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); DEBUG; 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); DEBUG; 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); DEBUG; 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); DEBUG; 


    glGenRenderbuffers(1, &depthBo); DEBUG; 
    glBindRenderbuffer(GL_RENDERBUFFER, depthBo); DEBUG; 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, WIN_WIDTH, WIN_HEIGHT); DEBUG; 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBo); DEBUG; 

    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0); DEBUG; 
    GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; DEBUG; 
    glDrawBuffers(1, DrawBuffers); DEBUG; 

    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 
     throw std::string("Frame buffer setup not complete"); 
    } 

    obj *o = new obj("data/models/cube.obj"); 
    o->load(); 
    poster = new Model3D(o, "cube"); 
    poster->setPosition(glm::vec3(-0.5, -0.5, -0.5)); 

    s2 = s; 
    poster->s = &s2; 
    std::cerr << "Rendered texture (FBO): " << renderedTexture << std::endl; 
    poster->replaceTexture(renderedTexture); // Uncomment this normal 
    poster->init(); 


} 

void WorldRender::postRenderFrame() 
{ 

} 

void WorldRender::destroy() 
{ 
    world::destroy(); 

} 

int WorldRender::exec(GLFWwindow *window) { 
    this->window = window; 
    init(); 
    glfwInit(); 
    ilInit(); 

    if (!window) { 
     throw std::string("cannot create window"); 

    } 


    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
    glClearColor(0.0f, 0.0f, 0.4f, 1.0f); 
    do { 
     glBindFramebuffer(GL_FRAMEBUFFER, frameBo); DEBUG; 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     renderFrame(); 
     glBindFramebuffer(GL_FRAMEBUFFER, 0); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     poster->draw(&s2); 


     glfwSwapBuffers(window); 
     glfwPollEvents(); 


    } while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && 
      glfwWindowShouldClose(window) == 0); 



    glfwTerminate(); 

    return 0; 

} 

void WorldRender::preRenderFrame() { 
    glBindFramebuffer(GL_FRAMEBUFFER, frameBo); 
} 

Model3D 그릴 :

#include "model3d.h" 

Model3D::Model3D() : Model() 
{ 
} 

Model3D::Model3D(obj *o, 
       std::string name, 
       std::string vShader, 
       std::string fShader) 
     : Model(o, 
       name, 
       o->materials.at(o->objects.at(name).materialName), 
       vShader, 
       fShader) { 

    vertices = &o->objects.at(name).vertices; 
    uvs = &o->objects.at(name).uvs; 
    normals = &o->objects.at(name).normals; 
    indices = &o->objects.at(name).indices; 
    m = o->materials.at(o->objects.at(name).materialName); 

    std::cerr << "Material name: " << m.name << std::endl; 
    std::cerr << "Materi kd path: " << m.mapKdPath << std::endl; 
    std::cerr << "Texture path " << texturePath << std::endl; 
    this->texturePath = texturePath; 
    this->vertices = vertices; 
    this->uvs = uvs; 
    this->normals = normals; 
    this->indices = indices; 

    vao = initVao(); 
} 


void Model3D::draw(scene *s) { 
    DEBUG; 
    double start = glfwGetTime(); 
    glm::mat4 translation = glm::translate(glm::mat4(1.0f),this->position); 
    glm::mat4 rotation = glm::rotate(glm::mat4(1.0f),this->rotation[0], glm::vec3(1.0f, 0.0f, 0.0f)); 
    rotation = glm::rotate(rotation, this->rotation[1], glm::vec3(0, 1, 0)); 
    rotation = glm::rotate(rotation, this->rotation[2], glm::vec3(0, 0, 1)); 
    glm::mat4 scalation = glm::scale(glm::mat4(1.0f),scale); 
    M = translation * rotation * scalation; 

    glUseProgram(programID); 
    DEBUG; 

    glBindVertexArray(vao); 
    DEBUG; 
    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 
    glEnableVertexAttribArray(2); 
    glEnableVertexAttribArray(3); 
    /** 
    glEnableVertexAttribArray(4); 
    glEnableVertexAttribArray(5); 
    **/ 
    DEBUG; 

    glBindBuffer(GL_ARRAY_BUFFER, vertexBo); 
    glVertexAttribPointer(
      0, // attribute 0. Brak uzasadnienia 
      3, // uważaj, tu z ilu komponentów składa się atrybut vertexu 
       // może być 1,2,3,4 
      GL_FLOAT, // type 
      GL_FALSE, // znormalizowane 
      0,  // stride 
      (void*)0 // array buffer offset 
    ); 

    DEBUG; 

    glBindBuffer(GL_ARRAY_BUFFER, uvBo); 
    glVertexAttribPointer(
      1, // attribute 1. Brak uzasadnienia 
      2, // uważaj, tu z ilu komponentów składa się atrybut vertexu 
       // może być 1,2,3,4 
      GL_FLOAT, // type 
      GL_FALSE, // znormalizowane 
      0,  // stride 
      (void*)0 // array buffer offset 
    ); 

    glBindBuffer(GL_ARRAY_BUFFER, normalBo); 
    glVertexAttribPointer(
      2, // attribute 0. Brak uzasadnienia 
      3, // uważaj, tu z ilu komponentów składa się atrybut vertexu 
       // może być 1,2,3,4 
      GL_FLOAT, // type 
      GL_FALSE, // znormalizowane 
      0,  // stride 
      (void*)0 // array buffer offset 
    ); 

    DEBUG; 

    /** 

    glBindBuffer(GL_ARRAY_BUFFER, tangentBo); 
    glVertexAttribPointer(
      4, // attribute 0. Brak uzasadnienia 
      3, // uważaj, tu z ilu komponentów składa się atrybut vertexu 
       // może być 1,2,3,4 
      GL_FLOAT, // type 
      GL_FALSE, // znormalizowane 
      0,  // stride 
      (void*)0 // array buffer offset 
    ); 

    glBindBuffer(GL_ARRAY_BUFFER, bitangentBo); 
    glVertexAttribPointer(
      5, // attribute 0. Brak uzasadnienia 
      3, // uważaj, tu z ilu komponentów składa się atrybut vertexu 
       // może być 1,2,3,4 
      GL_FLOAT, // type 
      GL_FALSE, // znormalizowane 
      0,  // stride 
      (void*)0 // array buffer offset 
    ); 

    **/ 

    preRender(s); 
    DEBUG; 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBo); 
    glVertexAttribPointer(
      3, // attribute 0. Brak uzasadnienia 
      1, // uważaj, tu z ilu komponentów składa się atrybut vertexu 
       // może być 1,2,3,4 
      GL_UNSIGNED_INT, // type 
      GL_FALSE, // znormalizowane 
      0,  // stride 
      (void*)0 // array buffer offset 
    ); 

    DEBUG; 

    glDrawElements(GL_TRIANGLES, 
        indices->size(), 
        GL_UNSIGNED_INT, 
        (void *)0); 
    glBindVertexArray(0); 

    DEBUG; 

    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 
    glDisableVertexAttribArray(2); 
    glDisableVertexAttribArray(3); 
    DEBUG; 
    /** 
    glDisableVertexAttribArray(4); 
    glDisableVertexAttribArray(5); 
    **/ 

    postRender(s); 
    DEBUG; 
    double end = glfwGetTime(); 
    double diff = end-start; 
    static double last = glfwGetTime(); 
    static std::list<float> times; 
    static float sum = 0.0; 

    times.push_front(diff); 
    sum += diff; 

    if (times.size() >= 20.0) { 
     float lastDiff = times.back(); 
     times.pop_back(); 
     sum -= lastDiff; 
    } 

    float avg = sum/(float)times.size(); 
    float fps = 1.0/avg; 

    if (end - last >= 1.0) { 
     last = end; 

     fprintf(stderr, "Model3D %s draw FPS: %.2f, time: %.2fms\n", 
       name.c_str(), 
       fps, 
       1000.0 * avg); 
    } 
    DEBUG; 
} 

void Model3D::preRender(scene *s) { 
    // pobiermy id uchwytu dla danych 
    if (s->lightPosition.size() != MAX_LIGHT_SOURCES) { 
     throw std::string("Too low light sources in buffer"); 
    } 

    GLuint matrixId = glGetUniformLocation(programID, "MVP"); 
    GLuint matrixId3 = glGetUniformLocation(programID, "MVP3"); 
    GLuint modelId = glGetUniformLocation(programID, "M"); 
    GLuint viewId = glGetUniformLocation(programID, "V"); 

    // GLuint texId2 = glGetUniformLocation(programID, "normalMap"); 
    glm::mat4 MVP = s->projection * s->view * M; 
    glm::mat3 MVP3(MVP); 

    // wysyłamy przekształcenie do aktualnie powiązanego shadera 
    glUniformMatrix4fv(matrixId, 1, GL_FALSE, &MVP[0][0]); 
    DEBUG; 
    glUniformMatrix3fv(matrixId3, 1, GL_FALSE, &MVP3[0][0]); 
    DEBUG; 
    glUniformMatrix4fv(modelId, 1, GL_FALSE, &M[0][0]); 
    DEBUG; 
    glUniformMatrix4fv(viewId, 1, GL_FALSE, &s->view[0][0]); 
    DEBUG; 

    glActiveTexture(GL_TEXTURE0); 
    DEBUG; 
    glBindTexture(GL_TEXTURE_2D, textureID); 

    updateTextureFilter(); 
    DEBUG; 


} 

void Model3D::postRender(scene *s) { 

} 

void Model3D::init() { 

    Model::init(); 
    glUseProgram(programID); 

    GLuint lightPosId = glGetUniformLocation(programID, "light_pos_world"); 

    GLuint texId1 = glGetUniformLocation(programID, "sampler"); 
    GLuint kAId = glGetUniformLocation(programID, "kA"); 
    GLuint kDId = glGetUniformLocation(programID, "kD"); 
    GLuint kSId = glGetUniformLocation(programID, "kS"); 
    GLuint kMaxDegrees = glGetUniformLocation(programID, "max_degree"); 
    DEBUG; 
    GLuint kLightDirectionGlo = glGetUniformLocation(programID, 
      "light_direction_glo"); 
    DEBUG; 
    GLuint kSpotlight = glGetUniformLocation(programID, 
      "spotlight"); 
    DEBUG; 
    GLuint kColors = glGetUniformLocation(programID, 
      "colors"); 
    DEBUG; 
    GLuint nrLightSourcesId = glGetUniformLocation(programID, "nrLightSources"); 
    DEBUG; 
    GLuint kLightPowerID = glGetUniformLocation(programID, 
      "lightPower"); 

    glUniform3fv(lightPosId, MAX_LIGHT_SOURCES, &s->lightPosition[0][0]); 
    // do lightPosition musi wejść 8 elementów 
    DEBUG; 

    glUniform3fv(kAId, 1, &m.Ka[0]); 
    DEBUG; 
    glUniform3fv(kDId, 1, &m.Kd[0]); 
    DEBUG; 
    glUniform3fv(kSId, 1, &m.Ks[0]); 
    DEBUG; 
    glUniform1i(nrLightSourcesId, s->nrOfLights); 
    DEBUG; 

    glUniform1fv(kMaxDegrees, MAX_LIGHT_SOURCES, &s->max_degree[0]); 
    DEBUG; 
    glUniform3fv(kLightDirectionGlo, MAX_LIGHT_SOURCES, 
      &s->lightDirection[0][0]); 
    DEBUG; 

    glUniform1iv(kSpotlight, MAX_LIGHT_SOURCES, &s->spotlight[0]); 
    DEBUG; 
    glUniform3fv(kColors, MAX_LIGHT_SOURCES, &s->colors[0][0]); 
    DEBUG; 
    glUniform1fv(kLightPowerID, MAX_LIGHT_SOURCES, &s->lightPower[0]); 
    DEBUG; 

    glActiveTexture(GL_TEXTURE0); 
    DEBUG; 
    glBindTexture(GL_TEXTURE_2D, textureID); 
    DEBUG; 
    texId1 = glGetUniformLocation(programID, "sampler"); 
    DEBUG; 
    glUniform1i(texId1, 0); 
    DEBUG; 


} 

void Model3D::destroy() { 
    Model::destroy(); 
} 

Model3D &Model3D::operator=(const Model3D &m) { 
    Model::operator =(m); 


    return *this; 
} 

Model3D::~Model3D() { 
    destroy(); 
} 

void Model3D::replaceTexture(GLuint texID) { 
    this->textureID = texID; 
    init(); 
} 

전체 코드 : https://bitbucket.org/tpsa/grafika-3d-laboratorium/src/4aa4edf09120e9f96694a1b811a051312ebb4bba/src/worldrender.cpp?at=render-to-texture-apply

내가 묻고 싶다 , 내가 뭘 잘못 할 수 있니? min_filter이 GL_NEAREST_MIPMAP_NEAREST 어디에 모델에

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); 

:: updateTextureFilter() :

+0

텍스처를로드하는 데 사용 하시겠습니까? framebufffer가'RGBA'를 사용하고 있기 때문에 텍스처를'RGBA'로로드하고 텍스처가이 채널을 처음부터 가지고 있는지 확인해야합니다. – Iggy

+0

이것을 단순화 할 가능성이 있습니까? 나는 읽기 시작했으나 순수한 코드를 제외하고는 동일한 코드를 여러 번 포함하고있는 것으로 보입니다. –

답변

0

문제는 형식도 아니고 단지 텍스처 필터링 쉐이더.

왜 이렇게 큰 차이가 났는지 모르겠습니다.