Я занимаюсь обновлением своего кода с OpenGL 3.0 до 3.3 (или, возможно, даже с 4.x), но мне что-то не хватает, поскольку экран черный.OpenGL 3.0 до 3.2
Ближайший ответ на эту проблему: triangle in openGL 3.1 but nothing in 3.2. Решение здесь использует профиль совместимости. Единственный намек на правильное использование основного профиля - «Фактически, используя правильную последовательность команд GL-профиля с полными шейдерами вершин и фрагментов».
Проблема заключается в том, что после того, как я погрузился весь день, читая спецификации, учебные пособия и примеры, я не вижу, что мой код делает неправильно. В настоящее время я работаю над демоверсией, которая перерабатывает какой-то код, который я использую, и вы можете найти всю демоверсию, в настоящее время просто отображая треугольник на gitub.
сочные биты являются следующие:
Код вершина:
#version 150
in vec3 aVertex;
void main()
{
gl_Position = aVertex;
}
Код фрагмент:
#version 330 core
out vec4 oFragColor;
void main()
{
oFragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
Сборка шейдер выполняется, как follows:
int status = 0;
char logstr[256];
const GLchar* vbuff[1] = {vertex_code.c_str()};
unsigned int vertex_id = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_id, 1, vbuff, NULL);
glCompileShader(vertex_id);
glGetShaderInfoLog(vertex_id, 256, NULL, logstr);
glGetShaderiv(vertex_id, GL_COMPILE_STATUS, &status);
if(! status)
{
glDeleteShader(vertex_id);
throw std::runtime_error(logstr);
}
const GLchar* fbuff[1] = {fragment_code.c_str()};
unsigned int fragment_id = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_id, 1, fbuff, NULL);
glCompileShader(fragment_id);
glGetShaderInfoLog(fragment_id, 256, NULL, logstr);
glGetShaderiv(fragment_id, GL_COMPILE_STATUS, &status);
if(! status)
{
glDeleteShader(vertex_id);
glDeleteShader(fragment_id);
throw std::runtime_error(logstr);
}
program_id = glCreateProgram();
glAttachShader(program_id, vertex_id);
glAttachShader(program_id, fragment_id);
glLinkProgram(program_id);
glGetShaderInfoLog(program_id, 256, NULL, logstr);
glGetShaderiv(program_id, GL_LINK_STATUS, &status);
if(! status)
{
glDeleteShader(vertex_id);
glDeleteShader(fragment_id);
glDeleteProgram(program_id);
throw std::runtime_error(logstr);
}
glDeleteShader(vertex_id);
glDeleteShader(fragment_id);
Затенение связанно с простым:
glUseProgram(program_id);
Вершина буфер создаются как follows:
glGenBuffers(5, buffers);
size_t vcount = vertexes.size();
size_t fcount = faces.size();
glBindBuffer(GL_ARRAY_BUFFER, buffers[VERTEX_BUFFER]);
glBufferData(GL_ARRAY_BUFFER, vcount * 3 * sizeof(float), &vertexes[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, buffers[NORMAL_BUFFER]);
glBufferData(GL_ARRAY_BUFFER, vcount * 3 * sizeof(float), &normals[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, buffers[TEXCOORD_BUFFER]);
glBufferData(GL_ARRAY_BUFFER, vcount * 2 * sizeof(float), &texcoords[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, buffers[TANGENT_BUFFER]);
glBufferData(GL_ARRAY_BUFFER, vcount * 3 * sizeof(float), &tangents[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[INDEX_BUFFER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, fcount * 3 * sizeof(unsigned int), &faces[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Буфера вершин затем оказывается с following sequence:
int vertex_location = shader.get_attribute_location("aVertex");
int normal_location = shader.get_attribute_location("aNormal");
int texcoord_location = shader.get_attribute_location("aTexCoord");
int tangent_location = shader.get_attribute_location("aTangent");
if (vertex_location != -1)
{
glBindBuffer(GL_ARRAY_BUFFER, buffers[VERTEX_BUFFER]);
glVertexAttribPointer(vertex_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(vertex_location);
}
if (normal_location != -1)
{
glBindBuffer(GL_ARRAY_BUFFER, buffers[NORMAL_BUFFER]);
glVertexAttribPointer(normal_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(normal_location);
}
if (texcoord_location != -1)
{
glBindBuffer(GL_ARRAY_BUFFER, buffers[TEXCOORD_BUFFER]);
glVertexAttribPointer(texcoord_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(texcoord_location);
}
if (tangent_location != -1)
{
glBindBuffer(GL_ARRAY_BUFFER, buffers[TANGENT_BUFFER]);
glVertexAttribPointer(tangent_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(tangent_location);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[INDEX_BUFFER]);
glDrawElements(GL_TRIANGLES, faces.size() * 3, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
местоположение атрибута определяется с помощью:
return glGetAttribLocation(program_id, name.c_str());
Этот код хорошо работает с 3.0 и 3.1. Какую деталь я пропустил, так что она ломается, начиная с ядра OpenGL 3.2. (Это, очевидно, также работает в 3.2 Compat.)
Из кода, вставленного до сих пор, я бы сказал, что в вашем коде отсутствуют VAO, которые являются обязательными в ядре. – derhass
Вы можете сгенерировать и привязать одно VAO на весь срок действия вашего приложения. Разница между совместимостью и ядром заключается в том, что в ядре, если у вас нет ненулевой привязки VAO, тогда все команды, такие как 'glVertexAttribPointer (...)', являются недопустимыми операциями._Вы действительно проверили 'glGetError()'? Он будет показывать «GL_INVALID_OPERATION», если это так. –
Подмножество http://stackoverflow.com/questions/25595368/converting-glsl-modern-opengl-3-2. –