Question

I'm a new learner about OpenGL and GLSL. I'm coding a program in which i wanna store a group of datas in a texture and get the data by sampling the texture in vertex shader. Then i want to set the datas as the y coodinates of terrain positions. But i get a trouble that it's failed and i can't get a correct value___all the y coodinates are 0.

The main code is below:

GLuint  terrainShader;      // The perspective demonstration shader
GLint   locMVP,locTex;                 // The location of the uniform in vertex shader

GLuint  vao;                    // The VAO
GLuint  vertexBuffer;          
GLuint elementBuffer;
GLuint vertexTexture;       

const int n=127;
float verteces[n*n*2];// vertex array
GLuint vIndexFine[(n-1)*2*n];//index array
GLsizei countFine[n-1];
GLvoid* offsetFine[n-1];

float *data=new float[n*n];
    terrainShader = gltLoadShaderPairWithAttributes("terrain.vp", "terrain.fp", 1, 
                                    GLT_ATTRIBUTE_VERTEX, "vVertex");

    locMVP = glGetUniformLocation(terrainShader, "mvpMatrix");
    locTex = glGetUniformLocation(terrainShader, "vertexTexture");

    //creat a terrain with size of n*n  
    for(int i=0;i<n;i++)
    {
        int sum=i*n;
        for(int j=0;j<n;j++)
        {
            verteces[(sum+j)*2]=float(j);
            verteces[(sum+j)*2+1]=float(i);
        }
    }
    //initialize the index array
    for(int i=0;i<n-1;i++)
    {
        if(i==0)                //the first line
        {
            for(int j=0;j<n;j++)
            {
                vIndexFine[2*j]=j;
                vIndexFine[2*j+1]=j+n;
            }
        }
        else
        {                   //if it's not the first line,then just add n to get the indexes of new line
            for(int k=0;k<2*n;k++)
            {
                vIndexFine[i*2*n+k]=vIndexFine[(i-1)*2*n+k]+n;
            }
        }
    }

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verteces), verteces, GL_STATIC_DRAW);
    glVertexAttribPointer(GLT_ATTRIBUTE_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(GLT_ATTRIBUTE_VERTEX);

    glGenBuffers(1, &elementBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vIndexFine), vIndexFine, GL_STATIC_DRAW);
        //initialize data array with random integers between 1 and 100
    for(int i=0;i<n*n;i++)
        data[i]=float(rand()%100)/100.0;

        //creat a texture and store data
    glGenTextures(1, &vertexTexture);   
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, vertexTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, n,n, 0,GL_RED, GL_FLOAT, data);

    //compute every trianglestrip's indexcount and offset
    int temp=n*2*sizeof(GLuint);
    for(int i=0;i<n-1;i++)
    {
        offsetFine[i]=(void*)(temp*i);
        countFine[i]=GLsizei(n*2);
    }

    glUseProgram(terrainShader);
    glUniform1i(locTex, 0); 

    modelViewMatrix.PushMatrix(viewFrame);
    modelViewMatrix.Translate(-n/2.0, -10.0f, -n/2.0);
    glUniformMatrix4fv(locMVP, 1, GL_FALSE, transformPipeline.GetModelViewProjectionMatrix());
    glMultiDrawElements(GL_TRIANGLE_STRIP,countFine,GL_UNSIGNED_INT, (const GLvoid**)offsetFine,n-1);   
    modelViewMatrix.PopMatrix();

the vertex shader:

#version 410

uniform mat4    mvpMatrix;
uniform sampler2D vertexTexture;
in vec2 vVertex;

void main(void) 
    { 
    vec2 vTexCoords=vVertex/127.0;
    float height = texture2DLod(vertexTexture, vTexCoords,0.0).x*100.0;
    vec4 position=vec4(vVertex.x,height,vVertex.y,1.0);
    gl_Position = mvpMatrix * position;
    }

i think the mistake must be the part of storing datas in application or the part of fetching datas from the texture in vertex shader. can sombody point it out for me?

Was it helpful?

Solution

It's solved now.the answer is here Try setting the texture's minification filter to GL_NEAREST or GL_LINEAR after glTexImage2D():

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

The OpenGL default is to use mipmaps and you didn't send any which makes the texture incomplete and will disable that texture image unit.

Then you can use texture(vertexTexture, vTexCoords) inside the shader instead of the deprecated texture2DLOD() version with the explicit LOD access.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top