2014-12-01 2 views
-1

Я занимаюсь обновлением своего кода с 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.)

+2

Из кода, вставленного до сих пор, я бы сказал, что в вашем коде отсутствуют VAO, которые являются обязательными в ядре. – derhass

+1

Вы можете сгенерировать и привязать одно VAO на весь срок действия вашего приложения. Разница между совместимостью и ядром заключается в том, что в ядре, если у вас нет ненулевой привязки VAO, тогда все команды, такие как 'glVertexAttribPointer (...)', являются недопустимыми операциями._Вы действительно проверили 'glGetError()'? Он будет показывать «GL_INVALID_OPERATION», если это так. –

+0

Подмножество http://stackoverflow.com/questions/25595368/converting-glsl-modern-opengl-3-2. –

ответ

5

Вы должны использовать VAOs

Создать один с glGenVertexArrays(1, &vao); и связываются с glBindVertexArray(vao);

переместить код Bining в код установки двигаться как так

glBindVertexArray(vao); 
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); 
} 

//etc. 

glBindBuffer(GL_ARRAY_BUFFER, 0); 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[INDEX_BUFFER]); 
glBindVertexArray(0); 

затем во время рендеринга, это просто

glBindeVertexArray(vao); 
glDrawElements(GL_TRIANGLES, faces.size() * 3, GL_UNSIGNED_INT, 0); 
glBindeVertexArray(0); 

Вероятно, лучше всего bind the attribute locations, прежде чем связывать программы, так что положение всегда 1 и нормали всегда 2 и т. Д.

+0

Спасибо за подсказку, что на самом деле решило мою проблему: https://stackoverflow.com/questions/20766864/glew-opengl-access-violation-when-using-glgenvertexarrays Поскольку glGenVertexArrays не был загружен glew, я предположил, что это не принадлежит к ядру ... – rioki

Смежные вопросы