gpt4 book ai didi

c++ - OPENGL 如何正确渲染这两个具有不同纹理/贴图的对象?

转载 作者:行者123 更新时间:2023-11-28 05:01:35 28 4
gpt4 key购买 nike

我试图将法线贴图和立方体贴图合并到一个程序中,但我无法正确渲染它们。在进行更复杂的事情之前,我正在做一个简单的练习来帮助我解决这个问题。我试图将这两个对象渲染到一个程序中。它们都有不同的纹理,环面使用立方体贴图,而墙使用法线贴图。

这些是他们应该单独看起来的样子:

object 1

object 2

目前,这就是我所拥有的。环面渲染正确,但没有显示墙的纹理。

3

我为此使用了 2 个单独的着色器程序,这是我第一次为一个程序使用多个着色器程序。我怀疑我的问题可能与着色器变量的初始化有关,或者是我没有得到的非常明显的问题。我为对象使用了两种不同的顶点结构。

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:对不起,如果我昨天的问题有点太不负责任了。有些建议我就是看不懂所以没有回复。

最佳答案

当您绘制第二部分(墙)时,您会将纹理绑定(bind)到纹理单元 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" 的属性索引存储到 texCoordIndex[i] for g_shaderProgramID[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]);

关于c++ - OPENGL 如何正确渲染这两个具有不同纹理/贴图的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45784493/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com