如何在 OpenGL (ES) 中将非 2 幂纹理显示为精灵而不进行拉伸?

2024-01-12

我想绘制一个任意大小的精灵作为 png,比如说 56 宽 x 30 高之类的完全疯狂的东西。任一维度都不是 2 的幂。另外,我可能想绘制另一个 72 宽 x 33 高的不同精灵。指出这一点是因为这里不接受任何“技巧”,我需要处理一般情况。

所以我有这个 png(具有透明度),我想将其绘制为精灵,绝对没有拉伸、插值等。我希望它与屏幕上的像素以 1:1 的比例映射。假设这些精灵是像素艺术(它们可能是也可能不是,但它们是为了精确的分辨率而绘制的)。

我理解精灵图绘制 - 2 个三角形作为四边形,通过纹理坐标映射将纹理渲染到该纹理 - 但是我只理解它的 2 的幂。而且我也不知道如何调整我的“四边形”的大小并设置我的 GL 矩阵这样我就可以使精灵的像素大小与我的精灵完全相同

我正在使用 OpenGL ES,因此使用新扩展来使用非 2 次方纹理是不可接受的。

我一次只绘制 3-10 个精灵,因此我愿意接受有关效率的建议,但我最感兴趣的是“准确”的外观结果。


要获得像素完美的坐标系,您可以按如下方式设置矩阵:

glViewport(0, window_width, 0, window_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, window_width, 0, window_height, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

这可确保 OpenGL 坐标到像素的 1:1 映射,并将原点放在左下角。

至于你的纹理,如果你不想依赖非二次幂扩展,你可以must将其填充为 2 的幂。尽管 OpenGL ES 规范并没有规定它也必须是正方形(据我所知),但我在 Android 上看到过奇怪的事情,纹理尺寸如 512 x 128,所以最好坚持使用square二次方纹理。

需要注意的是,OpenGL 中的纹理坐标始终介于 0 和 1 之间,无论纹理的像素大小是多少。因此,如果您的精灵宽度为 48 像素,并且将其填充为 64 x 64 的纹理,那么它将跨越从 0 到 0.75 的 x 坐标:

1 +--------+
  |        |
  |        |
  +-----+  |
  |\_O_/|  |
  |  O  |  |
  | / \ |  |
0 +-----+--+
  0   0.75 1   <- texture coordinates
  0     48 64  <- pixels

因此,您必须为四边形的角设置这些纹理坐标。因为我们有一个像素完美的投影,所以四边形也必须正好是 48 像素宽。

总之,在位置绘制你的精灵x, y(从左下角开始以像素为单位),执行如下操作:

float texcoord_x = (float)sprite_width / texture_width;
float texcoord_y = (float)sprite_height / texture_height;

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture_id);

glBegin(GL_QUADS);
// bottom left
glTexCoord2f(0, 0);
glVertex2i(x, y);
// bottom right
glTexCoord2f(texcoord_x, 0);
glVertex2i(x + sprite_width, y);
// top right
glTexCoord2f(texcoord_x, texcoord_y);
glVertex2i(x + sprite_width, y + sprite_height);
// top left
glTexCoord2f(0, texcoord_y);
glVertex2i(x, y + sprite_height);
glEnd();

