如何防止Texture_2D大于viewport被缩放到openGL的viewport
How to prevent Texture_2D bigger than viewport from being scaled to viewport in openGL
这里学习openGL的新手,我没有任何代码可以发布,因为这是一个关于概念的问题,而不是我目前的实现。如果代码是绝对需要的,让我知道,我的耻辱,我会张贴一些。
基本上我有一个在GL中显示2D图像的VBO,但是,由于我的视口是800x600,图像是1024x1024,因此图像正在按比例缩小以适应视口。我在谷歌上搜索了很长时间关于这个问题,我所能找到的都是关于这个的参考资料,比如NeHe教程,他们说这会发生,但没有解释为什么以及如何防止它发生。我想我找到了一个论坛,说有可能预防,但同样没有细节。
所以,我很好奇,这是怎么做到的?我刚刚学习GL,所以在这个领域我几乎是一个全新的新手。如果有帮助的话,我正在制作一款2D游戏,我试图使用这个VBO来显示关卡的背景图像,所以当你左右上下移动摄像机时,你实际上是在滚动背景图像。任何帮助将非常感激和感谢。:)
注:此外,我意识到这可能应该在一个单独的问题中,但任何解释或链接来解释顶点/纹理贴图的坐标系统也将受到赞赏。我没有真正掌握一个人应该如何从0-1映射纹理并将其转换为空间中的像素坐标。
好的,所以在一些更多的谷歌搜索后,我发现的唯一解决方案是暂时调整视口至少是你的2D纹理的大小,然后绘制你的2D纹理,然后设置视口回到窗口大小(或任何它应该是)。像这样:
//Set viewport so size of the current texture - note this is using a VBO
glViewport(0, 0, 1024, 1024);
glBindTexture(GL_TEXTURE_2D, texture);
glDrawArrays(GL_QUADS, 0, 4 );
glPopAttrib();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
//Set the viewport back to the window size
glViewport(0, 0, 800, 600);
唯一的问题是,这似乎是一个重大的黑客。这是官方或可接受的解决方案吗?
把纹理想象成橡胶片。纹理的左下角(不是像素)在(0,0),右上角在(1,1)。在屏幕上绘制三角形时——屏幕上的确切位置无关紧要——纹理"橡胶片"根据纹理坐标"裁剪"出来,并按照纹理坐标的指定拉伸到三角形上。在视口尺寸和纹理之间没有交互作用!
假设你有一个纹理,想要显示它的左下部分,到视口允许的数量。那么你可以这样做:
void display()
{
glViewport(0, 0, viewport_width, viewport_height);
/* ... */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* By using a orthographic projection with limits matching the viewport
we're effectively getting viewport pixel coordinates for the vertices. */
glOrtho(0, viewport_width, 0, viewport_height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* I'm using immediate mode here for clarity – not
recommended for new applications, use Vertex Arrays */
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0, 0);
glTexCoord2f(1.0f, 0.0f); glVertex2f(texture_width, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(texture_width, texture_height);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0, texture_height);
glEnd();
}
关键是,根据需要改变投影。OpenGL投影矩阵并不是一些不可触及的神圣数据。实际上,你应该随时修改它,使事情变得更容易。变换矩阵很便宜。这同样适用于视口。它们只是一组寄存器(在着色器方面,它们被称为制服),几乎可以自由设置。
最好的方法是将你正在绘制的顶点缩放到当前视口的大小。
例如,绘制一个10px * 10px的框(忽略过时的api)。
glBegin( GL_QUADS );
glVertex2d(0.0 ,0.0);
glVertex2d(10.0/viewportWidth * 2,0.0);
glVertex2d(10.0/viewportWidth * 2,10.0/viewportHeight * 2);
glVertex2d(0.0 ,10.0/viewportHeight * 2);
glEnd();
你可以在着色器或CPU上做。
改变视口看起来像是另一个昂贵的OpenGL状态改变。
注意:如果投影矩阵更复杂,这可能会变得更复杂。
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 计算缩放多边形的比例,得到给定的多边形面积
- QwtPlot具有相等的轴和自动缩放
- 如何在directx/c++中进行平移/缩放操作
- 在Qt中实现无限可缩放的画布
- 是否可以为 QPixmap 派生类嵌入缩放方法?
- 形状对象的旋转和缩放不正确C++
- 如何在 OpenSceneGraph 中缩放/旋转/移动资产
- 如何在OpenGL(GLFW,很高兴)中进行2D缩放?
- 改变或缩放两个正态分布以具有特定的相关系数
- SDL2 调整窗口大小后如何缩放鼠标坐标?
- 如何在OpenGL中正确旋转和缩放对象?
- 仅当类型为 std::complex 时,才进行缩放
- 将 VS Code 用于跨平台可缩放C++项目
- 根据帧速率缩放/缩小数字
- 在 c++ 中缩放浮点值
- 如何防止 DirectX C++程序的拉伸/缩放
- 使用提升几何缓冲区缩放多边形时的冗余折点
- 为什么我不能使用 Sphere 来缩放字形?
- 我在QChartView中找不到缩放图形的鼠标滚轮滚动事件