Использование texture2D в OpenGL 3.3 - PullRequest
0 голосов
/ 18 ноября 2018

Так что я возился со старым университетским проектом, выполненным в OpenGL 3.3 (FreeGLUT + GLEW), и столкнулся с некоторыми проблемами.

С самого начала я запускаю программу иполучаю сообщение об ошибке при компиляции фрагментного шейдера BumpMap:

#version 330 core    
#define lightCount 10

in vec4 vertPos;
in vec4 eyeModel;

in vec3 normalInterp;

in vec4 ambient;
in vec4 color;
in vec4 spec;
in vec2 texuv;

in vec4 lightPosition[lightCount];

struct LightSource {

        vec4 Position;
        vec4 Direction;

        vec4 Color;

        float CutOff;

        float AmbientIntensity;
        float DiffuseIntensity;
        float SpecularIntensity;

        float ConstantAttenuation;
        float LinearAttenuation;
        float ExponentialAttenuation;

        int lightType;
};

layout(std140) uniform LightSources {

        LightSource lightSource[10];
};

uniform sampler2D diffuse_tex;
uniform sampler2D normal_tex;

out vec4 out_Color;

void main() {
        out_Color = vec4(0);

        for(int i=0; i<lightCount; i++) {

                if(lightSource[i].lightType == 0)
                        continue;

                vec3 NormalMap = texture2D(normal_tex, texuv).rgb;
                vec3 normal = normalize(NormalMap * 2.0 - 1.0); //normalize(normalInterp);

                vec4 LightDirection = vertPos - lightSource[i].Position;
                float Distance = length(LightDirection);
                LightDirection = normalize(LightDirection);

                vec4 ambientColor = ambient * lightSource[i].Color * lightSource[i].AmbientIntensity;
                vec4 diffuseColor  =  vec4(0, 0, 0, 0);
                vec4 dColor = texture2D(diffuse_tex, texuv);
                vec4 specularColor = vec4(0, 0, 0, 0);

                float DiffuseFactor = dot(normal, vec3(-LightDirection));

                if (DiffuseFactor > 0) {

                        diffuseColor = dColor * lightSource[i].Color * lightSource[i].DiffuseIntensity * DiffuseFactor;

                        vec3 VertexToEye = normalize(vec3(eyeModel - vertPos));
                        vec3 LightReflect = normalize(reflect(vec3(LightDirection), normal));

                        float SpecularFactor = dot(VertexToEye, LightReflect);

                        SpecularFactor = pow(SpecularFactor, 255);
                        if(SpecularFactor > 0.0){
                        //SpecularFactor = pow( max(SpecularFactor,0.0), 255);
                                specularColor = spec * lightSource[i].Color * lightSource[i].SpecularIntensity * SpecularFactor;
                        }
                }

                out_Color += ambientColor + diffuseColor + specularColor;
        }
}

ОШИБКА: 0:55: 'функция': удалена в контексте прямой совместимости texture2D
ОШИБКА: 0:55: 'texture2D': не найдено соответствующей перегруженной функции (использующей неявное преобразование)

Поэтому я посмотрел на проблему и, хотя мне показалось, что это странно, я столкнулся с этой проблемой в проекте, который, как я знал, находился в рабочем состоянииЯ переключил вызов texture2D для вызова texture, и теперь шейдер компилируется, но я получаю другую ошибку, когда создается объект буфера для первого объекта в сцене:

//Consts defined here for readability
#define VERTICES 0
#define COLORS 1
#define NORMALS 2
#define TEXUVS 3
#define AMBIENTS 4
#define TANGENTS 5
#define SPECULARS 6
#define SPECULARS_CONSTANTS 7
#define NOISE_SCALE 8

