我似乎打破了程序中的着色器,这是他们的代码:
顶点着色器
#version 330 core
uniform mat4 camera;
uniform mat4 model;
layout(location = 0) in vec3 vert;
layout(location = 1) in vec3 vertNormal;
out vec3 fragVert;
out vec3 fragNormal;
void main() {
// Pass some variables to the fragment shader
fragNormal = vertNormal;
fragVert = vert;
// Apply all matrix transformations to vert
gl_Position = camera * model * vec4(vert, 1);
}
片段着色器
#version 150 core
uniform mat4 model;
uniform vec3 cameraPosition;
// material settings
uniform float materialShininess;
uniform vec3 materialSpecularColor;
uniform vec3 materialColor;
uniform struct Light {
vec3 position;
vec3 intensities; //a.k.a the color of the light
float attenuation;
float ambientCoefficient;
} light;
in vec3 fragNormal;
in vec3 fragVert;
out vec4 finalColor;
void main() {
vec3 normal = normalize(transpose(inverse(mat3(model))) * fragNormal);
vec3 surfacePos = vec3(model * vec4(fragVert, 1));
vec4 surfaceColor = vec4(materialColor, 1);
vec3 surfaceToLight = normalize(light.position - surfacePos);
vec3 surfaceToCamera = normalize(cameraPosition - surfacePos);
//ambient
vec3 ambient = light.ambientCoefficient * surfaceColor.rgb * light.intensities;
//diffuse
float diffuseCoefficient = max(0.0, dot(normal, surfaceToLight));
vec3 diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities;
//specular
float specularCoefficient = 0.0;
if(diffuseCoefficient > 0.0)
specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normal))), materialShininess);
vec3 specular = specularCoefficient * materialSpecularColor * light.intensities;
//attenuation
float distanceToLight = length(light.position - surfacePos);
float attenuation = 1.0 / (1.0 + light.attenuation * pow(distanceToLight, 2));
//linear color (color before gamma correction)
vec3 linearColor = ambient + attenuation*(diffuse + specular);
//final color (after gamma correction)
vec3 gamma = vec3(1.0/2.2);
finalColor = vec4(pow(linearColor, gamma), surfaceColor.a);
}
我有一个资产,我从一个obj文件加载,然后像这样绘制它:
void OpenGLView::run()
{
initializeAndSetupWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "PhongBunny");
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
loadBunnyAsset();
AssetInstance bunny1;
bunny1.asset = bunny;
bunny1.position = glm::vec3(2.0f, 2.0f, 2.0f);
bunny1.scale = glm::vec3(1.0f, 1.0f, 1.0f);
do{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
loadUniforms(bunny1);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, bunny.vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, bunny.normalBuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bunny.elementBuffer);
glDrawElements(GL_TRIANGLES, bunny.elementsSize, GL_UNSIGNED_INT, (void*)0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glfwSwapBuffers(window);
glfwPollEvents();
} while (!glfwWindowShouldClose(window));
glfwDestroyWindow(window);
glfwTerminate();
}
这是加载制服的功能:
void OpenGLView::loadUniforms(AssetInstance assetInstance)
{
Asset* asset = &assetInstance.asset;
glUseProgram(asset->shaderProgramID);
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 1000.0f);
glm::mat4 camera = Projection * getViewMatrix();
glm::mat4 model = translate(assetInstance.position) * scale(assetInstance.position);
GLuint cameraID = glGetUniformLocation(asset->shaderProgramID, "camera");
GLuint modelID = glGetUniformLocation(asset->shaderProgramID, "model");
GLuint cameraPositionID = glGetUniformLocation(asset->shaderProgramID, "cameraPosition");
GLuint lightPositionID = glGetUniformLocation(asset->shaderProgramID, "light.position");
GLuint lightIntensitiesID = glGetUniformLocation(asset->shaderProgramID, "light.intensities");
GLuint lightAttenuationID = glGetUniformLocation(asset->shaderProgramID, "light.attenuation");
GLuint lightAmbientCoefficientID = glGetUniformLocation(asset->shaderProgramID, "light.ambientCoefficient");
GLuint materialColorID = glGetUniformLocation(asset->shaderProgramID, "materialColor");
GLuint materialShininessID = glGetUniformLocation(asset->shaderProgramID, "materialShininess");
GLuint materialSpecularColorID = glGetUniformLocation(asset->shaderProgramID, "materialSpecularColor");
glUniformMatrix4fv(cameraID, 1, GL_FALSE, &camera[0][0]);
glUniformMatrix4fv(modelID, 1, GL_FALSE, &model[0][0]);
glUniform3fv(cameraPositionID, 1, &cameraPosition[0]);
glUniform3fv(lightPositionID, 1, &light.position[0]);
glUniform3fv(lightIntensitiesID, 1, &light.intensities[0]);
glUniform1f(lightAttenuationID, light.attenuation);
glUniform1f(lightAmbientCoefficientID, light.ambientCoefficient);
glUniform3fv(materialColorID, 1, &assetInstance.materialColor[0]);
glUniform1f(materialShininessID, assetInstance.materialShininess);
glUniform3fv(materialSpecularColorID, 1, &assetInstance.materialSpecularColor[0]);
}
并在此处完成了一些设置:
OpenGLView::OpenGLView()
{
light.position = glm::vec3(0.0f, 7.0f, 3.0f);
light.intensities = glm::vec3(0.3f, 0.3, 0.3f);
light.attenuation = 0.3f;
light.ambientCoefficient = 0.005f;
cameraPosition = glm::vec3(5.0f, 3.0f, 8.0f);
}
有一段时间我把bunny1的位置设置为0,0,0导致它根本不被绘制,我无法弄清楚为什么会这样?然后,当我将其更改为1,1,1时,它开始绘制,但现在我的key_callback函数(旋转并缩放兔子)停止工作。另外,这是我的翻译和缩放功能:
glm::mat4 OpenGLView::translate(glm::vec3 position)
{
return glm::translate(glm::mat4(), position);
}
glm::mat4 OpenGLView::scale(glm::vec3 size)
{
return glm::scale(glm::mat4(), size);
}
我无法弄清楚为什么改变bunny1.position似乎会扩展兔子而不是翻译它的位置?
答案 0 :(得分:1)
改变bunny1.position时你的兔子比例变化的原因是因为你通过bunny1.position缩放你的兔子:
glm::mat4 model = translate(assetInstance.position) * scale(assetInstance.position);
这可能也是为什么兔子在将它的位置设置为(0,0,0)时会消失的原因,因为然后将它缩放到0。