2016-12-13 5 views
0

Я пытаюсь текстурировать куб модели VBO/VAO. Куб определенно рендеринга/рисуется правильно, и насколько я знаю, я делаю все необходимое для загрузки текстуры.C++ Текстура не отображается правильно: Слияние в 1 цвет

Однако, когда дело доходит до применения текстуры, оно, как представляется, занимает в среднем все цвета в текстуре, а затем применяет это среднее значение ко всему кубу. Это приводит к тому, что появляются быть «окрашены» с равнины, регулярные цвета, как показано на рисунке ниже:

это текстура;

Я в недоумении, почему это происходит. Ниже приведен код из моей инициализации, LoadTexture и отображения функций (я не пишу функцию LoadTexture):

Init Функция (только показывая код соответствующей кубы + текстуру) недействительной инициализации (void) { . . . pyramidTexture = TextureLoader :: fiLoadTexture (wstring (L "Common \ Resources \ Textures \ Sandstone.png"));

// Setup VAO for pyramid object 
    glGenVertexArrays(1, &pyramidVAO); 
    glBindVertexArray(pyramidVAO); 

// Setup VBO for vertex position data 
    glGenBuffers(1, &pyramidVertexBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, pyramidVertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(pyramidVertices), pyramidVertices, GL_STATIC_DRAW); 
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0); // attribute 0 gets data from bound VBO (so assign vertex position buffer to attribute 0) 

// Setup VBO for vertex colour data 
    glGenBuffers(1, &pyramidColourBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, pyramidColourBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(pyramidColours), pyramidColours, GL_STATIC_DRAW); 
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_TRUE, 0, (const GLvoid*)0); // attribute 1 gets colour data 

    glGenBuffers(3, &pyramidTexCoordBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, pyramidTexCoordBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(pyramidTexCoordArray), pyramidTexCoordArray, GL_STATIC_DRAW); 
    glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0); 

// Enable vertex position and colour + Texture attribute arrays 
    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 
    glEnableVertexAttribArray(3); 

// Setup VBO for face index array 
    glGenBuffers(1, &pyramidIndexBuffer); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pyramidIndexBuffer); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(pyramidVertexIndices), pyramidVertexIndices, GL_STATIC_DRAW); 

    glBindVertexArray(0); 


    glEnable(GL_NORMALIZE); // If we scale objects, ensure normal vectors are re-normalised to length 1.0 to keep lighting calculations correct (see lecture notes) 
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Best colour interpolation results 
    . 
    . 
    . 
} 

LoadTexture Функция

GLuint TextureLoader::fiLoadTexture(const wstring& textureFilePath) { 

    BOOL    fiOkay = FALSE; 
    GLuint    newTexture = 0; 
    fipImage   I; 

// Convert wstring to const char* 
    wstring_convert<codecvt_utf8<wchar_t>, wchar_t> stringConverter; 

    string S = stringConverter.to_bytes(textureFilePath); 
    const char *filename = S.c_str(); 


// Call FreeImage to load the image file 
    fiOkay = I.load(filename); 

    if (!fiOkay) { 

      cout << "FreeImagePlus: Cannot open image file.\n"; 
      return 0; 
    } 

    fiOkay = I.flipVertical(); 
    fiOkay = I.convertTo24Bits(); 

    if (!fiOkay) { 

      cout << "FreeImagePlus: Conversion to 24 bits successful.\n"; 
      return 0; 
    } 

    auto w = I.getWidth(); 
    auto h = I.getHeight(); 

    BYTE *buffer = I.accessPixels(); 

    if (!buffer) { 

      cout << "FreeImagePlus: Cannot access bitmap data.\n"; 
      return 0; 
    } 


    glGenTextures(1, &newTexture); 
    glBindTexture(GL_TEXTURE_2D, newTexture); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, buffer); 

    // Setup default texture properties 
    if (newTexture) { 

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
    } 

    return newTexture; 
} 

Дисплей Функция

void display(void) { 

    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // Set viewport to the client area of the current window 
    glViewport(0, 0, glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)); 

    // Get view-projection transform as a GUMatrix4 
    GUMatrix4 T = mainCamera->projectionTransform() * mainCamera->viewTransform(); 

    if (principleAxes) 
     principleAxes->render(T); 

    if (texturedQuad) 
      texturedQuad->render(T * GUMatrix4::translationMatrix(0.5f, 0.5f, 0.0f)); 


