2017-08-20 3 views
0

J'essaie d'incorporer à la fois le mappage de mappage normal & en un seul programme, mais j'ai du mal à le faire correctement. Je travaille sur un exercice simple pour m'aider avec cela avant de passer à quelque chose de plus complexe. J'essaye de rendre ces deux objets dans un seul programme. Ils ont tous les deux des textures différentes et le tore utilise le mappage des cubes alors que le mur utilise la cartographie normale.OPENGL Comment rendre correctement ces 2 objets avec des textures/mappages différents?

Ce sont ce qu'ils sont censés ressembler individuellement:

object 1

object 2

Actuellement, ce que j'ai. Le tore est correctement rendu mais les textures du mur n'apparaissent pas.

3

J'utilise 2 programmes de shaders séparés pour cela, et il est ma première fois avec plus de 1 programme de shaders, pour un programme. Je soupçonne que mon problème pourrait être avec l'initialisation des variables shader, ou quelque chose de vraiment évident que je ne reçois tout simplement pas. J'utilise deux structures de Vertex différentes pour les objets.

struct Vertex2 
{ 
    GLfloat position[3]; 
    GLfloat normal[3]; 
    GLfloat tangent[3]; 
    GLfloat texCoord[2]; 
}; 

Vertex2 g_vertices[] = { 
    // Front: triangle 1 
    // vertex 1 
    -1.0f, 1.0f, 0.0f, // position 
    0.0f, 0.0f, 1.0f, // normal 
    1.0f, 0.0f, 0.0f, // tangent 
    0.0f, 1.0f,   // texture coordinate 
    // vertex 2 
    -1.0f, -1.0f, 0.0f, // position 
    0.0f, 0.0f, 1.0f, // normal 
    1.0f, 0.0f, 0.0f, // tangent 
    0.0f, 0.0f,   // texture coordinate 
    // vertex 3 
    1.0f, 1.0f, 0.0f, // position 
    0.0f, 0.0f, 1.0f, // normal 
    1.0f, 0.0f, 0.0f, // tangent 
    1.0f, 1.0f,   // texture coordinate 

    // triangle 2 
    // vertex 1 
    1.0f, 1.0f, 0.0f, // position 
    0.0f, 0.0f, 1.0f, // normal 
    1.0f, 0.0f, 0.0f, // tangent 
    1.0f, 1.0f,   // texture coordinate 
    // vertex 2 
    -1.0f, -1.0f, 0.0f, // position 
    0.0f, 0.0f, 1.0f, // normal 
    1.0f, 0.0f, 0.0f, // tangent 
    0.0f, 0.0f,   // texture coordinate 
    // vertex 3 
    1.0f, -1.0f, 0.0f, // position 
    0.0f, 0.0f, 1.0f, // normal 
    1.0f, 0.0f, 0.0f, // tangent 
    1.0f, 0.0f,   // texture coordinate 
}; 

Main.cpp fonction init:

