Функция возвращает -1, хотя Uniform определен и используется в вершинном шейдере, я подозреваю, что причина может заключаться в том, что выходные атрибуты могут быть неправильно связаны с целевым буфером (не уверен, что это так). Без этой униформы большинство моих ценностей останутся прежними.
Рисование обратной связи преобразования
/*code included in update*/
glUseProgram(feedbackShader->GetProgram());
glEnable(GL_RASTERIZER_DISCARD);
/*end of code included in update*/
glBindBuffer(GL_ARRAY_BUFFER, particleBuffer[isEvenBuffer]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformBuffer[!isEvenBuffer]);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), 0); //Location
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)12); //Velocity
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)24); //InitLocation
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)36); //InitVelocity
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)48); //Lifetime
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid*)52); //InitLifetime
GLint uniformLocation = glGetUniformLocation(feedbackShader->GetProgram(), "time");
glUniform1f(uniformLocation, msec);
glBeginTransformFeedback(GL_POINTS);
glDrawTransformFeedback(GL_POINTS, transformBuffer[isEvenBuffer]);
glEndTransformFeedback();
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glDisableVertexAttribArray(4);
glDisableVertexAttribArray(5);
Вершинный шейдер
#version 410
in vec3 inLocation;
in vec3 inVelocity;
in vec3 inInitLocation;
in vec3 inInitVelocity;
in float inLifeTime;
in float inInitlifeTime;
out vec3 outLocation;
out vec3 outVelocity;
out vec3 outInitLocation;
out vec3 outInitVelocity;
out float outLifeTime;
out float outInitlifeTime;
uniform float time;
vec3 Gravity = vec3(0.0f,-0.98f,0.0f);
float dampeningFactor = 0.5;
void main()
{
outLifeTime = inLifeTime - time;
if (outLifeTime > 0.0f){
outVelocity = (inVelocity + Gravity * time) * dampeningFactor;
outLocation = inLocation + inVelocity * time;
}else{
outVelocity = inInitVelocity;
outLocation = inInitLocation;
outLifeTime = inInitlifeTime;
}
outInitVelocity = inInitVelocity;
outInitLocation = inInitLocation;
outInitlifeTime = inInitlifeTime;
}
ОБНОВИТЬ Вы все просили немного дополнительной информации.
Вершинный шейдер
#version 410
in vec3 inLocation;
in vec3 inVelocity;
in vec3 inInitLocation;
in vec3 inInitVelocity;
in float inLifeTime;
in float inInitlifeTime;
out vec3 outLocation;
out vec3 outVelocity;
out vec3 outInitLocation;
out vec3 outInitVelocity;
out float outLifeTime;
out float outInitlifeTime;
uniform float time;
vec3 Gravity = vec3(0.0f,-0.98f,0.0f);
float dampeningFactor = 0.5;
void main()
{
outLifeTime = inLifeTime - time;
if (outLifeTime > 0.0f){
outVelocity = (inVelocity + Gravity * time) * dampeningFactor;
outLocation = inLocation + inVelocity * time;
}else{
outVelocity = inInitVelocity;
outLocation = inInitLocation;
outLifeTime = inInitlifeTime;
}
outInitVelocity = inInitVelocity;
outInitLocation = inInitLocation;
outInitlifeTime = inInitlifeTime;
}
Варианты обратной связи (я был глуп, и сначала этого не было, хотя та же проблема остается в моем коде)
const GLchar* feedbackVaryings[] = {
"outLocation",
"outVelocity",
"outInitLocation",
"outInitVelocity",
"outLifeTime",
"outInitlifeTime"
};
glTransformFeedbackVaryings(feedbackShader->LinkProgram(), 6, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
Я также добавил gluseProgram в раздел «Создание обратной связи по преобразованию».
Вы звоните glUseProgram где-нибудь перед звонком glUniform1f? Я не вижу этого в Вашем коде ...
Вы должны привязать свой шейдер, например, glUseProgram(feedbackShader->GetProgram()), прежде чем переходить к униформе, GLint uniformLocation = glGetUniformLocation(feedbackShader->GetProgram(), "time");
@ Rabbid76 FeedbackShader переменная четко указывает, что программа уже связана. Его не нужно связывать снова, он может просто получить местоположение, привязав шейдер / используя идентификатор программы
@ Rabbid76 Я понимаю вашу точку зрения, в этом случае OP должен включать детали своего шейдера, чтобы мы могли увидеть детали реализации и продолжить оттуда
@ HasanAl-Baghdadi, можете ли вы включить источник вашего класса Shader и способы использования вашей переменной feedbackShader?
@ Rabbid76 Я попросил кое-какие подробности у OP, может быть, мы сможем исходить из этого.
Приносим извинения за поздний ответ и благодарим за помощь. Но мне кажется, я только что добавил все, что вы просили.





Предполагаю, что инструкция
feedbackShader->LinkProgram()
связывает программу. Но переменные переменной обратной связи преобразования должны быть указаны до связывания программы.
См. Спецификация профиля ядра API OpenGL 4.6; 7.3.1.1 Именование активных ресурсов; стр. 104
The order of the active resource list is implementation-dependent for all interfaces except for TRANSFORM_FEEDBACK_VARYING. If variables in the TRANSFORM_FEEDBACK_VARYING interface were specified using the
TransformFeedbackVaryingscommand, the active resource list will be arranged in the variable order specified in the most recent call toTransformFeedbackVaryingsbefore the last call toLinkProgram.
Это означает, что сначала вы должны присоединить скомпилированный объект вершинного шейдера к объекту программы (glAttachShader). Затем вы должны указать изменение обратной связи преобразования (glTransformFeedbackVaryings). Наконец, вам нужно связать программу (glLinkProgram):
GLuint shader_obj;
GLuint program_obj;
.....
glAttachShader(program_obj, shader_obj);
const GLchar* feedbackVaryings[] = {
"outLocation",
"outVelocity",
"outInitLocation",
"outInitVelocity",
"outLifeTime",
"outInitlifeTime"
};
glTransformFeedbackVaryings(program_obj, 6, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
glLinkProgram(program_obj);
Далее я рекомендую использовать Квалификатор макета для определения индексов атрибутов входных переменных вершинного шейдера.
например
layout (location = 0) in vec3 inLocation;
layout (location = 1) in vec3 inVelocity;
layout (location = 2) in vec3 inInitLocation;
layout (location = 3) in vec3 inInitVelocity;
layout (location = 4) in float inLifeTime;
layout (location = 5) in float inInitlifeTime;
В качестве альтернативы индекс атрибута может быть определен посредством glGetAttribLocationпосле, связывающего программу, или установлен посредством glBindAttribLocationперед, связывающего программу.
Однако это обратная связь с преобразованием, поэтому фрагментного шейдера не существует.