// Fixed function rendering (Compatability profile only) - use this since CGImport is written against OpenGL 2.1 
    glUseProgram(0); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glMultMatrixf((const float*)mainCamera->projectionTransform().M); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glMultMatrixf((const float*)mainCamera->viewTransform().M); 
    glMultMatrixf((const float*)GUMatrix4::translationMatrix(0.0f, -0.15f, 0.0f).M); 

    glEnable(GL_TEXTURE_2D); 

    glPolygonMode(GL_FRONT, GL_FILL); 

    if (exampleModel) 
     exampleModel->renderTexturedModel(); 

    glDisable(GL_TEXTURE_2D); 

    //Define position and direction (so appear at fixed point in scene) 
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDirection); 
    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); 

    // enable texturing 
    glEnable(GL_TEXTURE_2D); 


    glEnable(GL_LIGHTING); 


    glEnable(GL_LIGHT0); 
// 
// Pyramid VBO rendering 
// 

    // Use basic shader for rendering pyramid (we'll look at this in more detail next week) 
    glUseProgram(basicShader); 

    static GLint mvpLocationPyramid = glGetUniformLocation(basicShader, "mvpMatrix"); 

    glUniformMatrix4fv(mvpLocationPyramid, 1, GL_FALSE, (const GLfloat*)&(T.M)); 

    GUMatrix4 pyramidModelTransform = GUMatrix4::translationMatrix(-5.75f, 0.0f, 0.0f) * GUMatrix4::scaleMatrix(2.0f, 2.0f, 2.0f); 
    GUMatrix4 mvpPyramid = T * pyramidModelTransform; 
    glUniformMatrix4fv(mvpLocationPyramid, 1, GL_FALSE, (const GLfloat*)&(mvpPyramid.M)); 

    // Bind VAO that contains all relevant pyramid VBO buffer and attribute pointer bindings 
    glBindVertexArray(pyramidVAO); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, pyramidTexture); 
    // Draw pyramid 
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, (const GLvoid*)0); 

    // Unbind pyramid VAO (or bind another VAO) 
    glBindVertexArray(0); 


    glutSwapBuffers(); 
} 

Я пытался исправить это в течение нескольких часов в настоящее время без каких-либо удачи, как таковой любой suppo rt будет оценен по весу !!!

EDIT: Добавлена ​​в ВАО атрибуты + шейдеры

ВАО Настройки

// Per-vertex position vectors 
static float pyramidVertices[32] = 
{ 
    //Front 
    0.0f, 0.0f, 0.0f, 1.0f, //BtmLeft 
    1.0f, 0.0f, 0.0f, 1.0f, //BtmRight 
    1.0f, 1.0f, 0.0f, 1.0f, //TopRight 
    0.0f, 1.0f, 0.0f, 1.0f, //TopLeft 
    //Back 
    0.0f, 1.0f, 1.0f, 1.0f, //TopLeft 
    1.0f, 1.0f, 1.0f, 1.0f, //TopRight 
    1.0f, 0.0f, 1.0f, 1.0f, //BottomRight 
    0.0f, 0.0f, 1.0f, 1.0f //BottomLeft 
}; 


// Per-vertex colours (RGBA) floating point values 
static float pyramidColours[32] = 
{ 
    1.0f, 0.0f, 0.0f, 1.0f, 
    0.0f, 1.0f, 0.0f, 1.0f, 
    0.0f, 0.0f, 1.0f, 1.0f, 
    1.0f, 0.0f, 1.0f, 1.0f, 
    0.0f, 1.0f, 1.0f, 1.0f, 
    0.0f, 0.0f, 1.0f, 1.0f, 
    1.0f, 0.0f, 1.0f, 1.0f, 
    1.0f, 0.0f, 0.0f, 1.0f 
}; 

// 5 faces each with 3 vertices (each face forms a triangle) 
static unsigned short pyramidVertexIndices[36] = 
{ 
    //Front 
    0, 3, 2, 
    2, 1, 0, 
    //Right 
    4, 3, 0, 
    0, 7, 4, 
    //Back 
    4, 7, 6, 
    6, 5, 4, 
    //Top 
    4, 5, 3, 
    3, 5, 2, 
    //Left 
    2, 5, 1, 
    1, 5, 6, 
    //Bottom 
    6, 7, 0, 
    0, 1, 6 
}; 


