2016-04-10 13 views
0

私は、これらのトピックには新しく、学校プロジェクトのための最後の数日間クラッシュコースを提供していると言って前に説明します。これはかなり長いことをお詫びしますが、どこに問題があるのか​​分かりませんので、徹底的に試してみることにしました。フレームバッファ(テクスチャブランク)を使用したテクスチャへの描画

フレームバッファを使用して、後で他の図面で使用されるいくつかのRGBAテクスチャを描画しようとしています(テクスチャの値をベクトルとしてベクトルとして使用しています - テクスチャは、と速度)。

しかし、私が知る限り、描画後のテクスチャは空白です。テクスチャ内の値をサンプリングすると、戻ってきます(0、0、0、1)。これは私の後の作図手順でも確認されたようです。が表示されます。すべてのパーティクルが原点で重なって描画されています(この観察はブレンド関数とハードコードされたテストカラー値に基づいています)。

私はSDL2でOpenGL 4を使用しています。

私が整然と関連するすべてのものを投稿しようとします:

フレームバッファクラスは、フレームバッファとアタッチ(3)のテクスチャを作成します。 それがあります。この中で、再び(フレームバッファ用に作成する方法を多くのテクスチャでピクセル単位でテクスチャの幅と高さ0に初期化フレームバッファのID、unsigned int width, height、ある

GLuint buffer_id_numTexturesを、ケース3)、フレームバッファに関連するすべてのテクスチャについてはstd::vector<GLuint> textures_です。一つは、出力としてシェーダプログラムおよび他の入力として使用することができるように

bool Framebuffer::init() { 
    assert(numTextures <= GL_MAX_COLOR_ATTACHMENTS); 
    // Get the buffer id. 
    glGenFramebuffers(1, &buffer_id_); 
    glBindFramebuffer(GL_FRAMEBUFFER, buffer_id_); 
    // Generate the textures. 
    for (unsigned int i = 0; i < numTextures; ++i) { 
     GLuint tex; 
     glGenTextures(1, &tex); 
     glBindTexture(GL_TEXTURE_2D, tex); 
     // Give empty image to OpenGL. 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, 0); 
     // Use GL_NEAREST, since we don't want any kind of averaging across values: 
     // we just want one pixel to represent a particle's data. 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
     // This probably isn't necessary, but we don't want to have UV coords past the image edges. 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
     textures_.push_back(tex); 
    } 
    glBindTexture(GL_TEXTURE_2D, 0); 
    // Bind our textures to the framebuffer. 
    GLenum drawBuffers[GL_MAX_COLOR_ATTACHMENTS]; 
    for (unsigned int i = 0; i < numTextures; ++i) { 
     GLenum attach = GL_COLOR_ATTACHMENT0 + i; 
     glFramebufferTexture(GL_FRAMEBUFFER, attach, textures_[i], 0); 
     drawBuffers[i] = attach; 
    } 
    glDrawBuffers(numTextures, drawBuffers); 

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 
     std::cerr << "Error: Failed to create framebuffer." << std::endl; 
     return false; 
    } 
    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
    return true; 
} 

つマッチングフレームバッファは、パーティクルシステムによって行われます。

bool AmbientParticleSystem::initFramebuffers() { 
    framebuffers_[0] = new Framebuffer(particle_texture_width_, particle_texture_height_, NUM_TEXTURES_PER_FRAMEBUFFER); 
    framebuffers_[1] = new Framebuffer(particle_texture_width_, particle_texture_height_, NUM_TEXTURES_PER_FRAMEBUFFER); 

    return framebuffers_[0]->init() && framebuffers_[1]->init(); 
} 

それから私は、最初のフレームバッファへの初期状態を描画しようとすると:

void AmbientParticleSystem::initParticleDrawing() { 
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffers_[0]->getBufferID()); 
    // Store the previous viewport. 
    GLint prevViewport[4]; 
    glGetIntegerv(GL_VIEWPORT, prevViewport); 
    glViewport(0, 0, particle_texture_width_, particle_texture_height_); 
    glClear(GL_COLOR_BUFFER_BIT); 
    glDisable(GL_DEPTH_TEST); 
    glBlendFunc(GL_ONE, GL_ZERO); 

    init_shader_->use(); // This sets glUseProgram to the init shader. 
    GLint attrib = init_variable_ids_[constants::init::Variables::IN_VERTEX_POS]->id; 
    glEnableVertexAttribArray(attrib); 
    glBindBuffer(GL_ARRAY_BUFFER, full_size_quad_->getBufferID()); 
    glVertexAttribPointer(attrib, full_size_quad_->vertexSize, 
       GL_FLOAT, // type 
       GL_FALSE, // normalized? 
       0,   // stride 
       (void*)0); // Array buffer offset 
    glDrawArrays(GL_TRIANGLES, 0, full_size_quad_->numVertices); 

