我在着色逻辑中添加了着色器,但似乎无法弄清楚出了什么问题。在此之前,它还不错,但是现在我什么也没画。我检查以确保着色器已编译并成功链接。
这是我的渲染代码Scene :: Render():
// This block renders each object in the scene
for (auto it = objects_.begin(); it != objects_.end(); it++) {
Renderer* r = it->get_renderer();
GLuint* shader = r->get_material()->get_shader();
glUseProgram(*shader);
glBindBuffer(GL_ARRAY_BUFFER, *r->get_vertex_buffer());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *r->get_index_buffer());
GLuint position_attrib = glGetUniformLocation(*shader, "position");
GLuint normal_attrib = glGetUniformLocation(*shader, "normal");
GLuint color_attrib = glGetUniformLocation(*shader, "color");
glEnableVertexAttribArray(position_attrib);
glEnableVertexAttribArray(normal_attrib);
glEnableVertexAttribArray(color_attrib);
glVertexAttribPointer(position_attrib, 4, GL_FLOAT, GL_FALSE, sizeof(engine::Vertex), (char*)NULL);
glVertexAttribPointer(normal_attrib, 4, GL_FLOAT, GL_FALSE, sizeof(engine::Vertex), (char*)NULL + 16);
glVertexAttribPointer(color_attrib, 4, GL_FLOAT, GL_FALSE, sizeof(engine::Vertex), (char*)NULL + 32);
// Set up transformation matrices for shader
glm::mat4 model = (*it).get_transform();
glm::mat4 view = main_.get_view();
glm::mat4 model_view = view * model;
glm::mat4 model_view_projection = main_.get_projection() * model_view;
glm::mat4 normal = glm::transpose(glm::inverse(model_view));
// Send light to shader
auto ambient = light_.get_ambient();
glUniform4f(glGetUniformLocation(*shader, "light_ambient"), ambient[0], ambient[1], ambient[2], ambient[3]);
auto diffuse = light_.get_diffuse();
glUniform4f(glGetUniformLocation(*shader, "light_diffuse"), diffuse[0], diffuse[1], diffuse[2], diffuse[3]);
auto specular = light_.get_specular();
glUniform4f(glGetUniformLocation(*shader, "light_specular"), specular[0], specular[1], specular[2], specular[3]);
auto position = light_.get_position();
glUniform4f(glGetUniformLocation(*shader, "light_position"), position[0], position[1], position[2], position[3]);
// Send material to shader
ambient = r->get_material()->get_ambient();
glUniform4f(glGetUniformLocation(*shader, "mat_ambient"), ambient[0], ambient[1], ambient[2], ambient[3]);
diffuse = r->get_material()->get_diffuse();
glUniform4f(glGetUniformLocation(*shader, "mat_diffuse"), diffuse[0], diffuse[1], diffuse[2], diffuse[3]);
specular = r->get_material()->get_specular();
glUniform4f(glGetUniformLocation(*shader, "mat_specular"), specular[0], specular[1], specular[2], specular[3]);
auto shine = r->get_material()->get_shininess();
glUniform1f(glGetUniformLocation(*shader, "mat_shine"), shine[0]);
// Send transformation matrices
glUniformMatrix4fv(glGetAttribLocation(*shader, "world2eye"), 1, GL_FALSE, &view[0][0]);
glUniformMatrix4fv(glGetAttribLocation(*shader, "local2eye"), 1, GL_FALSE, &model_view[0][0]);
glUniformMatrix4fv(glGetAttribLocation(*shader, "local2clip"), 1, GL_FALSE, &model_view_projection[0][0]);
glUniformMatrix4fv(glGetAttribLocation(*shader, "normal_matrix"), 1, GL_FALSE, &normal[0][0]);
r->Draw();
}
这是主要的显示功能:
void display() {
glEnable(GL_DEPTH_TEST);
glClearColor(0.604f, 0.784f, 0.831f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
scene.Render();
glDisableClientState(GL_VERTEX_ARRAY);
glutSwapBuffers();
}
最后是顶点和片段着色器:
// default.vert
attribute vec4 position;
attribute vec4 color;
attribute vec4 normal;
varying vec4 pcolor;
uniform mat4 local2clip;
uniform mat4 local2eye;
uniform mat4 normal_matrix;
uniform mat4 world2eye;
uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 light_pos;
uniform vec4 mat_ambient;
uniform vec4 mat_diffuse;
uniform vec4 mat_specular;
uniform float mat_shine;
void main(void) {
gl_Position = local2clip * position;
vec4 ambient = light_ambient * mat_ambient;
vec3 N = normalize(vec3(normal_matrix * normal));
vec4 Lpos = world2eye * light_pos;
vec4 Vpos = local2eye * position;
vec3 L = normalize(vec3(Lpos - Vpos));
float NdotL;
if (dot(N,L) <0.0) NdotL = 0.0;
else NdotL = dot(N, L);
vec4 diffuse = light_diffuse * mat_diffuse * NdotL;
vec3 R = normalize(reflect(-L, N));
vec3 V = normalize(vec3(-Vpos));
float RdotV;
RdotV = dot(R, V);
if (NdotL == 0.0) RdotV = 0.0;
if (RdotV < 0.0) RdotV = 0.0;
vec4 specular = light_specular * mat_specular * pow(RdotV,mat_shine);
pcolor = ambient + diffuse + specular;
}
// default.frag
varying vec4 pcolor;
uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 mat_ambient;
uniform vec4 mat_diffuse;
uniform vec4 mat_specular;
uniform float mat_shine;
varying vec3 N;
varying vec3 L;
varying vec3 R;
varying vec3 V;
void main() {
vec4 ambient = light_ambient * mat_ambient;
float NdotL;
if (dot(N,L) <0.0) NdotL = 0.0;
else NdotL = dot(N, L);
float RdotV = dot(R, V);
if (NdotL == 0.0) RdotV = 0.0;
if (RdotV < 0.0) RdotV = 0.0;
vec4 diffuse = light_diffuse * mat_diffuse * NdotL;
vec4 specular = light_specular * mat_specular * pow(RdotV,mat_shine);
gl_FragColor = pcolor + ambient + diffuse + specular;
}
我最不确定着色器的实现,因为这是我目前正在学习的内容。在此之前,我使用的是
glVertexPointer
。我在display和Render的实现中使用的引用似乎有效,但是在假定它们的方法可以转移到我的实现中时,我可能会犯一些错误。 最佳答案
您应该对顶点着色器中的“位置”,“常规”和“颜色”属性使用glGetAttribLocation。
GLuint position_attrib = glGetAttribLocation(*shader, "position");
GLuint normal_attrib = glGetAttribLocation(*shader, "normal");
GLuint color_attrib = glGetAttribLocation(*shader, "color");
转换矩阵应使用glGetUniformLocation而不是glGetAttribLocation。
glUniformMatrix4fv(glGetUniformLocation(*shader, "world2eye"), 1, GL_FALSE, &view[0][0]);
glUniformMatrix4fv(glGetUniformLocation(*shader, "local2eye"), 1, GL_FALSE, &model_view[0][0]);
glUniformMatrix4fv(glGetUniformLocation(*shader, "local2clip"), 1, GL_FALSE, &model_view_projection[0][0]);
glUniformMatrix4fv(glGetUniformLocation(*shader, "normal_matrix"), 1, GL_FALSE, &normal[0][0]);
它们可能是可互换的,但我不会依靠它。
关于c++ - 引入了着色器,不再绘制,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33790989/