У меня возникли проблемы с поиском расположения 2D-объекта в моей сцене с использованием экранных координат. На данный момент у меня есть что-то работающее (код ниже), но он хочет координаты NDC, с которыми работать нелегко. Я не могу понять, где это происходит. Я думаю, что я использовал все, как должно быть, поэтому я думаю, что что-то забыл.Преобразование OpenGL в координатах NDC вместо координат экрана (2D)
Вот код, который обрабатывает рисование объектов в моей сцене:
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// RENDERING HERE
colorProgram.bind();
for (size_t t = 0; t < objectsWithGraphicsComponentInThisScene.size(); ++t)
{
// set texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, objectsWithGraphicsComponentInThisScene[t]->getComponent<GraphicsComponent>()->getTexture());
GLint texLocation = colorProgram.getUniformLocation("texSampler");
glUniform1i(texLocation, 0);
glm::mat4 trans;
trans = glm::translate(glm::mat4x4(1.0f), glm::vec3(objectsWithGraphicsComponentInThisScene[t]->getPosition().x, objectsWithGraphicsComponentInThisScene[t]->getPosition().y, 0));
GLint transMatLocation = colorProgram.getUniformLocation("transformMatrix");
glUniformMatrix4fv(transMatLocation, 1, GL_FALSE, glm::value_ptr(trans));
// set camera Matrix
GLint projMatLocation = colorProgram.getUniformLocation("projectionMatrix");
glm::mat4 cameraMatrix = camera->getCameraMatrix();
glUniformMatrix4fv(projMatLocation, 1, GL_FALSE, glm::value_ptr(cameraMatrix));
objectsWithGraphicsComponentInThisScene[t]->getComponent<GraphicsComponent>()->getSprite()->draw();
// unbind all
glBindTexture(GL_TEXTURE_2D, 0);
}
colorProgram.unbind();
где colorProgram является шейдер мои спрайты использовать и getPosition()
просто возвращает значение, которое я установил. (где значения x y и z должны быть указаны как координаты экрана). поэтому, например, getPosition может возвращать [100, 50, 0], но это отобразит объект за пределами экрана (экран 1280x720).
Теперь код, который делает спрайт (objectsWithGraphicsComponentInThisScene [т] -> GetComponent() -> getSprite() -> рисуем();):
void Sprite::draw()
{
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glEnableVertexAttribArray(0);
// position
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
//color
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, color));
// uv
glVertexAttribPointer(2, 2, GL_FLOAT, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, uv));
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
А вот код в шейдере (colorProgram): Vertex Shader:
#version 130
// per vertex
// input data from VBO
in vec2 vertexPosition;
in vec4 vertexColor;
in vec2 vertexUV;
// output to fragment shader
out vec4 fragmentColor;
out vec2 fragmentUV;
uniform mat4 projectionMatrix;
uniform mat4 transformMatrix;
void main()
{
mat4 resultMatrix = transformMatrix * projectionMatrix;
gl_Position.xy = (resultMatrix * vec4(vertexPosition, 0.0, 1.0)).xy;
gl_Position.z = 0.0;
// Indicate that the coordinates are normalized
gl_Position.w = 1.0;
fragmentColor = vertexColor;
fragmentUV = vec2(vertexUV.x, 1.0 - vertexUV.y);
}
пиксельный шейдер
#version 130
// per pixel
// input from vertex shader
in vec4 fragmentColor;
in vec2 fragmentUV;
out vec4 color;
uniform sampler2D texSampler;
void main()
{
vec4 textureColor = texture(texSampler, fragmentUV);
if (textureColor.a < 0.5) discard;
color = fragmentColor * textureColor;
}
I f вам нужно больше кода, я был бы счастлив добавить больше, хотя я думаю, что это все, что нужно.
Попробуйте использовать матрицу орфографической проекции ([glm :: ortho] (http://glm.g-truc.net/0.9.2/api/a00245.html#ga71777a3b1d4fe1729cccf6eda05c8127)). – BDL
Я установил это при создании моей камеры. мне нужно делать это каждый раз, когда я делаю призыв к розыгрышу? – Dries
Вы должны положить его в форму шейдера. Как и любая другая матрица. Я бы умножал его на 'cameraMatrix', так как вы уже называете его' projectionMatrix' в шейдере;) – BDL