2015-03-09 3 views
0

поэтому у меня очень простой шейдер glsl, который отображает объект с текстурой и направленным светом.Текстура OpenGL не передается через GLSL

Теперь у меня очень трудное время, чтобы получить текстуру для отображения, все остальное работает, кроме этого.

Когда я отключу шейдер (glUseProgram (0)), текстура отображается в черно-белом режиме, но когда я включаю ее, вся сетка находится в одном цвете и не текстурирована, и при изменении текстуры она меняет цвет.

это, как я загрузить мою текстуру

data = CImg<unsigned char>(src); 
glGenTextures(1, &m_textureObj); 
glBindTexture(GL_TEXTURE_2D, m_textureObj); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, data.width(), data.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, data); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

это, как я связать свою текстуру

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, m_textureObj); 

и это моя вершинный шейдер

#version 330 

layout (location = 0) in vec3 Position; 
layout (location = 1) in vec2 TexCoord; 
layout (location = 2) in vec3 Normal; 

uniform mat4 gWVP; 
uniform mat4 gWorld; 

out vec2 TexCoord0; 
out vec3 Normal0; 

void main() 
{ 
    gl_Position = (gWVP * gWorld) * vec4(Position, 1.0); 
    TexCoord0 = TexCoord; 
    Normal0 = (gWorld * vec4(Normal, 0.0)).xyz; 
} 

и это мой фрагмент шейдеры

#version 330 

in vec2 TexCoord0; 
in vec3 Normal0;                  

out vec4 FragColor;                 

struct DirectionalLight                
{                     
    vec3 Color;                  
    float AmbientIntensity;               
    float DiffuseIntensity;               
    vec3 Direction;                 
};                     

uniform DirectionalLight gDirectionalLight;           
uniform sampler2D gSampler;               

void main()                   
{                     
    vec4 AmbientColor = vec4(gDirectionalLight.Color, 1.0f) *      
        gDirectionalLight.AmbientIntensity;       

    float DiffuseFactor = dot(normalize(Normal0), -gDirectionalLight.Direction);  

    vec4 DiffuseColor;                

    if (DiffuseFactor > 0) {               
     DiffuseColor = vec4(gDirectionalLight.Color, 1.0f) *       
        gDirectionalLight.DiffuseIntensity *       
        DiffuseFactor;            
    }                    
    else {                   
     DiffuseColor = vec4(0, 0, 0, 0);            
    }                    

    FragColor = texture2D(gSampler, TexCoord0.xy) * 
      (AmbientColor + DiffuseColor); 
} 

и последнее, но не в последнюю очередь я говорю своему шейдеру использовать правильную текстуру

glUniform1i(GetUniformLocation("gSampler"), 0); 

Я сделал F **** т читать онлайн о том, как правильно это сделать простое и задачу и побежал в кучу разных конфигураций, чтобы только расстроиться.

Если кто-нибудь может указать, что я делаю неправильно, я был бы в восторге, я уверен, что мне не хватает одной глупой детали, но я не могу найти ее. пожалуйста, не обращайтесь к https://www.opengl.org/wiki/Common_Mistakes#Creating_a_complete_texture спасибо за чтение.

вот как я создаю свою сетку и загружаю ее на GPU. это конструктор вершин Vertex (х, у, г, и, v)

#define BUFFER_OFFSET(i) ((char *)NULL + (i)) 

unsigned int Indices[] = { 
     0, 3, 1, 
     1, 3, 2, 
     2, 3, 0, 
     1, 2, 0 
    }; 
    Vertex Vertices[4] = { 
     Vertex(-1.0f, -1.0f, 0.5773f, 0.0f, 0.0f), 
     Vertex(0.0f, -1.0f, -1.15475f, 0.5f, 0.0f), 
     Vertex(1.0f, -1.0f, 0.5773f, 1.0f, 0.0f), 
     Vertex(0.0f, 1.0f, 0.0f, 0.5f, 1.0f) 
    }; 
    Mesh *data = new Mesh(Vertices, 4, Indices, 12); 

    glGenBuffers(1, &vbo); 
     glGenBuffers(1, &ibo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 

      glEnableVertexAttribArray(0); 
      glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(0)); 
      glEnableVertexAttribArray(1); 
      glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(12)); 
      glEnableVertexAttribArray(2); 
      glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(24)); 

      glBufferData(GL_ARRAY_BUFFER, data->count*Vertex::Size(), data->verts, GL_STATIC_DRAW); 
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, data->indsCount*sizeof(unsigned int), data->inds, GL_STATIC_DRAW); 

    unsigned int Vertex::Size() { 
     return 32; 
    } 

