2016-12-13 7 views
0

VBO/VAOモデルキューブのテクスチャを作成しようとしています。キューブは間違いなく正しく描画/描画されており、私が知る限り、テクスチャをロードするのに必要なすべてを実行しています。C++テクスチャが正しく表示されない:1色にマージする

しかし、テクスチャを適用する場合は、テクスチャ内のすべての色の平均をとっているように見えます。その平均をキューブ全体に適用します。これは、以下のスクリーンショットに示すように、無地で定期的に色を「塗装」するように見えることになり:

これは、テクスチャです。

私はこれが起こっている理由として途方に暮れてよ。以下は私のinit、loadTextureおよび表示機能のコード(私はloadTexture関数を書いていない)である:

init関数は ボイドのinit(のみキューブ+テクスチャに関連するコードを示します) (無効){ 。 。 。 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:VAOに追加されましたが、+シェーダ属性

VAO設定

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

バーテックスシェーダ

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

フラグメントシェーダ

#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はそれを浮動小数点データで初期化し、浮動小数点として解釈し、実際に負の値を格納します。したがって、浮動小数点データでなければなりません。 – ybungalobill

+0

これは私の問題を解決しました!どうもありがとうございます! – NeoKuro

1

奇妙なことがたくさんあります:

あなたは、テクスチャ座標のための3 VBOsを生成しているが、一つだけを使用しています。 pyramidTexCoordBufferがGLuint [3]のタイプでない限り(これは&ではないと仮定しています)、範囲外です。

編集:これは3つのバッファを割り当て、pyramidTexCoordBufferから始まる3つの連続でGLuintの変数に格納しglGenBuffers(3, &pyramidTexCoordBuffer);ラインを指します。 pyramidTexCoordBufferはおそらくGLuintであるため、pyramidTexCoordBuffer[1]pyramidTexCoordBuffer[2]は未割り当てメモリを指します。

pyramidTexCoordArrayの配列はunsigned shortと指定されていますが、浮動小数点数を記述しています。符号なしなので、少なくとも負の数はなくなります。

また、あなたはデータが(それはない)タイプGL_FLOATである

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

ラインでOpenGLを伝え、それが頂点ごとに2つの浮動小数点数があること(をするが、データは頂点ごとに3つの要素を持っています) :

+0

彼はテクスチャ座標に3つのVBOを使用していませんか?彼は3つのVBOを使用していますが、異なるデータに使用しています。 – SporreKing

+0

私はVAO/VBOを正しく理解していれば、1 VBOを使って頂点位置を保存しています.1つはVBO、TextureCoordsは1です。 unsigned shortをfloatに変更すると、テクスチャが正しく表示されるようになりましたので、どうもありがとうございました!私はまた、3つの座標系が必要だったのかどうか(あるいはもしあれば)確信が持てませんでした(私はテクスチャー座標がu、vであったので3番目の値を取り除いたと思っていますが、まだ動作しています。 – NeoKuro

+0

私はこの行を参照していました: 'glGenBuffers(3、&pyramidTexCoordBuffer);'、3つのバッファを割り当て、 'pyramidTexCoordBuffer'で始まる3つの連続した' GLuint'変数に格納します。 'pyramidTexCoordBuffer'はおそらく' GLuint'なので、 'pyramidTexCoordBuffer [1]'と 'pyramidTexCoordBuffer [2]'は未割り当てメモリを指します。私はこれを質問に加えました。 – BDL

関連する問題