2016-07-12 11 views
0

データセットの各値が[0, 1]に正規化されている3次元データセットがあります。テクスチャとブレンドを使用してこのデータセットを視覚化したいと思います。 しかし、私はそれを動作させることはできないようです。ブレンディング作業ができません

//All inputs >=0.6 is transformed to highly transparent white color. 
glm::vec4 transformValueToColor(GLclampf tValue) 
{ 
    if (tValue >= 0.6f) { 
     return glm::vec4(255, 255, 255, 10); 
    } 
    else { 
     auto val = round(255 * tValue); 
     auto valOp = round(255 * (1 - tValue)); 
     return glm::vec4(val, val, val, valOp); 
    }  
} 

マイ頂点シェーダ:

int main(){ 
    ... 
    //building an image for each rectangular slice of data 
    vector<Texture> myTextures; 
    for (GLint rowIndex = 0; rowIndex < ROW_NUM; rowIndex++) 
    { 
     auto pathToImage = "images/row" + to_string(rowIndex) + FILE_EXT; 
     FIBITMAP *img = FreeImage_Allocate(SLICE_DIMENSION, SLICE_NUM, 32); //32 = RGBA 

     for (GLint depthIndex = 0; depthIndex < DEPTH_NUM; depthIndex++) 
     { 
      for (GLint colIndex = 0; colIndex < COL_NUM; colIndex++) 
      { 
       auto value = my3DData[depthIndex][rowIndex][colIndex]; 

       //transform tValue to a source color 
       glm::vec4 source = transformValueToColor(value); 

       //note that here I am also setting the opacity. 
       RGBQUAD linRgb = { source.b, source.g, source.r, source.a }; 
       FreeImage_SetPixelColor(img, colIndex, depthIndex, &linRgb); 
      } 
     } 

     //Saving images. Saved images shows transparency. 
     FreeImage_Save(FIF_PNG, img, pathToImage.c_str()); 
     myTextures.push_back(Texture(pathToImage.c_str(), GL_TEXTURE0)); 
    } 
    //create VAO, VBO, EBO for a unit quad. 

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

    //game loop 
    while (!glfwWindowShouldClose(window)) 
    { 
     ... 
     for (int i = 0; i < myTextures.size(); i++) 
     { 
      GLint index = myTextures.size() - i - 1; 
      myTextures[index].bind(); //does glActiveTexture(...), and glBindTexture(...); 

      glm::mat4 model; 

      //translate 
      model = glm::translate(model, glm::vec3(0.0f, 0.0f, -index*0.003f)); 

      //scale 
      model = glm::scale(model, glm::vec3(1.2f)); 

      glUniformMatrix4fv(glGetUniformLocation(ourShader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model)); 

      glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 
     } 
    } 
} 

transformValueToColor色値に[0,1]にデータ値を変換する:ここで

は、私がこれまでに行ったことある

#version 330 core 

layout(location = 0) in vec3 position; 
layout(location = 1) in vec2 texCoord; 

out vec2 TexCoord; 

uniform mat4 model; 
uniform mat4 view; 
uniform mat4 projection; 

void main() 
{ 
    gl_Position = projection * view * model * vec4(position, 1.0f); 
    TexCoord = vec2(texCoord.s, 1-texCoord.t); 
} 

マイフラグメントシェーダ:

#version 330 core 

in vec2 TexCoord; 

out vec4 color; 

uniform sampler2D sliceTexture; 

void main() 
{ 
    vec4 texColor = texture(sliceTexture, TexCoord); 
    color = texColor; 
} 

これは、ブレンドが機能するために必要なコードだと思います。画像は正しく生成され、クワッドのテクスチャとして正しく適用されます。しかし、前面のクワッドは完全に不透明であるように見えますが、生成された画像(前面に表示されていても)は透明な領域を表示します。

どこが間違っているのかわかりません。あなたの提案をリクエストする。

ありがとうございます。

編集:(RGBA画像をロードし、それからRGBAテクスチャの作成に関連する部分のみ)Textureクラスの詳細:

int width, height, channelCount; 
unsigned char* image = SOIL_load_image(pathToImage, &width, &height, &channelCount, SOIL_LOAD_RGBA); 
...  
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); 

EDIT2:カメラクラスの追加さ詳細。 Camera::getViewMatrix()は、viewマトリックスを提供する。

Camera::Camera(GLFWwindow* window, glm::vec3 position, glm::vec3 worldUpDirection, GLfloat yaw, GLfloat pitch) 
    :mouseSensitivity(0.25f), fov(45.0f), cameraSpeed(1.0f) 
{ 
    this->position = this->originalPosition = position; 
    this->worldUpDirection = worldUpDirection; 
    this->yaw = this->originalYaw = yaw; 
    this->pitch = this->originalPitch = pitch; 

    updateCameraVectors(); 
} 

void Camera::updateCameraVectors() 
{ 
    glm::mat4 yawPitchRotMat; 

    yawPitchRotMat = glm::rotate(yawPitchRotMat, glm::radians(yaw), glm::vec3(0.0f, 1.0f, 0.0f));  //y-ais as yaw axis 
    yawPitchRotMat = glm::rotate(yawPitchRotMat, glm::radians(pitch), glm::vec3(1.0f, 0.0f, 0.0f));  //x-axis as pitch axis 

    frontDirection = glm::normalize(-glm::vec3(yawPitchRotMat[2].x, yawPitchRotMat[2].y, yawPitchRotMat[2].z)); 

    rightDirection = glm::normalize(glm::cross(frontDirection, worldUpDirection)); 
    upDirection = glm::normalize(glm::cross(rightDirection, frontDirection)); 
} 

glm::mat4 Camera::getViewMatrix() 
{ 
    return glm::lookAt(position, position + frontDirection, upDirection); 
} 

答えて

2
myTextures.push_back(Texture(pathToImage.c_str(), GL_TEXTURE0)); 

これはあなたのTextureクラスに関する情報が含まれていないと、どのように画像ファイルを解析しています。ファイル自体に透明性が示されていても、画像をロードするときにテクスチャローディングコードがアルファチャンネルを破棄している可能性があります。

model = glm::translate(model, glm::vec3(0.0f, 0.0f, -index*0.003f)); 

これは、前から後にレンダリングしているかのように見えます。透明なオブジェクトをレンダリングしたい場合は、互いに独立した透明度のためにアルゴリズムを使用する必要があります。また、前から後までレンダリングする必要があります。

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

また、/アルファチャンネルのミキシングが異なって行われるようにglBlendFuncSeparateを使用する必要がある場合があります。私はこの1つについても分かりません。

単一のGL_TEXTURE_3Dオブジェクトを単純に配置し、それをキューブとしてレンダリングし、各レイヤーの一連の四角形をレンダリングするのではなく、フラグメントシェイダーですべてのミキシングを行うこともできます。

+0

ご返信ありがとうございます。問題の 'Texture'クラスの関連する詳細を追加しました。また、注文に関しては、一番遠い四角形と最も近い四角形を最後に描画していると思います。正面方向に進むほどz値が小さくなると思います。何を指示してるんですか? –

+1

私が見たほとんどのOpenGL設定では、前進するにつれてZ値が減少します。どのようにあなたのために働くつもりは、あなたのビューの行列を作成する方法に依存しますが、あなたはそれを表示しません。 – Jherico

+0

ご意見ありがとうございます。ビュー行列の 'Camera'クラスの詳細を追加しました。 –

関連する問題