// Here I'm just printing some sample values to confirm it is blank/black. 
    glBindTexture(GL_TEXTURE_2D, framebuffers_[0]->getTexture(0)); 
    GLfloat *pixels = new GLfloat[particle_texture_width_ * particle_texture_height_ * 4]; 
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, pixels); 

    std::cout << "some pixel entries:\n"; 
    std::cout << "pixel0:  " << pixels[0] << " " << pixels[1] << " " << pixels[2] << " " << pixels[3] << std::endl; 
    std::cout << "pixel10: " << pixels[40] << " " << pixels[41] << " " << pixels[42] << " " << pixels[43] << std::endl; 
    std::cout << "pixel100: " << pixels[400] << " " << pixels[401] << " " << pixels[402] << " " << pixels[403] << std::endl; 
    std::cout << "pixel10000: " << pixels[40000] << " " << pixels[40001] << " " << pixels[40002] << " " << pixels[40003] << std::endl; 
// They all print 0, 0, 0, 1 
    delete pixels; 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glDisableVertexAttribArray(attrib); 
    init_shader_->stopUsing(); 
    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
    // Return the viewport to its previous state. 
    glViewport(prevViewport[0], prevViewport[1], prevViewport[2], prevViewport[3]); 
} 

あなたがここで見ることができ、私はいくつかのピクセル値を取得しようとどこにもあり、これはすべてのリターン(0、0、0 、1)。

ここで使用full_size_quad_がで定義されます。

// Create quad for textures to draw onto. 
static const GLfloat quad_array[] = { 
    -1.0f, -1.0f, 0.0f, 
    1.0f, 1.0f, 0.0f, 
    -1.0f, 1.0f, 0.0f, 
    -1.0f, -1.0f, 0.0f, 
    1.0f, -1.0f, 0.0f, 
    1.0f, 1.0f, 0.0f, 
}; 
std::vector<GLfloat> quad(quad_array, quad_array + 18); 
full_size_quad_ = new VertexBuffer(3, 6, quad); 

VertexBufferは自分のクラスで、私はは、私がここに表示する必要がないと思います。 glGensとglBindsの配列とバッファをバインドします。

ここで使用されるシェーダが頂点シェーダのためのこの有する:フラグメントシェーダ用

#version 400 core 

in vec3 inVertexPos; 

void main() { 
    gl_Position = vec4(inVertexPos, 1.0); 
} 

及びこれを:

#version 400 core 

layout(location = 0) out vec4 position; 
layout(location = 1) out vec4 velocity; 
layout(location = 2) out vec4 other; 

uniform vec2 uResolution; 

// http://stackoverflow.com/questions/4200224/random-noise-functions-for-glsl 
float rand(vec2 seed) { 
    return fract(sin(dot(seed.xy,vec2(12.9898,78.233))) * 43758.5453); 
} 

void main() { 
    vec2 uv = gl_FragCoord.xy/uResolution.xy; 

    vec3 pos = vec3(uv.x, uv.y, rand(uv)); 
    vec3 vel = vec3(-2.0, 0.0, 0.0); 
    vec4 col = vec4(1.0, 0.3, 0.1, 0.5); 

    position = vec4(pos, 1.0); 
    velocity = vec4(vel, 1.0); 
    other = col; 
} 

uResolutionはにより設定された、ピクセル単位でテクスチャの幅と高さ:

init_shader_->use(); 
glUniform2f(init_uniform_ids_[constants::init::Uniforms::U_RESOLUTION]->id, particle_texture_width_, particle_texture_height_); 

変更を試みましたposition = vec4(pos, 1.0);をdifに変更しました私のピクセル印刷はまだ0 0 0 1を与えました。

私はこれを約20-30時間デバッグしています。ここでは数十種類のチュートリアルやその他の質問を参照していますが、ここ数時間は私が何らかの根拠を感じていません。

ここでは、テクスチャが空白/黒色のように見える理由、またはアドレッシングが必要なものは何ですか?私はシェーダについて学ぶためにこのプロジェクトを使用していたので、私はこのすべてに非常に新しいです。どんな助けも非常に高く評価されます。

+0

定数 'GL_MAX_COLOR_ATTACHMENTS'を使用してバッファの割り当てとループの反復回数を制御するのは、*** WRONG ***です。これは、実際の番号を調べるために照会するIDであり、基本形式ではソートの制限ではなく、実行時に問題が発生してループを割り当てて実行しようとするほど大きな数値になります何度も:)最初に値を照会してください。 –

+0

@ AndonM.Colemanキャッチをありがとう。今私はそれを 'glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS、&maxAttach);'で照会します。 3つのテクスチャしか得られなかったのは幸いだと思うので、これまでのところ問題はなかった。 – Claytorpedo

+0

変更はないと思いますか?第2の問題点は、アクティブなフレームバッファに既に書き込まれている読み込み用のテクスチャをバインドしていることです。フレームバッファのイメージアタッチメントとして現在アクティブな状態でテクスチャをバインドすると、何か良いことは起こりそうにないので、インコヒーレントな値が戻ってくる可能性があります。現在バインドされているFBOからピクセルデータを読み戻すには、適切なカラーアタッチメントに設定されたreadbufferで 'glReadPixels(...) 'を使用することが期待されます。 –

答えて

0

これはコードの完全な書き換えによって解決されました。

私はまだ問題がどこにあるのかはっきりしていませんが、私はおそらくいくつかの不一致の呼び出しがあったと思います。

関連する問題