static unsigned short pyramidTexCoordArray[24] = 
{ 
    -1.0f, -1.0f, -1.0f, 
    1.0f, -1.0f, -1.0f, 
    1.0f, 1.0f, -1.0f, 
    -1.0f, 1.0f, -1.0f, 
    -1.0f, -1.0f, 1.0f, 
    1.0f, -1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f, 1.0f 
}; 

Vertex Shader

#version 330 

uniform mat4 mvpMatrix; 

layout (location=0) in vec4 vertexPos; 
layout (location=3) in vec2 vertexTexCoord; 

out vec2 texCoord; 

void main(void) { 

    mat4 M; 
    M[0] = vec4(1.0); 

    ivec2 a = ivec2(1, 2); 
    //vec3 b = vec3(2.0, 4.0, 1.0) + a; 

    texCoord = vertexTexCoord; 
    gl_Position = mvpMatrix * vertexPos; 
} 

Фрагмент Shader

#version 330 

uniform sampler2D texture; 

in vec2 texCoord; 

layout (location=0) out vec4 fragColour; 

void main(void) { 

    vec4 texColor = texture2D(texture, texCoord); 
    fragColour = texColor; 

} 
+1

Без просмотра координат текстуры, которые вы используете, и ваших шейдеров мы не можем помочь. – ybungalobill

+1

Не могли бы вы предоставить данные ячейки и шейдерный источник? – SporreKing

+0

Извините, я знал, что что-то забыл. Данные были добавлены на дно с шейдерами. – NeoKuro

ответ

2

Вы определили ваши данные как unsigned short:

static unsigned short pyramidTexCoordArray[24] 

Но это должно быть float.

+0

Это должно быть? Что делать, если используется GL_UNSIGNED_SHORT? – eldo

+0

OP инициализирует его данными с плавающей запятой и интерпретирует его как float и фактически сохраняет отрицательные значения, поэтому да, это должно быть 'float'. – ybungalobill

+0

Это исправило мою проблему! Спасибо огромное! – NeoKuro

1

Есть много вещей странно:

Вы генерируете 3 РВО для текстурных координат, но только с помощью одного. Если pyramidTexCoordBuffer имеет тип GLuint [3] (который, я полагаю, не из-за &), вы пишете границы.

Изменить: Это относится к glGenBuffers(3, &pyramidTexCoordBuffer); линии, которая выделяет 3 буфера и сохраняет их в трех последовательных GLuint переменных, начиная с pyramidTexCoordBuffer. С pyramidTexCoordBuffer, скорее всего, GLuint, pyramidTexCoordBuffer[1] и pyramidTexCoordBuffer[2] относятся к нераспределенной памяти.

массив pyramidTexCoordArray указан как unsigned short, но вы пишете на нем поплавки. Так как он неподписан, по крайней мере отрицательные числа исчезнут.

Кроме того, вы говорите OpenGL с

glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0); 

линии, что данные имеет тип GL_FLOAT (которой нет), и что она имеет два поплавка для каждой вершины (но данные есть 3 элементов на вершине) :

+0

Он не использует 3 VBOs для координат текстуры? Он использует 3 VBOs, но для разных данных. – SporreKing

+0

Если я правильно понимаю VAO/VBO, я использую 1 VBO для хранения положений вершин, 1 VBO для цвета, 1 для TextureCoords. Но изменение неподписанного короткого замыкания на поплавок зафиксировало его, и текстура теперь правильно отображается, так что спасибо вам большое! Я также был не уверен, почему (или если) мне нужны 3 набора коордов (я думал, что текстурные коорды были u, v, поэтому я удалил третьи значения, и все еще кажется, что это работает. Просто нужно разработать правильные комбинации сейчас :)) – NeoKuro

+0

Я ссылался на эту строку: 'glGenBuffers (3, & pyramidTexCoordBuffer);', которая выделяет 3 буфера и хранит их в трех последовательных переменных 'GLuint', начиная с' pyramidTexCoordBuffer'. Поскольку 'pyramidTexCoordBuffer' является, скорее всего,' GLuint', 'pyramidTexCoordBuffer [1]' и 'pyramidTexCoordBuffer [2]' относится к нераспределенной памяти. Я также добавил это к вопросу. – BDL

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

  • Нет связанных вопросов^_^