簡體   English   中英

OPENGL如何正確渲染具有不同紋理/映射的這兩個對象?

[英]OPENGL How do I correctly render these 2 objects with different textures/mapping?

我試圖將普通映射和多維數據集映射合並到一個程序中,但是我很難使它們正確呈現。 在進行更復雜的工作之前,我正在做一個簡單的練習來幫助我完成這項工作。 我試圖將這兩個對象渲染到一個程序中。 它們都有不同的紋理,圓環使用立方體貼圖,而牆使用法線貼圖。

這些是它們本應分別顯示的樣子:

對象1

對象2

目前,這就是我所擁有的。 圓環可以正確渲染,但牆的紋理不會出現。

3

我為此使用了2個單獨的着色器程序,這是我第一次為一個程序使用多個着色器程序。 我懷疑我的問題可能與着色器變量的初始化有關,或者確實很明顯我沒有得到。 我正在為對象使用兩種不同的Vertex結構。

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初始化函數:

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]);
}

渲染場景功能:

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
}

環形着色器的頂點着色器:

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

圓環的片段着色器:

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

牆的頂點着色器:

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

牆的片段着色器:

#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:對不起,如果我昨天對我的問題有點不負責任。 我只是不明白,因此沒有回音的一些建議。

繪制第二部分(牆)時,將紋理綁定到紋理單元GL_TEXTURE1GL_TEXTURE2

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

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

但是,您正在將紋理單元索引0和1設置為紋理采樣器制服uTextureSampleruNormalSampler

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

像這樣修改您的代碼:

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


此外,將"aTexCoord"的屬性索引存儲到g_shaderProgramID[i] texCoordIndex[i]中:

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

在設置頂點屬性指針並啟用頂點屬性時,您必須意識到這一點。

更改此:

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

對此:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM