2011-04-23 44 views
6

在决定尝试使用现代OpenGL进行编程之后,我留下了固定功能管道,并且我不完全确定要获得与之前相同的功能。使用现代OpenGL进行像素完美纹理映射

我想纹理地图四边形像素完美大小,匹配纹理大小。例如,128x128纹理映射到四边形128x128的大小。

这是我的顶点着色器。

 

    #version 110 
    uniform float xpos; 
    uniform float ypos; 
    uniform float tw; // texture width in pixels 
    uniform float th; // texture height in pixels 
    attribute vec4 position; 
    varying vec2 texcoord;   
void main() 
    { 
    mat4 projectionMatrix = mat4(2.0/600.0, 0.0, 0.0, -1.0, 
            0.0, 2.0/800.0, 0.0, -1.0, 
            0.0, 0.0, -1.0, 0.0, 
            0.0, 0.0, 0.0, 1.0); 

    gl_Position = position * projectionMatrix; 
    texcoord = (gl_Position.xy); 
    } 
 

这是我的片段着色器:

 

    #version 110 
    uniform float fade_factor;  
    uniform sampler2D textures[1]; 
    varying vec2 texcoord; 

    void main() 
    { 
     gl_FragColor = texture2D(textures[0], texcoord); 
    } 
 

我的顶点数据作为这样的,其中w和h是纹理的宽度和高度。

 

    [ 
    0, 0, 
    w, 0, 
    w, h, 
    0, h 
    ] 
 

我打开一个128x128的质地和与这些着色器我看到图像重复4次:http://i.stack.imgur.com/UY7Ts.jpg

可以在正确的道路的人提供建议,以便能够翻译和规模给予TW日,XPOS ,xpos制服?

+0

Hello,Lefty!欢迎来到StackOverflow。请记住一些事项 - 请使用四个空格(或使用“{}”图标)缩进代码,以便格式正确。另外,当在OpenGL标签中发布时,在指定OpenGL版本时很有帮助。特别是因为你的代码样本听起来像OpenGL 2.0,这确实有用,但今天不是“现代”。 :) – Kos 2011-04-23 13:17:28

+0

感谢您的答复。这是现代的OpenGL(> = 3?),因为我没有使用固定功能流水线,我的顶点数据是以数组形式提供的,纹理采样是使用着色器完成的。这就是说,我还是比较新的这个,所以纠正我,如果我错了:) – Lefty 2011-04-23 13:22:55

+0

相关http://stackoverflow.com/questions/7922526/opengl-deterministic-rendering-between-gpu-vendor – 2016-07-13 12:50:34

回答

6

有一个问题是:

mat4 projectionMatrix = mat4(2.0/600.0, 0.0, 0.0, -1.0, 
            0.0, 2.0/800.0, 0.0, -1.0, 
            0.0, 0.0, -1.0, 0.0, 
            0.0, 0.0, 0.0, 1.0); 

gl_Position = position * projectionMatrix; 

转型matices是右关联的,即你应该乘相反的顺序。您通常也不会在着色器中指定投影矩阵,而是将其作为统一进行传递。 OpenGL为您提供了投影和模型视图的准备工作。在OpenGL-3核心中,您可以重新使用统一名称来保持兼容。

// predefined by OpenGL version < 3 core: 
#if __VERSION__ < 400 
uniform mat4 gl_ProjectionMatrix; 
uniform mat4 gl_ModelviewMatrx; 
uniform mat4 gl_ModelviewProjectionMatrix; // premultiplied gl_ProjectionMatrix * gl_ModelviewMatrix 
uniform mat4 gl_ModelviewInverseTranspose; // needed for transformin normals 

attribute vec4 gl_Vertex; 

varying vec4 gl_TexCoord[]; 
#endif 

void main() 
{ 
    gl_Position = gl_ModelviewProjectionMatrix * gl_Vertex; 
} 

接下来你必须明白,纹理坐标不解决纹理像素(纹理元素),但质地应被理解为与给定的采样点的插值功能;纹理坐标0或1不会撞击纹理元素的中心,但恰好位于环绕之间,因此模糊。只要屏幕尺寸的四边形与纹理尺寸完全一致,这就好了。但是,只要你想展示一个子图像,事情就会变得有趣(我将它作为练习让读者弄清楚确切的映射;提示:你将拥有0.5 /维和(维 - 1)/维在解决方案中)

+0

这可能是这个问题http://stackoverflow.com/questions/34952184/pixel-perfect-shader-in-unity对你来说很简单,DW! :o – Fattie 2016-01-22 17:04:54