iOS-利用OpenGL加载VR(本地网络)图片

iOS-利用OpenGL加载VR(本地网络)图片,第1张

>

可能是因为你抠图的方法不对,使用了魔棒直接点击背景的方法。

解决方法:

1、直接用裁切工具沿图像边缘切一下。

2、新建画布,再将这个用鼠标拖进新建的画布中,用移动工具移好位置,再按CTRL+T组合键缩放大小,用矩形选框工具框选裁掉即可。

我有一个基于 OpenGL 的 gui。我使用超分辨率能够处理各种比例。不是放大图像,而是缩小图像(除非碰巧有人以 4000x4000+ 分辨率运行)。

问题是,OpenGL 似乎并不能顺利缩减。我有工件,好像缩放是最近的邻居。 (例如,文本边缘是块状的,即使它们不在原始文件中)

这些是我使用的设置:

glBindTexture(GL_TEXTURE_2D, tex);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

这是一个工件样本,我相信比例是 2:1。由于窗口边缘等原因,可能并不准确。

您可以看到左边缘看起来很完美(虽然不是这样),但右边缘有奇怪的中断。原始图形完全对称,没有伪影。

我试过 GL_NEAREST、GL_LINEAR。没有 mipmapping 所以

OpenGL 在缩放方面肯定不是那么差吗?我想要双三次缩放之类的东西或能产生良好结果的东西。

我使用的是 OpenGL 11。我可能会预先缩放图像,但每次窗口大小发生变化时我都必须这样做,并且 cpu 可能会很慢。首先,您必须了解信号理论,即Nyquist Theorem(该页面在谈论“时间”域中的信号时过于具体;该原理对于所有类型的离散采样信号(包括图像)都是通用的)。在进行下采样时,您始终必须应用lowpass anti aliasing filter,它会切断采样频率一半以上的所有频率分量,以避免产生混叠伪影。如果没有过滤,即使是线性积分下采样器也会产生伪影。实现纹理低通滤波器的实时图形方式是mipmaps。每个 mipmap 级别的截止频率恰好是下一个更高级别的频率的一半。

你现在有两个选择:

实现 mipmapping

实现下采样片段着色器

当然,明智的做法是首先不要以过高的分辨率进行渲染,而是以完全目标分辨率来渲染你的 GUI。

讨论:

解决方案2:

根据你提供的代码,我会猜测可能是什么问题。

尝试加载您的图像或至少分配内存在您使用glParameteri 设置这些纹理参数之前。另外,将GL_TEXTURE_MIN_FILTER 设置各向异性过滤可以应用于不同的级别,此代码将应用到最大级别,如果您愿意,可以使用小于aniso 的数字我用OpenGL渲染出三维场景,然后通过glReadPixels()将三维场景保存为BMP格式的,发现保存的分辨率就是渲染窗口的分辨率,请问通过什么方法可以实现将渲染的场景保存为超过窗口分辨率的?例如:我的图形显示窗口为300300,我想保存为10001000分辨率的如何实现,请大家给点思路,要是有相关的链接或代码也可以我可能问题描述的不清楚,我并不是想渲染得到纹理,只是想将渲染窗口的图像保存为BMP,遇到的问题是保存的只能和窗口大小一样,有没有办法得到保存的场景内容与窗口中的一样,只是得到的大小几倍于窗口么?例如:我渲染的窗口比较小,直观看的话图像并不清晰,保存为后由于较大就比较清晰了是在显卡存储空间中开辟出的一块内存缓存区,用于存储顶点的各类属性信息,如顶点坐标,顶点法线,顶点颜色数据等。

顶点着色器渲染时,可直接从VBO中取出顶点的各类属性数据,由于VBO在显存而不是在内存中,不需要从CPU传输数据,处理效率更高。所以可以理解为VBO就是显存中的一个存储区域,可以保持大量的顶点属性信息。并且可以开辟很多个VBO,每个VBO在OpenGL中有它的唯一标识ID,这个ID对应着具体的VBO的显存地址,通过这个ID可以对特定的VBO内的数据进行存取 *** 作。

顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER,允许同时绑定多个缓冲,只要它们是不同的缓冲类型

可使用glBindBuffer函数把新创建的缓冲绑定到GL_ARRAY_BUFFER目标上。

使用VBO画图

在这里插入描述

顶点数组对象 (Vertex Array Object,VAO)

是一个保存了所有顶点数据属性的状态结合,它存储了顶点数据的格式以及顶点数据所需的VBO对象的引用。