static void init(GLFWwindow* window) 
{ 
    glEnable(GL_DEPTH_TEST); // enable depth buffer test 
    glEnable(GL_TEXTURE_2D); 

    // read the image data 
    GLint imageWidth[5];   //image width info 
    GLint imageHeight[5];   //image height info 

    g_texImage[FRONT] = readBitmapRGBImage("images/cm_front.bmp", &imageWidth[0], &imageHeight[0]); 
    g_texImage[BACK] = readBitmapRGBImage("images/cm_back.bmp", &imageWidth[0], &imageHeight[0]); 
    g_texImage[LEFT] = readBitmapRGBImage("images/cm_left.bmp", &imageWidth[0], &imageHeight[0]); 
    g_texImage[RIGHT] = readBitmapRGBImage("images/cm_right.bmp", &imageWidth[0], &imageHeight[0]); 
    g_texImage[TOP] = readBitmapRGBImage("images/cm_top.bmp", &imageWidth[0], &imageHeight[0]); 
    g_texImage[BOTTOM] = readBitmapRGBImage("images/cm_bottom.bmp", &imageWidth[0], &imageHeight[0]); 
    g_texImage[6] = readBitmapRGBImage("images/Fieldstone.bmp", &imageWidth[1], &imageHeight[1]); 
    g_texImage[7] = readBitmapRGBImage("images/FieldstoneBumpDOT3.bmp", &imageWidth[2], &imageHeight[2]); 

    glGenTextures(10, g_textureID);     

    // ... 

    // create and compile our GLSL program from the shader files 
    g_shaderProgramID[0] = loadShaders("CubeEnvMapVS.vert", "CubeEnvMapFS.frag"); 
    g_shaderProgramID[1] = loadShaders("NormalMappingVS.vert", "NormalMappingFS.frag"); 

    // find the location of shader variables 
    for (int i = 0; i < 2; i++) 
    { 
     positionIndex[i] = glGetAttribLocation(g_shaderProgramID[i], "aPosition"); 
     normalIndex[i] = glGetAttribLocation(g_shaderProgramID[i], "aNormal"); 
     texCoordIndex[i] = glGetAttribLocation(g_shaderProgramID[i], "aTexCoord"); 

     g_MVP_Index[i] = glGetUniformLocation(g_shaderProgramID[i], "uModelViewProjectionMatrix"); 
     g_M_Index[i] = glGetUniformLocation(g_shaderProgramID[i], "uModelMatrix"); 
     g_viewPointIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uViewPoint"); 

     g_lightPositionIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.position"); 
     g_lightAmbientIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.ambient"); 
     g_lightDiffuseIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.diffuse"); 
     g_lightSpecularIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.specular"); 
     g_lightShininessIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.shininess"); 

     g_materialAmbientIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uMaterialProperties.ambient"); 
     g_materialDiffuseIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uMaterialProperties.diffuse"); 
     g_materialSpecularIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uMaterialProperties.specular"); 
    } 

    g_envMapSamplerIndex = glGetUniformLocation(g_shaderProgramID[0], "uEnvironmentMap"); 
    tangentIndex = glGetAttribLocation(g_shaderProgramID[1], "aTangent"); 
    g_texSamplerIndex = glGetUniformLocation(g_shaderProgramID[1], "uTextureSampler"); 
    g_normalSamplerIndex = glGetUniformLocation(g_shaderProgramID[1], "uNormalSampler"); 

    // initialise model matrix to the identity matrix 
    g_mm_torus = glm::mat4(1.0f); 
    g_mm_wall = mat4(1.0f); 

    // ... 

    // load mesh 
    // load_mesh("models/sphere.obj"); 
    load_mesh("models/torus.obj"); 

    // ... 

    // generate identifier for VBOs and copy data to GPU 
    glGenBuffers(5, g_VBO); 
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*g_numberOfVertices, g_pMeshVertices, GL_STATIC_DRAW); 

    // generate identifier for IBO and copy data to GPU 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_VBO[1]); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * 3 * g_numberOfFaces, g_pMeshIndices, GL_STATIC_DRAW); 

    // generate identifiers for VAO 
    glGenVertexArrays(5, g_VAO); 

    // create VAO and specify VBO data 
    glBindVertexArray(g_VAO[0]); 
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_VBO[1]); 
    glVertexAttribPointer(positionIndex[0], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position))); 
    glVertexAttribPointer(normalIndex[0], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal))); 

    glEnableVertexAttribArray(positionIndex[0]); // enable vertex attributes 
    glEnableVertexAttribArray(normalIndex[0]); 

    // generate identifier for VBOs and copy data to GPU 
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices), g_vertices, GL_STATIC_DRAW); 

    // create VAO and specify VBO data 
    glBindVertexArray(g_VAO[1]); 
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]); 
    glVertexAttribPointer(positionIndex[1], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast<void*>(offsetof(Vertex2, position))); 
    glVertexAttribPointer(normalIndex[1], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast<void*>(offsetof(Vertex2, normal))); 
    glVertexAttribPointer(tangentIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast<void*>(offsetof(Vertex2, tangent))); 
    glVertexAttribPointer(texCoordIndex[0], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast<void*>(offsetof(Vertex2, texCoord))); 

    // enable vertex attributes 
    glEnableVertexAttribArray(positionIndex[1]); 
    glEnableVertexAttribArray(normalIndex[1]); 
    glEnableVertexAttribArray(tangentIndex); 
    glEnableVertexAttribArray(texCoordIndex[0]); 
} 

