2013-10-25 2 views
0

Я пытаюсь отобразить pointprites в Opengl по определенному пути. Я определяю спрайт как двумерную текстуру и устанавливаю ее для использования GL_NEAREST в качестве фильтра mag/min. Я также определяю 1D текстуру, содержащую несколько 2D-координат (так что мне нужно только 1 float для спрайта, чтобы определить их расположение в пространстве экрана), которые я установил в GL_LINEAR.Использование нескольких текстур + фильтров в GLSL

Однако, когда я запускаю свою программу на своем ноутбуке, он всегда использует метод фильтра mag для спрайта-текстуры и игнорирует настройку на текстуре пути. Мой ноутбук работает под управлением Linux + mesa 9.2.1 + Opengl 3.0 на Intel Iris Pro 5200. Все работает так, как ожидалось, на моем рабочем столе, который работает под управлением Linux, и использует собственный драйвер Nvidia с opengl 4.2.

Соответствующий код

//A path "t -> (x,y)" along which we will place our sprites 
v2f path[] = {{-0.5,0.5}, 
    {-0.5,-0.5}, 
    {0.5,-0.5}, 
    {0.5,0.5}}; 
glActiveTexture(GL_TEXTURE0); 
if(glGetError() != GL_NO_ERROR) 
report(FAIL, "Couldn't activate texture!"); 

GLuint pathTex; 
glGenTextures(1, &pathTex); //create a new texture 
glBindTexture(GL_TEXTURE_1D, pathTex); //start using it as a 1D texture 
//store the coordinates of path in the texture so that we can interpolate our path in the shader. 
glTexImage1D(GL_TEXTURE_1D,0,GL_RG32F, sizeof(path)/sizeof(v2f),0,GL_RG,GL_FLOAT,path); 
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_BASE_LEVEL, 0);//We need these two lines 
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAX_LEVEL, 0);//because we don't have mipmaps. 
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//We want the path to be linearly filtered 
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//Set the min filter just to be safe. 
if(glGetError() != GL_NO_ERROR) 
report(FAIL, "Something went wrong setting up pathTex"); 
GLint uniformLoc = glGetUniformLocation(shaderProgram, "pathTexture"); //locate the uniform 
uniformLoc >= 0?glUniform1i(uniformLoc, 0):report(FAIL, "found uniform spriteTexture at %d", uniformLoc); //and set it to "0" because we're using GL_TEXTURE0 
    if(glGetError() != GL_NO_ERROR) 
    report(FAIL, "Couldn't set uniform!"); 
    report(PASS, "Setup texture for path"); 

//create and set second texture 
    rgba sprite[] = {{1.0,0,0,1},{0,1.0,0,1},{0,0,1.0,1},{1,1,0,1}}; //our sprite, a simple "red,green,blue,yellow" square. 
    glActiveTexture(GL_TEXTURE0+1); //use texUnit 1 now. 
    if(glGetError() != GL_NO_ERROR) 
    report(FAIL, "Couldn't activate texture!"); 
    GLuint spriteTex; 
    glGenTextures(1, &spriteTex); //create a new texture 
    glBindTexture(GL_TEXTURE_2D, spriteTex); //start using it as a 2D texture 
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA, 2,2,0,GL_RGBA,GL_FLOAT,sprite); //load the data again. 2x2 sprite. 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);//We need these two lines 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);//because we don't have mipmaps. 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//We want our sprites to be filtered to 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//the nearest pixel, not interpolated. 
    if(glGetError() != GL_NO_ERROR) 
    report(FAIL, "Something went wrong setting up pathTex"); 
    uniformLoc = glGetUniformLocation(shaderProgram, "spriteTexture"); //locates and set the second sampler. 
    uniformLoc >= 0?glUniform1i(uniformLoc, 1):report(FAIL, "found uniform spriteTexture at %d", uniformLoc); 
    if(glGetError() != GL_NO_ERROR) 
    report(FAIL, "Couldn't set uniform!"); 
    report(PASS, "Setup texture for sprite"); 

И моя вершина затенения

#version 130 
uniform sampler1D pathTexture; 
in float t; 
void main(){ 
    gl_Position = texture(pathTexture, t); 
} 

и мой фрагмент затенения

#version 130 
uniform sampler2D spriteTexture; 
out vec4 outputColor; 
void main() 
{ 
     outputColor = texture(spriteTexture, gl_PointCoord); 
} 

Весь код (один подал) я приклеила here , и here - скриншоты того, что я вижу на Nvidia и Inte л соответственно.

Редактировать: Я получаю те же результаты на Nvidia с контекстом 3.0.

Что может быть причиной этого?

+0

Если вы используете OpenGL 4.x, вы можете использовать Sampler Objects для хранения состояния фильтра/обертки. Вы можете привязать пробник к текстурному блоку 0, который использует ближайшую фильтрацию, а один - к текстурной единице 1, которая использует билинейную. Затем вместо использования объекта фильтра для текстуры вы можете привязать любую текстуру, которую вы хотите к единице, и вместо этого будет использовать фильтр сэмплера. Это действительно намного более элегантное решение, поскольку оно в основном превращает объекты текстуры в хранилища изображений и разделяет некоторые из состояний, которые на самом деле никогда не принадлежали им; это хорошая идея, что D3D проделал это в течение 10 лет :) –

+0

Спасибо за совет:), но я тоже пробовал его с использованием объектов сэмплера, однако я получаю те же результаты. –

+0

Теперь, когда я понимаю, что вы на самом деле пытаетесь сделать здесь, я чувствую себя обязанным указать, что выборки вершинной текстуры очень ограничены по сравнению с фрагментом. Некоторые аппаратные средства поддерживают только несколько форматов изображений на этапе вершины, линейная фильтрация не всегда аппаратно ускорена, анизотропная фильтрация ** никогда не работает в вершинном шейдере (для этого требуется знание градиентной/частичной производной, которая действительно не имеет смысла в контекст выборки по вершинам) и mipmapping тоже. У меня такое чувство, что это либо ограничение Mesa, либо аппаратное обеспечение Iris, либо, возможно, и то, и другое. –

ответ

1

Убедитесь, что вы звоните glfwInit()перед тем любые другие функции GLFW

То же самое с glewInit().

+0

Спасибо. Я исправил его, но, к сожалению, Я все равно получаю те же результаты. –

Смежные вопросы