GLSL像素着色器仅运行0纹理联合

时间:2015-05-12 14:27:19

标签: c++ qt opengl glsl shader

我正在尝试编写一个简单的片段着色器,它应混合2个或更多纹理。我已经在Qt 5.4上编写了测试项目,但由于某种原因,它无法操作任何已经绑定到非零联合的纹理。 它忽略了任何值   setUniformValue(“tex *”,*); (str.83-90) 并且任何sampler2d总是只运行绑定为0的纹理。

怎么了?

Source of test project on Qt 5.4 available at bitbucket

#include<iostream>
#include<fstream>
#include<math.h>
#include<omp.h>
using namespace std;

#define LONGTH 88147
int label[LONGTH] ;
float data[LONGTH][2000] ;
float w[2000];
float e[2000];

void Input()
{
    ifstream fin;
    float a;
    fin.open("/home/data.train");
    if (!fin)
    {
            cout << "file error";
            return;
    }
    for (int i = 0; i < LONGTH; i++)
    {
            fin >> a;
            label[i] = int(a);
            for (int j = 0; j < 2000; j++)
            {
                    fin>>data[i][j];
            }
    }
    fin.close();
    cout<<"input over"<<endl;
    return;
}
void Initial()
{
    for (int i = 0; i < 2000; i++)
    {
            w[i] = 1;
            e[i] = 1;
    }
    return;
}

bool End()
{
    for (int i = 0; i < 2000; i++)
    {
            if (fabs(e[i])>pow(0.1, 6))
                    return 0;
    }
    return 1;
}

float Tkj(int i, int j, int k,float w[2000])
{
    return w[i] * data[k][i] - w[j] * data[k][j];
}

float En(int n)//*computation*
{
    float result = 0;
    #pragma omp parallel for num_threads(64) reduction(+:result)
    for (int k = 0; k < LONGTH; k++)
    {
            int tnum = omp_get_thread_num();
            float tmp = 0;
            int i = label[k] - 1;
            for (int j = 0; j < 2000; j++)
            {
                    if (j != i)
                    {
                            float l = 0;
                            if (n == i)
                            {
                                    l = data[k][i];
                                    float e = exp(Tkj(i, j, k,w));
                                    tmp = tmp + (-e*l) / pow(1 + e, 2);
                            }
                            else if (n == j)
                            {
                                    l = -data[k][j];
                                    float e = exp(Tkj(i, j, k,w));
                                    tmp = tmp + (-e*l) / pow(1 + e, 2);
                            }
                            else
                            {
                                    continue;
                            }                       
                    }
            }
            result = result + tmp;
    }
    return result;
}
float Ex(float w[2000])
{
    float result = 0;
    #pragma omp parallel for num_threads(64) reduction(+:result)
    for (int k = 0; k < LONGTH; k++)
    {
            int i = label[k] - 1;
            float tmp = 0;
            int tnum = omp_get_thread_num();
            for (int j = 0; j < 2000; j++)
            {
                    if (j != i)
                    {
                            tmp = tmp + 1 / (1 + exp(Tkj(i,j,k,w)));
                    }
            }
            result = result+tmp;
    }
    return result;
}

int main()
{
    Input();
    Initial();
    float w2[2000] = { 0 };
    float b = pow(0.1,5);
    int times = 0;
    while (!End()&&times<=30000)
    {
            times++;
            cout<<times<<endl;
            for (int i = 0; i < 2000; i++)
            {
                    e[i] = En(i);
                    w2[i] = w[i] - b*e[i];
            }
            if (Ex(w2)<=Ex(w))//better
            {
                    b = b * 2;
                    for (int i = 0; i < 2000; i++)
                            w[i] = w2[i];
            }
            else//worser
            {
                    b = b / 2;
            }
    }
    ofstream fout("/home/w.txt");
    for(int i=0;i<2000;i++)
    {
            fout<<w[i]<<' ';
    }
    fout.close();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

在OpenGL的C API中,为了使用或修改对象,必须首先将其绑定*。

显然,在调用pr.setUniformValue更改统一值之前,pr不绑定glUniform。虽然有点不方便且不直观,但这是可以理解的;一遍又一遍地冗余地绑定同一个着色器会产生性能开销。

所以只需将pr.bind()移到您调用pr.setUniformValue的位置上方。

* EXT_direct_state_access 扩展允许您修改对象而不绑定它们,但需要不同的API,并且不保证在4.5(最新版本)之前出现在OpenGL版本中。