Rendu fonction de scène:

static void render_scene() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear colour buffer and depth buffer 

    glUseProgram(g_shaderProgramID[0]); // use the shaders associated with the shader program 

    glBindVertexArray(g_VAO[0]);  // make VAO active 

    // set uniform shader variables 
    glm::mat4 MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_torus; 
    glUniformMatrix4fv(g_MVP_Index[0], 1, GL_FALSE, &MVP[0][0]); 
    glUniformMatrix4fv(g_M_Index[0], 1, GL_FALSE, &g_mm_torus[0][0]); 

    glUniform3fv(g_viewPointIndex[0], 1, &g_camera.getPosition()[0]); 
    glUniform4fv(g_lightPositionIndex[0], 1, &g_lightProperties.position[0]); 
    glUniform4fv(g_lightAmbientIndex[0], 1, &g_lightProperties.ambient[0]); 
    glUniform4fv(g_lightDiffuseIndex[0], 1, &g_lightProperties.diffuse[0]); 
    glUniform4fv(g_lightSpecularIndex[0], 1, &g_lightProperties.specular[0]); 
    glUniform1fv(g_lightShininessIndex[0], 1, &g_lightProperties.shininess); 

    glUniform4fv(g_materialAmbientIndex[0], 1, &g_materialProperties.ambient[0]); 
    glUniform4fv(g_materialDiffuseIndex[0], 1, &g_materialProperties.diffuse[0]); 
    glUniform4fv(g_materialSpecularIndex[0], 1, &g_materialProperties.specular[0]); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_CUBE_MAP, g_textureID[0]); 
    glUniform1i(g_envMapSamplerIndex, 0); 

    glDrawElements(GL_TRIANGLES, g_numberOfFaces * 3, GL_UNSIGNED_INT, 0); // display the vertices based on their indices and primitive type 

    glUseProgram(g_shaderProgramID[1]); // use the shaders associated with the shader program 

    glBindVertexArray(g_VAO[1]);  // make VAO active 

    // set uniform shader variables 
    glClear(GL_DEPTH_BUFFER_BIT); 
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_wall; 
    glUniformMatrix4fv(g_MVP_Index[1], 1, GL_FALSE, &MVP[0][0]); 
    glUniformMatrix4fv(g_M_Index[1], 1, GL_FALSE, &g_mm_wall[0][0]); 

    glUniform3fv(g_viewPointIndex[1], 1, &g_camera.getPosition()[0]); 
    glUniform4fv(g_lightPositionIndex[1], 1, &g_lightProperties.position[0]); 
    glUniform4fv(g_lightAmbientIndex[1], 1, &g_lightProperties.ambient[0]); 
    glUniform4fv(g_lightDiffuseIndex[1], 1, &g_lightProperties.diffuse[0]); 
    glUniform4fv(g_lightSpecularIndex[1], 1, &g_lightProperties.specular[0]); 
    glUniform1fv(g_lightShininessIndex[1], 1, &g_lightProperties.shininess); 

    glUniform4fv(g_materialAmbientIndex[1], 1, &g_materialProperties.ambient[0]); 
    glUniform4fv(g_materialDiffuseIndex[1], 1, &g_materialProperties.diffuse[0]); 
    glUniform4fv(g_materialSpecularIndex[1], 1, &g_materialProperties.specular[0]); 

    glActiveTexture(GL_TEXTURE1); 
    glBindTexture(GL_TEXTURE_2D, g_textureID[6]); 

    glActiveTexture(GL_TEXTURE2); 
    glBindTexture(GL_TEXTURE_2D, g_textureID[7]); 

    glUniform1i(g_texSamplerIndex, 1); 
    glUniform1i(g_normalSamplerIndex, 2); 

    glDrawArrays(GL_TRIANGLES, 0, 36); 

    glFlush(); // flush the pipeline 
} 

Vertex shader pour tore:

#version 330 core 

// input data (different for all executions of this shader) 
in vec3 aPosition; 
in vec3 aNormal; 

// uniform input data 
uniform mat4 uModelViewProjectionMatrix; 
uniform mat4 uModelMatrix; 

// output data (will be interpolated for each fragment) 
out vec3 vNormal; 
out vec3 vPosition; 