void BufferObject::createBufferObject() {

    glGenVertexArrays(1, &_vertexArrayObjectID);
    glBindVertexArray(_vertexArrayObjectID);

    glGenBuffers(1, &_vertexBufferObjectID);

    glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*_vertexCount, _vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(VERTICES);
    glVertexAttribPointer(VERTICES, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);

    glEnableVertexAttribArray(COLORS);
    glVertexAttribPointer(COLORS, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)sizeof(_vertices[0].XYZW));

    glEnableVertexAttribArray(NORMALS);
    glVertexAttribPointer(NORMALS, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)));

    glEnableVertexAttribArray(TEXUVS);
    glVertexAttribPointer(TEXUVS, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)+sizeof(_vertices[0].NORMAL)));

    glEnableVertexAttribArray(AMBIENTS);
    glVertexAttribPointer(AMBIENTS, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)+sizeof(_vertices[0].NORMAL)+sizeof(_vertices[0].TEXUV)));

    glEnableVertexAttribArray(TANGENTS);
    glVertexAttribPointer(TANGENTS, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)+sizeof(_vertices[0].NORMAL)+sizeof(_vertices[0].TEXUV)+sizeof(_vertices[0].AMBIENT)));

    glEnableVertexAttribArray(SPECULARS);
    glVertexAttribPointer(SPECULARS, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)+sizeof(_vertices[0].NORMAL)+sizeof(_vertices[0].TEXUV)+sizeof(_vertices[0].AMBIENT)+sizeof(_vertices[0].TANGENT)));

    glEnableVertexAttribArray(SPECULARS_CONSTANTS);
    glVertexAttribPointer(SPECULARS_CONSTANTS, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(_vertices[0].XYZW)+sizeof(_vertices[0].RGBA)+sizeof(_vertices[0].NORMAL)+sizeof(_vertices[0].TEXUV)+sizeof(_vertices[0].AMBIENT)+sizeof(_vertices[0].TANGENT)+sizeof(_vertices[0].SPECULAR)));

    glBindVertexArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    glDisableVertexAttribArray(VERTICES);
    glDisableVertexAttribArray(COLORS);
    glDisableVertexAttribArray(NORMALS);
    glDisableVertexAttribArray(TEXUVS);
    glDisableVertexAttribArray(AMBIENTS);
    glDisableVertexAttribArray(TANGENTS);
    glDisableVertexAttribArray(SPECULARS);
    glDisableVertexAttribArray(SPECULARS_CONSTANTS);

    Utility::checkOpenGLError("ERROR: Buffer Object creation failed.");
}

ОШИБКА OpenGL [Неверная операция] = 1282

И это вся информация, которую я получаю.Я переместил checkOpenGLError и понял, что glDisableVertexAttribArray(VERTICES) выдает ошибку.После еще нескольких копаний я обнаружил, что вы не должны устанавливать glBindVertexArray(0) (по крайней мере, до того, как вы glDisableVertexAttribArray, насколько я помню, мы установили эти флаги в 0, чтобы мы не могли случайно повлиять на то, что мы не сделали).не хочется)

В этот момент ошибка перемещается туда, где мы рисуем один из объектов сцены.В этот момент я ударился о стену и не знаю, куда идти дальше.Я предполагаю, что мой вопрос заключается в том, существует ли конфигурация при запуске проекта, которую необходимо установить, или может ли просто запуск этой программы на более новой видеокарте объяснять другое поведение.И последнее замечание: это работает в Windows от Visual Studio 10 (или 15, переключается на 10, когда все изменения отменены и не перенастраивают решение) в widnows, конфигурации программы следующие:

//GLUT Init
glutInit(&argc, argv);

glutInitContextVersion(3, 3);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_GLUTMAINLOOP_RETURNS);

glutInitWindowSize(windowWidth, windowHeight);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

windowHandle = glutCreateWindow(CAPTION);

//GLEW Init
glewExperimental = GL_TRUE;

GLenum result = glewInit(); 

//GLUT Init
std::cerr << "CONTEXT: OpenGL v" << glGetString(GL_VERSION) << std::endl;

glClearColor(0.1f, 0.1f, 0.1f, 1.0f);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
glDepthRange(0.0,1.0);
glClearDepth(1.0);

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);

с указанным выше контекстом:

КОНТЕКСТ: OpenGL v3.3.0 - сборка 22.20.16.4749

Сообщите мне, если требуется дополнительная информация, я не сделалНе нужно добавлять ненужный беспорядок, и проект слишком велик, чтобы просто вставить все это сюда ...

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Сначала позвольте мне обратиться к спецификации, Спецификация профиля ядра API OpenGL 4.6; 10.3.1. Объекты Vertex Array; страница 347 :

Пространство имен для объектов массива вершин представляет собой целые числа без знака, с нулем, зарезервированным GL .
...
Объект массива вершин создается путем связывания имени, возвращаемого GenVertexArray, с помощью команды

void BindVertexArray( uint array );

array - имя объекта массива вершин. Результирующий объект массива вершин представляет собой новый вектор состояний, включающий все состояния и с одинаковыми начальными значениями, перечисленными в таблицах 23.3 и 23.4.
BindVertexArray также может использоваться для привязки существующего объекта массива вершин. Если привязка прошла успешно, изменения состояния связанного массива вершин не производится, и любая предыдущая привязка нарушается.