我知道 OpenGL ES 没有glVertex2i等等,所以你必须将这些坐标放入缓冲区。而且它不允许四边形,因此您必须将其分成三角形。但这是基本思想。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 OpenGL (ES) 中将非 2 幂纹理显示为精灵而不进行拉伸? 的相关文章

  • Android——在 OnDrawFrame 方法之外将 GLSurfaceView.Renderer 置于睡眠状态(如 Thread.sleep(20))

    我想控制 GLSurfaceView Renderer 的渲染速率 我在扩展 GLSurfaceView 的类中实现了一个线程 并在 while true 循环中定期将其置于睡眠状态 这不会减慢渲染器的速度 有一个很好的答案here htt
  • 如何将文本渲染为位图并绘制它

    我是 android 新手 我的小组目前正在使用 opengl es 2 0 使用 GlSurfaceView 创建图形应用程序 我们最近在绘图上显示了网格和刻度线 现在我被分配了实现数字刻度并将 x 和 y 轴标记为 X 和 Y 的任务
  • 如何使用 GLshorts 表示法线坐标或纹理坐标?

    许多关于提高 iPhone 游戏性能的建议都围绕着向 GPU 发送更少的数据而展开 明显的建议是尽可能使用 GLshorts 而不是 GLfloat 例如对于顶点 法线或纹理坐标 使用 GLshort 作为法线坐标或纹理坐标时有哪些细节 使
  • 执行eglSwapBuffer和eglMakeCurrent时性能低下

    我正在开发一个 Android Unity 插件 允许用户记录他 她的游戏玩法我的解决方案概述 使用 OpenGl FrameBufferObject FBO 使 Unity 离屏渲染到此 FBO Get the offscreen tex
  • 如何更改 OpenGL 中的旋转中心

    我有一个 3D 模型 OpenGL ES 1 1 iPhone SDK v3 0 这有点复杂 即数千个顶点和面 并且我想围绕模型中心或附近的 Y 轴旋转该模型 问题是 glRotate 围绕位于 附近的点旋转我的模型其底边之一的中心 不靠近
  • Unity3D 中 android 切换速度太慢

    我的游戏有 1000 多个帧 并且精灵的格式是 Crunch 因为这个项目中的精灵太多 当我想从Windows切换到Android时 我花了将近1天的时间来切换 实际上我不允许它完全切换 但切换到Windows并没有那么多 也许只有15分钟
  • 找不到不使用 GL11Ext 进行绘图的 android 2d opengl sprite 类的合适示例

    正如 SpriteMethodTest 所说 绘制精灵的方法有很多种 首先 我尝试了canvas 并遇到了一些性能问题 接下来 我决定学习opengl 我使用 GL11Ext 扩展取得了第一个成就 但是 默认情况下您知道 当您绘制纹理时 它
  • 如何使用 OpenGL ES 2.0 旋转对象?

    在 OpenGL ES 1 1 中 您可以使用glRotatef 旋转模型 但 OpenGL ES 2 0 中不存在该函数 那么 在OpenGL ES 2 0中如何进行旋转呢 为了遵循克里斯蒂安所说的 您需要自己跟踪模型视图矩阵并操纵它来执
  • 开发iPhone游戏需要什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Android OpenGLES 渲染到纹理

    我为 iPhone 编写图形应用程序 并且希望将我最新的应用程序 Layers 移植到 Android 平台 Layers 是一款绘画应用程序 允许用户在屏幕上绘画并使用不同的画笔 颜色等创建多层绘画 并导出到 PSD 它有桌面同步 涂抹工
  • 具有漫反射和法线贴图纹理的 3D 模型

    我想使用 libgdx 的资源加载器加载具有漫反射纹理和法线贴图的 3D 模型 据我所知 fbx 以及转换后的 g3dj g3db 格式可以包含漫反射纹理 正如我在 fbx conv 示例中看到的那样 骑士 g3db 如何为其添加法线贴图纹
  • Android中的OpenGL用于视频显示

    是否可以使用 OpenGL 来显示视频并能够在运行时调整视图大小 是的 它的工作原理是通过 glTexSubImage2D 将每个帧作为纹理上传 我已经测试了基于 FFmpeg 的解码器的输出 效果很好
  • iPhone OpenGL ES 单视图还是多视图?

    我很困惑为 iPhone 编写游戏时最好的方法是什么 游戏将使用 OpenGL 渲染 但我很好奇创建开始屏幕 菜单 高分页面等 您是否使用 OpenGL 完成所有这些操作 或者创建额外的 UIView 并使用 UIKit 我认为没有最好的方
  • 如何在cocos2d中测试精灵碰撞?

    我如何开始实现精灵碰撞类 正如 Eric 指出的 CGRectIntersectsRect 是测试两个边界矩形是否重叠的方法 使用 CCNode 类的boundingBox 方法获取每个精灵 或其他节点 的正确边界框 在这里查看我的回答 C
  • AndEngine Sprite/Box2D Body 删除使我的程序崩溃,没有错误/异常信息?

    我正在制作一个滑板游戏 其中有障碍 你必须使用 box2D 和 AndEngine 跳过 我试图做到这一点 以便当玩家与物体碰撞时 该物体被移除 并在物体的旧位置放置爆炸 但是精灵移除代码中的某些内容冻结了我的程序 导致它结束 甚至没有强制
  • Android 纹理仅显示纯色

    我正在尝试在四边形上显示单个纹理 我有一个可用的 VertexObject 它可以很好地绘制一个正方形 或任何几何对象 现在我尝试扩展它来处理纹理 但纹理不起作用 我只看到一种纯色的四边形 坐标数据位于 arrayList 中 the ve
  • 对于某些纹理尺寸,glFramebufferTexture2D 在 iPhone 上失败

    当我尝试将纹理附加到帧缓冲区时 glCheckFramebufferStatus 报告某些纹理大小的 GL FRAMEBUFFER UNSUPPORTED 我已经在第二代和第四代 iPod Touch 上进行了测试 两个模型之间失败的纹理尺
  • 如何在 Android NDK 中创建新的 NativeWindow 而无需 Android 操作系统源代码?

    我想编译一个 Android OpenGL 控制台应用程序 您可以直接从控制台启动 Android x86 运行 或者从 Android x86 GUI 内的 Android 终端应用程序运行 这个帖子 如何在 Android NDK 中创
  • 从哪里开始使用适用于 Retina 显示屏的 OpenGL 绘制程序

    我知道由于这里提到的错误 我无法将 GLPainter 示例从苹果适应到视网膜 在 Retina iPad 上显示全屏 CAEAGLLayer 时出现问题 https stackoverflow com questions 9757052
  • 使用 Nexus 10 在 Android 4.3 上滚动时性能不佳

    我的应用程序有一个带有一些滚动的列表视图 在我测试过的所有手机 Nexus One Nexus 4 和 Galaxy S3 4 上都表现得非常好 以 60fps 滚动 但 Nexus 10 上的表现很糟糕 大概在 15fps 左右 我已经将