void main() 
{ 
    // set vertex position 
    gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0); 

    // world space 
    vPosition = (uModelMatrix * vec4(aPosition, 1.0)).xyz; 
    vNormal = (uModelMatrix * vec4(aNormal, 0.0)).xyz; 
} 

shader Fragment de tore:

#version 330 core 

// interpolated values from the vertex shaders 
in vec3 vNormal; 
in vec3 vPosition; 

// uniform input data 
struct LightProperties 
{ 
    vec4 position; 
    vec4 ambient; 
    vec4 diffuse; 
    vec4 specular; 
    float shininess; 
}; 

struct MaterialProperties 
{ 
    vec4 ambient; 
    vec4 diffuse; 
    vec4 specular; 
}; 

uniform LightProperties uLightingProperties; 
uniform MaterialProperties uMaterialProperties; 
uniform vec3 uViewPoint; 

uniform samplerCube uEnvironmentMap; 

// output data 
out vec3 fColor; 

void main() 
{ 
    vec3 N = normalize(vNormal); 
    vec3 L; 

    // determine whether the light is a point light source or directional light 
    if(uLightingProperties.position.w == 0.0f) 
     L = normalize((uLightingProperties.position).xyz); 
    else 
     L = normalize((uLightingProperties.position).xyz - vPosition); 

    vec3 V = normalize(uViewPoint - vPosition); 
    vec3 R = reflect(-L, N); 

    // calculate the ambient, diffuse and specular components 
    vec4 ambient = uLightingProperties.ambient * uMaterialProperties.ambient; 
    vec4 diffuse = uLightingProperties.diffuse * uMaterialProperties.diffuse * max(dot(L, N), 0.0); 
    vec4 specular = vec4(0.0f, 0.0f, 0.0f, 1.0f); 

    if(dot(L, N) > 0.0f) 
    { 
     specular = uLightingProperties.specular * uMaterialProperties.specular 
      * pow(max(dot(V, R), 0.0), uLightingProperties.shininess); 
    } 

    vec3 reflectEnvMap = reflect(-V, N); 

    // set output color 
    fColor = texture(uEnvironmentMap, reflectEnvMap).rgb; 

    fColor *= (diffuse + specular + ambient).rgb; 
} 

Vertex shader pour mur:

#version 330 core 

// input data (different for all executions of this shader) 
in vec3 aPosition; 
in vec3 aNormal; 
in vec3 aTangent; 
in vec2 aTexCoord; 

// uniform input data 
uniform mat4 uModelViewProjectionMatrix; 
uniform mat4 uModelMatrix; 

// output data (will be interpolated for each fragment) 
out vec3 vPosition; 
out vec3 vNormal; 
out vec3 vTangent; 
out vec2 vTexCoord; 

void main() 
{ 
    // set vertex position 
    gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0); 

    // world space 
    vPosition = (uModelMatrix * vec4(aPosition, 1.0)).xyz; 
    vNormal = (uModelMatrix * vec4(aNormal, 0.0)).xyz; 
    vTangent = (uModelMatrix * vec4(aTangent, 0.0)).xyz; 
    vTexCoord = aTexCoord; 
} 

shader Fragment pour mur:

#version 330 core 

// interpolated values from the vertex shaders 
in vec3 vPosition; 
in vec3 vNormal; 
in vec3 vTangent; 
in vec2 vTexCoord; 

// uniform input data 
struct LightProperties 
{ 
    vec4 position; 
    vec4 ambient; 
    vec4 diffuse; 
    vec4 specular; 
    float shininess; 
}; 

struct MaterialProperties 
{ 
    vec4 ambient; 
    vec4 diffuse; 
    vec4 specular; 
}; 

uniform LightProperties uLightingProperties; 
uniform MaterialProperties uMaterialProperties; 
uniform vec3 uViewPoint; 

uniform sampler2D uTextureSampler; 
uniform sampler2D uNormalSampler; 

// output data 
out vec3 fColor; 

