4

地形をレンダリングし、高さに応じて色を適用したいと考えています。
Qt プロジェクトを書いているので、QGlShaderProgram を使用します。

私の地形グリッドは (0,0,0) から (1000,0,1000) で、頂点は長さ 100 単位ごとに配置されます。均一な配列を使用してデータをシェーダーに転送したかったのです。

シェーダーにデータを送信する際にまだ問題があります。

C++/Qt からの呼び出し:

QGLShaderProgram  mShader;
QVector< GLfloat> mHeightMap (10*10, some_data);
GLfloat           mXStepSize = 100;
GLfloat           mZStepSize = 100;
// ..
mShader.link();
mShader.bind();
mShader.setUniformValueArray( "heights",
                               &(mHeightMap[0]),       // one line after another
                               mHeightMap.size(), 1 );
mShader.setUniformValue( "x_res", (GLint) mXStepSize);
mShader.setUniformValue( "z_res", (GLint) mZStepSize);

シェーダー ソース:

uniform sampler2D heights;
uniform int       x_res;
uniform int       z_res;
void main(void)
{
       vec4 tmp         = gl_Vertex;
       vec4 h;
       float x_coord    = gl_Vertex[0] * 0.001;
       float z_coord    = gl_Vertex[2] * 0.001;

       // interprete as 2D:
       int element      = int( (x_coord + float(x_res)*z_coord) );

       h                = texture2D( heights, vec2(x_coord, z_coord));
       gl_FrontColor    = gl_Color;
       gl_FrontColor[1] = h[ element];     // set color by height
       tmp.y            = h[ element];     // write height to grid
       gl_Position      = gl_ModelViewProjectionMatrix * tmp;
}

私の間違いはどこですか?
データをシェーダーにロードして、そこにアクセスするにはどうすればよいですか?

4

2 に答える 2

2

テクスチャとして渡したい場合は、最初に glTexImage2D を使用して配列マップ (mHeightMap) を opengl テクスチャに変換する必要があります。これを見てください、それはあなたが探しているものかもしれません: https://gamedev.stackexchange.com/questions/45188/how-can-i-pass-an-array-of-floats-to-the-fragment-shader-テクスチャの使用

編集:あなたはそれのいくつかを微調整したいかもしれませんが、それはアイデアです:

//Create texture: 
glint texture;
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);  
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, &(mHeightMap.constData()[data_start]));

//pass it to shader
glint uniformId = glGetUniformid(shader, "height");
glActiveTexture(GL_TEXTURE0);   
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);  
glUniform1i(uniformId, 0); // 0 is the texture number
于 2013-10-28T15:58:48.973 に答える
2

(コードは現在動作しているようです)

私は izissise の助けを借りて、そのほとんどを理解しました。GL_TEXTURE_2D の代わりに GL_TEXTURE_RECTANGLE を使用しました。
それでも、赤のチャネルのみを使用します (これは最適化されている可能性があります)。

これは私の初期化です:

QGLShaderProgram    mShader;
QVector< GLfloat> mHeightMap (width * height * state_count, 
                              some_data);
mShader.link();

// init texture
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &mShaderTexture);
glBindTexture(GL_TEXTURE_RECTANGLE, mShaderTexture);


データをシェーダーに送信します(これは何度でも繰り返すことができます):

mShader.bind();
// ..
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RED,
             width, depth, 0,
             GL_RED, GL_FLOAT,
             &(mHeightMap.constData()[mHeightMapPos])); // set portion of vector as array to texture / sampler
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_RECTANGLE);
glBindTexture(GL_TEXTURE_RECTANGLE, mShaderTexture);
mShader.setUniformValue( "max_height",  (GLfloat) (250.0) );
mShader.setUniformValue( "x_steps",     (GLint) width);
mShader.setUniformValue( "z_steps",     (GLint) height);

// ..
mShader.release();


シェーダー ソース と同様に:

uniform int     x_steps;
uniform int     z_steps;
uniform sampler2DRect heights;
uniform float   max_height;

void main(void)
{
    vec4 tmp         = gl_Vertex;
    vec4 h;

    float x_coord    = gl_Vertex[0] * 0.001 * float(x_steps-1);
    float z_coord    = gl_Vertex[2] * 0.001 * float(z_steps-1);
    h                = texture2DRect( heights, ivec2(int(x_coord), int(z_coord)) );
    tmp.y            = max_height * (h.r);

    gl_FrontColor    = gl_Color;
    gl_FrontColor[1] = h.r;

    gl_Position      = gl_ModelViewProjectionMatrix * tmp;
}
于 2013-10-29T16:17:54.793 に答える