随机推荐

  • 什么时候工厂方法比简单工厂更好,反之亦然?

    我正在阅读 Head First Design Patterns 一书 我相信我了解简单工厂和工厂方法 但我很难看出工厂方法相对于简单工厂带来的优势 如果对象 A 使用简单工厂来创建其 B 对象 那么客户端可以这样创建它 A a new A
  • 到 Out-GridView 和 Out-File 的管道有不同的行?

    以下命令仅返回一行 参数 Context 10被忽略 select string path file txt pattern Context 10 Out GridView 但是 以下命令创建一个包含所有行的文件 select string
  • logback 在 Flink 中不起作用

    我有一个单节点 Flink 实例 它在 lib 文件夹中具有 logback 所需的 jar logback classic jar logback core jar log4j over slf4j jar 我已从 lib 文件夹中删除了
  • 如何在 iOS 中用渐变填充由 CGPoints 定义的形状?

    我在代码中设置了自定义形状的箭头 我想做的就是用渐变填充它 问题是 我不知道如何用渐变填充非矩形形状 暗框内的空间 有任何想法吗 Define colours used in drawing CGContextRef context UIG
  • UILabel 默认字偶距与 CATextLayer 不同

    我有一个UILabel与字符串 LA 我也有一个CATextLayer具有相同的字符NSAttributedString分配给其string财产 字距调整UILabel与CATextLayer 这是代码 void viewDidLoad s
  • ExecutorService 与 Swing 计时器

    我一直在读肮脏的有钱客户 http filthyrichclients org 最近注意到 虽然Java的版本是6 但是并没有提到Concurrent Framework 因此 他们谈论 java util Timer 和 javax sw
  • 如何绑定到用户控件的属性?

    在 Windows 应用商店应用中 您创建一个用户控件来封装和重用代码隐藏和布局 XAML 一个简单的用户控件可能如下所示
  • Android 中的文件浏览器[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • PHP 中的 INET_ATON() 和 INET_NTOA()?

    我想将 IP 地址存储在数据库中 但我还需要在整个应用程序中使用它们 我读到关于使用INET ATON and INET NTOA 在我的 MySQL 查询中 从 IP 地址中获取 32 位无符号整数 这正是我想要的 因为它将比使用 cha
  • 每月累计总数和 Postgresql

    我正在尝试计算 dellstore2 数据库的累计用户数 看看这里的答案和其他论坛 我用了这个 select date trunc month orderdate sum count distinct customerid over ord
  • 无法插入断点。低值地址

    我正在尝试调试这个简单的 C 程序 include
  • Facebook Javascript,如何检测用户是否是我的 Facebook 页面的粉丝?在我的网站上?

    我有以下 JS 代码 该代码的目的是首先获取用户的 facebook id 然后使用 FQL 对照我的页面 ID 检查该 id 并确保该用户是粉丝 我遇到的问题是 代码真正起作用的唯一时间是我使用自己的个人 Facebook 个人资料登录时
  • 具有给定厚度、位置和半径的拉环。 (Java2D)

    我需要画一个具有给定厚度的环 看起来像这样 中心必须是透明的 这样它就不会覆盖之前绘制的形状 或其他戒指 我尝试过这样的事情 g is a Graphics2D object g setColor Color RED g drawOval
  • 验证来自 Spring RESTful 资源服务器的 OAuth 2.0 访问令牌

    我想保护我的 Spring RESTful 后端 一种方法 正确的 是使用 OAuth 2 0 如下所示 http www youtube com watch v 8uBcpsIEz2I http www youtube com watch
  • Android 中按钮的单击和双击

    在我的应用程序中 我有一个按钮 单击和双击按钮后将执行单独的操作 我怎样才能做到这一点 谢谢 嗯 很简单 只需覆盖即可 OnClickListener 的 onClick 方法 public abstract class DoubleCli
  • 使用 Android Jetpack 导航时如何禁用导航图标

    当您向导航架构注册工具栏时 它将创建一个箭头 允许您在您所在的片段上弹出 在一些基本级别的片段上 我不想有汉堡菜单图标或箭头 而是自定义视图对象 如何从视图中禁用后退按钮 我尝试过手动禁用 但很难找到如何使用导航拱门来管理它 val sup
  • 如何访问控制台应用程序中的资源?

    我如何获得访问权限 Properties Resources在控制台应用程序中 这是为了使用解决方案附加的资源文件 Here s exactly what I can see 第一个语法错误不是我关心的 只能使用赋值 调用 自增 自减和新对
  • JavaScriptSerializer 可以排除具有 null/默认值的属性吗?

    我正在使用 JavaScriptSerializer 来序列化一些实体对象 问题是 许多公共属性包含 null 或默认值 有没有办法让 JavaScriptSerializer 排除具有 null 或默认值的属性 我希望生成的 JSON 不
  • 如何使用 sqlite 在 pytest 中启用外键检查

    我有一个 django 项目 其中的测试在我调用时运行py test 但我最近注意到它不检查外键约束 我怎样才能让它检查外键约束 显然 外键约束直到 sqlite 3 才成为可能 https sqlite org foreignkeys h
  • 如何在 OpenGL (ES) 中将非 2 幂纹理显示为精灵而不进行拉伸?

    我想绘制一个任意大小的精灵作为 png 比如说 56 宽 x 30 高之类的完全疯狂的东西 任一维度都不是 2 的幂 另外 我可能想绘制另一个 72 宽 x 33 高的不同精灵 指出这一点是因为这里不接受任何 技巧 我需要处理一般情况 所以