void main() 
{ 
    // calculate normal map vectors 
    vec3 normal = normalize(vNormal); 
    vec3 tangent = normalize(vTangent); 
    vec3 biTangent = normalize(cross(tangent, normal)); 

    vec3 normalMap = 2.0f * texture(uNormalSampler, vTexCoord).xyz - 1.0f; 

    // calculate vectors for lighting 
    vec3 N = normalize(mat3(tangent, biTangent, normal) * normalMap); 
    vec3 L; 

    // determine whether the light is a point light source or directional light 
    if(uLightingProperties.position.w == 0.0f) 
     L = normalize((uLightingProperties.position).xyz); 
    else 
     L = normalize((uLightingProperties.position).xyz - vPosition); 

    vec3 V = normalize(uViewPoint - vPosition); 
    vec3 R = reflect(-L, N); 

    // calculate Phong lighting 
    vec4 ambient = uLightingProperties.ambient * uMaterialProperties.ambient; 
    vec4 diffuse = uLightingProperties.diffuse * uMaterialProperties.diffuse * max(dot(L, N), 0.0); 
    vec4 specular = vec4(0.0f, 0.0f, 0.0f, 1.0f); 

    if(dot(L, N) > 0.0f) 
    { 
     specular = uLightingProperties.specular * uMaterialProperties.specular 
      * pow(max(dot(V, R), 0.0), uLightingProperties.shininess); 
    } 

    // set output color 
    fColor = (diffuse + specular + ambient).rgb;  
    fColor *= texture(uTextureSampler, vTexCoord).rgb; 
} 

PS: Désolé si je suis un peu trop irresponsable avec mes questions hier. Certains des conseils que je n'ai pas compris et n'ont donc pas répondu.

+0

Voulez-vous envelopper la carte normale autour du tore? Est-ce que le tore a des coordonnées de texture? – Rabbid76

+0

@ Rabbid76 J'essaie d'obtenir une carte de cube pour le tore et une carte normale pour le mur. Puis-je le faire avec 2 programmes de shader séparés comme ci-dessus? – gremolada

+1

Je ne suis pas sûr de ce que vous demandez. Voulez-vous mélanger les 2 images ci-dessus ou voulez-vous un tore avec la réflexion et la cartographie normale? – Rabbid76

Répondre

1

Lorsque vous dessinez la 2ème partie (mur), vous liez les textures aux unités de texture GL_TEXTURE1 et GL_TEXTURE2:

glActiveTexture(GL_TEXTURE1); 
glBindTexture(GL_TEXTURE_2D, g_textureID[6]); 

glActiveTexture(GL_TEXTURE2); 
glBindTexture(GL_TEXTURE_2D, g_textureID[7]); 

Mais vous définissez l'unité de texture indices 0 et 1 à la texture uniformes sampler uTextureSampler et uNormalSampler:

glUniform1i(g_texSamplerIndex, 0); 
glUniform1i(g_normalSamplerIndex, 1);` 

Adapt votre code comme ceci:

glUniform1i(g_texSamplerIndex, 1); // GL_TEXTURE1 
glUniform1i(g_normalSamplerIndex, 2); // GL_TEXTURE2 


Futher l'indice d'attribut de "aTexCoord" est stocké à texCoordIndex[i] pour g_shaderProgramID[i]:

for (int i = 0; i < 2; i++) 
{ 
    .... 
    texCoordIndex[i] = glGetAttribLocation(g_shaderProgramID[i], "aTexCoord"); 
    ..... 
} 

Vous devez être conscient de cela quand mettre en place le pointeur d'attribut de sommet et permettre au sommet d'attribut

Change

glVertexAttribPointer(texCoordIndex[1], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast<void*>(offsetof(Vertex2, texCoord))); 
..... 
glEnableVertexAttribArray(texCoordIndex[1]); 
+0

Ah merci j'ai changé ça mais ça ne rend malheureusement toujours pas. Est-ce parce que j'ai appelé glClear (GL_DEPTH_BUFFER_BIT); avant ça? Parce que si je ne le fais pas, même le carré noir n'apparaît pas. – gremolada

+0

@gremolada Non, 'glClear (GL_DEPTH_BUFFER_BIT)' est correct, si vous voulez dessiner le mur au-dessus du tore. – Rabbid76

+0

Avez-vous essayé de dessiner uniquement la texture, pour des raisons de débogage (sans mappage normal et sans lumière?) FColor = texture (uTextureSampler, vTexCoord) .rgb; ' – Rabbid76