/*In the update function*/ 
glDrawElements(GL_TRIANGLES, data->indsCount, GL_UNSIGNED_INT, 0); 

это моя вершина класса http://pastebin.com/iYwjEdTQ

Редактировать

Я решил его! Я привязывал вершину по-старому, а затем после того, как дротик-урод показал мне, как правильно его привязать, я заметил, что я привязывал координаты текстуры к местоположению 2, но в шейдере, в котором я искал, в местоположении 1.

glEnableVertexAttribArray(2); 
      glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(24)); 

(фраги шейдер)

layout (location = 1) in vec2 TexCoord; 

так я изменил фрагмент шейдер

layout (location = 2) in vec2 TexCoord; 

и теперь он работает прекрасно. Спасибо ratchet freak и birdypme за помощь. Я собираюсь принять ответ трещотки, потому что это привело меня к решению, но вы оба направили меня в правильном направлении.

+0

Здравствуйте, вы можете добавить код, который создает геометрию? Даже если это простой квад с 4 вершинами. Мое первоначальное чувство от симптомов заключается в том, что координаты текстуры могут быть не полностью привязаны (что намекает на то, что разные текстуры показывают разные цвета). – birdypme

+0

уверенный предмет. просто добавлено –

ответ

4

Это ваша проблема:

glEnableClientState(GL_VERTEX_ARRAY); 
glVertexPointer(3, GL_FLOAT, Vertex::Size(), BUFFER_OFFSET(0)); 
glEnableClientState(GL_NORMAL_ARRAY); 
glNormalPointer(GL_FLOAT, Vertex::Size(), BUFFER_OFFSET(12)); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
glTexCoordPointer(2, GL_FLOAT, Vertex::Size(), BUFFER_OFFSET(24)); 

Это использует старый и устаревший фиксированной функции спецификации стиля вместо этого вы тусклый использовать glVertexAttribPointer:

glEnableVertexAttribArray(0); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, Vertex::Size(), BUFFER_OFFSET(0)); 
glEnableVertexAttribArray(1); 
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, Vertex::Size(), BUFFER_OFFSET(12)); 
glEnableVertexAttribArray(2); 
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, Vertex::Size(), BUFFER_OFFSET(24)); 

Другая проблема, которую я вижу, что ваш Vertex класс не принимает нормальное значение в конструкторе. И Vertex::Size() должен быть равен sizeof(Vertex)

+0

Большое спасибо за ответ, но, к сожалению, он действительно решил проблему. У меня есть отдельный конструктор для нормалей. Это потому, что я не хочу иметь дело с нормалями на этом этапе. конструктор, который я использую, устанавливает все нормали в 0. Это вызовет проблемы? –

1

Вообще говоря, вы должны использовать sizeof() вместо жестко закодированных смещений, чтобы избежать неприятных сюрпризов.

glEnableClientState(GL_VERTEX_ARRAY); 
    glVertexPointer(3, GL_FLOAT, Vertex::Size(), BUFFER_OFFSET(0)); 
    glEnableClientState(GL_NORMAL_ARRAY); 
    glNormalPointer(GL_FLOAT, Vertex::Size(), BUFFER_OFFSET(3*sizeof(float))); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glTexCoordPointer(2, GL_FLOAT, Vertex::Size(), BUFFER_OFFSET(6*sizeof(float))); 

и vertex.h

static unsigned int Size() { 
     return 8*sizeof(float); 
    } 

Однако это вряд ли правильно ответить на ваш вопрос. Я не удаляю свой ответ, чтобы сохранить vertex.h pastebin ниже, что может быть важно, но я, вероятно, удалю его, как только будет опубликован действительный ответ.

+0

Я понимаю, почему вы думаете, что это мой класс вершин http://pastebin.com/iYwjEdTQ, извините за промахивание –

+0

Хорошо спасибо. Я просто положил свою пробку на мой вопрос. –

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