2017-02-14 15 views
3

私はスプライトクラスを設計しており、テクスチャがロードされていない場合は色のみを表示したいと思います。ここでsampler2Dが空であることを確認してください

は、私の頂点シェーダは

#version 330 core 
layout (location = 0) in vec4 vertex; // <vec2 pos, vec2 tex> 

out vec2 vs_tex_coords; 

uniform mat4 model; 
uniform mat4 projection; 

void main() 
{ 
    vs_tex_coords = vertex.zw; 
    gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0); 
} 

とフラグメントシェーダです:

#version 330 core 

in vec2 vs_tex_coords; 

out vec4 fs_color; 

uniform sampler2D image; 
uniform vec3 sprite_color; 

void main() 
{ 
    fs_color = vec4(sprite_color, 1.0) * texture(image, vs_tex_coords); 
} 

私の問題は、私はテクスチャを結合しない場合、それは黒のみのスプライトを表示するということです。問題は、私のフラグメントシェーダのテクスチャ関数が0を返し、すべての式をねじ込むということです。

sampler2Dが初期化されていないか、nullであるかどうかを知る方法はありますか?単にsprite_colorを返しますか?

SOLUTION:

ソリューションは、空の1x1のテクスチャを生成し、とにかくそれをバインドすることでした。これを行うには、RGBAの場合は4文字から255の配列を作成し、1x1のテクスチャが作成されるように1x1のサイズをglTexImage2D関数に与える必要があります。

Texture::Texture() 
{ 
    glGenTextures(1, &ID); 

    GLubyte data[] = { 255, 255, 255, 255 }; 

    glBindTexture(GL_TEXTURE_2D, ID); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 

    size.x = 1; 
    size.y = 1; 
} 
+0

希望する色で1x1テクスチャをバインドしますか? – genpfault

答えて

2

サンプラーを「空にする」ことはできません。有効なテクスチャは、レンダリングが明確な振る舞いをするためには、各サンプラによって参照されるテクスチャユニットにバインドされなければならない()。

しかし、それはそこにバインドされているテクスチャからを読み取る必要があることを意味しません。 uniformの値を使用してテクスチャから読み込むかどうかをシェーダに伝えるのは完全に有効です。

でも、そこには単純な1x1テクスチャをバインドする必要があります。実際にはサンプラーでtextureSizeを使用できます。それが1x1のテクスチャならば、そこから読むのは気にしないでください。これはuniformを使用するよりも遅くなる可能性があることに注意してください。

+0

空のテクスチャを生成するのに[this](https://hastebin.com/jivojakusi.hs)を使用しますが、まだ黒の出力があります。 – Bl4ckb0ne

+1

データ量が少なすぎます。 1x1 RGBAテクスチャには少なくとも4バイト必要です。 – BDL

+1

ああ、愚かな私。私は解決策を見つけるためにもっと掘り起こさなければなりませんでしたが、あなたはどちらも間違いなく私を助けました。私は私の解決策で最初の投稿を更新します。ありがとう – Bl4ckb0ne

0

ここでは、if... else...を条件とした場合としない場合の2つのバージョンを示します。条件文は、使用されていない場合にテクスチャをサンプリングする必要がないようにします。

uniform int textureSampleは、それぞれテクスチャまたは色が表示されるように1または0に設定されています。両方の統一変数は通常、シェーダではなくプログラムによって設定されます。

uniform int textureSample = 1; 
uniform vec3 color = vec3(1.0, 1.0, 0.0); 


void main() {  // without if... else... 

    // ... 
    vec3 materialDiffuseColor = textureSample * texture(textureSampler, fragmentTexture).rgb - (textureSample - 1) * color; 
    // ... 
} 


void main() {  // with if... else... 

    // ... 
if (textureSample == 1) {  // 1 if texture, 0 if color 

    vec3 materialDiffuseColor = textureSample * texture(textureSampler, fragmentTexture).rgb; 
    vec3 materialAmbientColor = vec3(0.5, 0.5, 0.5) * materialDiffuseColor; 
    vec3 materialSpecularColor = vec3(0.3, 0.3, 0.3); 

    gl_Color = brightness * 
     (materialAmbientColor + 
     materialDiffuseColor * lightPowerColor * cosTheta/distanceLight2 + 
     materialSpecularColor * lightPowerColor * pow(cosAlpha, 10000)/distanceLight2); 
} 
else { 
    vec3 materialDiffuseColor = color; 
    vec3 materialAmbientColor = vec3(0.5, 0.5, 0.5) * materialDiffuseColor; 
    vec3 materialSpecularColor = vec3(0.3, 0.3, 0.3); 

    gl_Color = brightness * 
     (materialAmbientColor + 
     materialDiffuseColor * lightPowerColor * cosTheta/distanceLight2 + 
     materialSpecularColor * lightPowerColor * pow(cosAlpha, 10000)/distanceLight2); 
    } 
} 
関連する問題