VAO本身并没有存储顶点的相关属性数据,这些信息是存储在VBO中的,VAO相当于是对很多个VBO的引用,把一些VBO组合在一起作为一个对象统一管理。一个着色器程序对象(shader program object) 就是多个着色器结合链接到一起的最终版本。激活的着色器程序对象将在调用渲染 *** 作时使用它会使用比正常分辨率更高的分辨率(即超采样)来渲染场景,当图像输出在帧缓冲中更新时,分辨率会被下采样(Downsample)至正常的分辨率。栅器会将一个图元的所有顶点作为输入,并将它转换为一系列的片段。顶点坐标理论上可以取任意值,但片段不行,因为它们受限于你窗口的分辨率。顶点坐标与片段之间几乎永远也不会有一对一的映射,所以光栅器必须以某种方式来决定每个顶点最终所在的片段/屏幕坐标由于屏幕像素总量的限制,有些边缘的像素能够被渲染出来,而有些则不会。结果就是我们使用了不光滑的边缘来渲染图元,导致之前讨论到的锯齿边缘。多重采样所做的正是将单一的采样点变为多个采样点(这也是它名称的由来)。我们不再使用像素中心的单一采样点,取而代之的是以特定图案排列的4个子采样点(Subsample)。我们将用这些子采样点来决定像素的遮盖度。当然,这也意味着颜色缓冲的大小会随着子采样点的增加而增加。在这里插入描述这里,每个像素包含4个子采样点(不相关的采样点都没有标注),蓝色的采样点被三角形所遮盖,而灰色的则没有。对于三角形的内部的像素,片段着色器只会运行一次,颜色输出会被存储到全部的4个子样本中。而在三角形的边缘,并不是所有的子采样点都被遮盖,所以片段着色器的结果将只会储存到部分的子样本中。根据被遮盖的子样本的数量,最终的像素颜色将由三角形的颜色与其它子样本中所储存的颜色来决定。

问题的关键在于设置裁剪区域的纵横比与视口的纵横比一致。

设置视口大小:

[cpp] view plain copy

<span style="font-size:18px;">glViewport(GLint x,GLint y,GLsizei w,GLsizei h);</span>

(x,y)是视口距离窗口左下角的位置,(w,h)是视口的宽度和高度。

设置二维观察函数:

[cpp] view plain copy

glOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GL double top);

锁定纵横比,注意这里为什么要加一个判断语句。比如当窗口的宽大于高时(w>h),裁剪区域只能设置将高扩大即:(-150/ratio,150/ratio),而不能设置将宽缩小(这样会使图像在w方向的部分显示不出来)

[html] view plain copy

glViewport(0,0,w,h);

GLfloat ratio=(GLfloat)w/(GLfloat)h;

if(w<=h)//保持形状不变

gluOrtho2D(-150,150,-150/ratio,150/ratio);

else

gluOrtho2D(-150ratio,150ratio,-150,150);

具体代码:

[cpp] view plain copy

#include <stdlibh>

#include <GL/gluth>

GLfloat v[3][3]={{-100,00,00},{100,00,00},{00,100,00}};

int num=5;

void reshape(GLsizei w,GLsizei h)

{

GLfloat ratio=(GLfloat)w/(GLfloat)h;

glViewport(0,0,w,h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

if(w<=h)//保持形状不变

gluOrtho2D(-150,150,-150/ratio,150/ratio);

else

gluOrtho2D(-150ratio,150ratio,-150,150);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

void triangle(GLfloat a,GLfloat b,GLfloat c)

{

glVertex3fv(a);

glVertex3fv(b);

glVertex3fv(c);

}

void divide_triangle(GLfloat a,GLfloat b,GLfloat c,int n)

{

GLfloat ab[3],ac[3],bc[3];

if(n>0)

{

for(int j=0;j<3;j++)

{

ab[j]=(a[j]+b[j])/2;

ac[j]=(a[j]+c[j])/2;

bc[j]=(b[j]+c[j])/2;

}

divide_triangle(a,ab,ac,n-1);

divide_triangle(ab,b,bc,n-1);

divide_triangle(ac,bc,c,n-1);

}

else triangle(a,b,c);

}

void display()

{  

glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_TRIANGLES);

divide_triangle(v[0],v[1],v[2],num);

glEnd();

glFlush();

}

void myInit()

{

glClearColor(10,10,10,10);

glColor3f(00,10,00);

glViewport(0,0,500,500);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(-150,150,-150,150);

glMatrixMode(GL_MODELVIEW);

}

void main(int argc,char argv)

{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);

glutInitWindowSize(500,500);

glutInitWindowPosition(0,0);

glutCreateWindow("Sierpinski");

glutReshapeFunc(reshape);

glutDisplayFunc(display);

myInit();

glutMainLoop();

}

视口和视景体,当视口的纵横比和视景体的纵横比相同的时候,改变窗口大小,图像才不会变形;例如:控制视口大小为:glViewprot(0,0,400,200);则其纵横比为2那么控制视景体的参数为:gluPerspective(fovy,2,near,far);可以了控制视景体还有其他函数,原理是一样的opengl编程指南有详细解释。

以上就是关于iOS-利用OpenGL加载VR(本地/网络)图片全部的内容,包括:iOS-利用OpenGL加载VR(本地/网络)图片、OpenGL中如果图片的长和宽不是2的n次方该怎么贴图、OpenGL缩放图片有白边等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9609908.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存