C++ NDC坐标代替屏幕坐标的OpenGL转换(2D)
我无法确定如何使用屏幕坐标在场景中定位2D对象。目前,我有一些工作(代码如下),但它需要NDC坐标,这是不容易工作。我不知道哪里出了问题。我想我已经用了所有应该用的东西,所以我想我忘了什么 以下是处理“我的场景”中对象的绘制的代码:C++ NDC坐标代替屏幕坐标的OpenGL转换(2D),c++,opengl,glm-math,C++,Opengl,Glm Math,我无法确定如何使用屏幕坐标在场景中定位2D对象。目前,我有一些工作(代码如下),但它需要NDC坐标,这是不容易工作。我不知道哪里出了问题。我想我已经用了所有应该用的东西,所以我想我忘了什么 以下是处理“我的场景”中对象的绘制的代码: glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // RENDERING HERE colorProgram.bind(); for (size_t t = 0;
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)中的代码:
顶点着色器:
#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;
}
#版本130
//每像素
//来自顶点着色器的输入
在vec4片段颜色中;
在vec2片段中;
输出vec4颜色;
均匀取样器;
void main()
{
vec4 textureColor=纹理(texSampler,fragmentUV);
如果(textureColor.a<0.5)丢弃;
颜色=碎片颜色*纹理颜色;
}
如果您需要更多代码,我很乐意添加更多代码,尽管我认为这是所需的一切。在顶点着色器中执行此序列
mat4 resultMatrix = transformMatrix * projectionMatrix;
gl_Position.xy = (resultMatrix * vec4(vertexPosition, 0.0, 1.0)).xy;
不太可能是你真正想要的。由于使用了矩阵*向量约定,因此最终
position = transform * projection * v
= transform * (projection * v)
换句话说:在投影之后应用变换。由于投影后,观察体积在[-1,1]^3范围内(在透视分割后的欧几里德NDC空间中。实际上,我们在剪辑空间中工作,它是[-w,w]^3,但在这种情况下这并不重要,),将对象平移100个单位肯定会将其移出平截体
你应该颠倒矩阵乘法的顺序。尝试使用正交投影矩阵()。我在创建相机时设置了它。我是否需要在每次抽签时都这样做?你必须将其放入着色器制服中。就像其他矩阵一样。我会将它乘以
cameraMatrix
,因为您已经在着色器中调用了projectionMatrix
)看起来简单多了(看看答案)。非常感谢您的回复:)非常感谢哇,这似乎解决了问题!非常感谢!:)
position = transform * projection * v
= transform * (projection * v)