如何将数组存储到纹理中并正确地采样顶点着色器中的纹理?

时间:2014-04-04 09:29:42

标签: opengl glsl vertex-shader

我是OpenGL和GLSL的新学员。我正在编写一个程序,我希望在纹理中存储一组数据,并通过在顶点着色器中对纹理进行采样来获取数据。然后我想将数据设置为地形位置的y坐标。但是我遇到了麻烦,它失败了,我无法得到正确的值_所有y坐标都是0。

主要代码如下:

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();

顶点着色器:

#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;
    }

我认为错误必须是在应用程序中存储数据的部分或从顶点着色器中的纹理中获取数据的部分。可以为我指出一下吗?

1 个答案:

答案 0 :(得分:0)

现在已经解决了。答案是here 尝试在glTexImage2D()之后将纹理的缩小过滤器设置为GL_NEAREST或GL_LINEAR:

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

OpenGL的默认设置是使用mipmap,你没有发送任何使纹理不完整的内容,并且会禁用该纹理图像单元。

然后你可以在着色器中使用纹理(vertexTexture,vTexCoords),而不是使用显式LOD访问的已弃用的texture2DLOD()版本。

相关问题