Таблицы 23.3. Состояние объекта массива вершин
VERTEX_ATTRIB_ARRAY_ENABLED, VERTEX_ATTRIB_ARRAY_SIZE, VERTEX_ATTRIB_ARRAY_STRIDE, VERTEX_ATTRIB_ARRAY_TYPE, VERTEX_ATTRIB_ARRAY_NORMALIZED, VERTEX_ATTRIB_ARRAY_INTEGER, VERTEX_ATTRIB_ARRAY_LONG, VERTEX_ATTRIB_ARRAY_DIVISOR, VERTEX_ATTRIB_ARRAY_POINTER

Таблица 23.4. Состояние объекта Vertex Array
ELEMENT_ARRAY_BUFFER_BINDING, VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, VERTEX_ATTRIB_BINDING, VERTEX_ATTRIB_RELATIVE_OFFSET, VERTEX_BINDING_OFFSET, VERTEX_BINDING_STRIDE, VERTEX_BINDING_DIVISOR, VERTEX_BINDING_BUFFER.

Это означает, что Vertex Array Object собирает всю информацию, необходимую для рисования объекта. В объекте массива вершин хранится информация о расположении атрибутов вершины и формате. Далее объект массива вершин «знает», включен ли атрибут или нет.

Если вы делаете

glBindVertexArray(0);

glDisableVertexAttribArray( .... );

это вызывает ошибку INVALID_OPERATION, когда вы используете профиль ядра контекст OpenGL , потому что тогда объект массива вершин 0 не является допустимым объектом массива вершин. Если вы используете контекст профиля совместимости, это не приведет к ошибке, потому что тогда объект массива вершин 0 является объектом массива вершин по умолчанию и является действительным.

Если вы делаете

glBindVertexArray(_vertexArrayObjectID);

glEnableVertexAttribArray( ..... );
glVertexAttribPointer( ..... );

glDisableVertexAttribArray( ..... );

glBindVertexArray(0);

тогда отрисовка не удастся. Вы приложили усилия, чтобы определить все массивы данных общих атрибутов вершин и правильно включить их все, но сразу после этого вы снова отключаете их. Таким образом, в массиве вершин хранится состояние «отключено» для всех атрибутов.

Правильная процедура для определения объекта массива вершин:

  • Генерация буферов вершин, а также создание и инициализация хранилища данных объекта буфера (этот шаг можно выполнить и после создания и привязки объекта массива вершин):
glGenBuffers(1, &_vertexBufferObjectID);

glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*_vertexCount, _vertices, GL_STATIC_DRAW);
  • Создание и привязка объекта массива вершин:
glGenVertexArrays(1, &_vertexArrayObjectID);
glBindVertexArray(_vertexArrayObjectID);
  • Определите и включите массивы данных общих атрибутов вершин (это необходимо сделать после привязки объекта массива вершин):
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferObjectID);
glEnableVertexAttribArray(VERTICES);
glVertexAttribPointer(VERTICES, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);

....

glBindBuffer(GL_ARRAY_BUFFER, 0);
  • Если бы вы использовали буфер элементов (GL_ELEMENT_ARRAY_BUFFER), то вам нужно было бы указать его сейчас, потому что имя (ссылка на) объекта буфера элемента хранится в объекте массива вершин, и это должно быть привязывается в данный момент, когда объект буфера элемента становится связанным.
glGenBuffers(1, &ibo);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ..... );
  • Наконец вы можете сделать glBindVertexArray(0). Но нет никаких причин для этого. Достаточно связать новый объект массива вершин, прежде чем указывать новую сетку, или связать соответствующий объект массива вершин, прежде чем рисовать сетку.

Далее нет необходимости в glDisableVertexAttribArray, если вы не хотите изменять спецификацию объекта массива вершин. Состояние «включено» хранится в объекте массива вершин и хранится там. Если вы связываете новый объект массива вершин, тогда объект и все его состояния становятся текущими.

Теперь рисунок прост:

 glBindVertexArray(_vertexArrayObjectID);
 glDrawArrays( .... );

Опять нет необходимости в glBindVertexArray(0) после вызова отрисовки (особенно в режиме ядра).

0 голосов
/ 18 ноября 2018

В вашем шейдере вы используете ядро ​​glsl версии 330, что означает, что texture2D() устарело, и вы должны использовать texture().

Что касается вашей ошибки INVALID OPERATION, проблема в том, что вы отменили vao с помощью glBindVertexArray(0); и затем вызвали glDisableVertexAttribArray(VERTICES);, который работает с текущим связанным vao.Вам следует переместиться glBindVertexArray(0); под эти вызовы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...