在GLSL中显示纹理的一部分

时间:2014-01-23 12:12:55

标签: opengl glsl shader texture-mapping jmonkeyengine

我正在使用GLSL从精灵表中绘制精灵。我正在使用jME 3,但只有很小的差异,只有关于已弃用的功能。

从精灵表中绘制精灵的最重要部分是仅绘制像素的子集/范围,例如从(100,0)到(200,100)的范围。在下面的测试用例精灵表中,并使用前面的边界,只会绘制精灵表的绿色部分。

Test case sprite-sheet

这是我到目前为止所做的:

定义:

MaterialDef Solid Color {
    //This is the list of user-defined variables to be used in the shader
    MaterialParameters {
        Vector4 Color
        Texture2D ColorMap
    }
    Technique {
        VertexShader GLSL100:   Shaders/tc_s1.vert
        FragmentShader GLSL100: Shaders/tc_s1.frag

        WorldParameters {
            WorldViewProjectionMatrix
        }
    }
}

.vert文件:

uniform mat4 g_WorldViewProjectionMatrix;
attribute vec3 inPosition;

attribute vec4 inTexCoord;
varying vec4 texture_coordinate;

void main(){
    gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
    texture_coordinate = vec4(inTexCoord);
}

.frag:

uniform vec4 m_Color;
uniform sampler2D m_ColorMap;
varying vec4 texture_coordinate;

void main(){
    vec4 color = vec4(m_Color);
    vec4 tex = texture2D(m_ColorMap, texture_coordinate);
    color *= tex;
    gl_FragColor = color;
}

在jME 3中,inTexCoord引用gl_MultiTexCoord0,inPosition引用gl_Vertex。

正如你所看到的,我试图给texture_coordinate一个vec4类型而不是vec2,以便能够引用它的p和q值(texture_coordinate.p和texture_coordinate.q)。修改它们只会产生不同的色调。

m_Color是指用户输入的颜色,用于改变色调。在这种情况下,应该忽略它。

到目前为止,着色器按预期工作,纹理显示正确。

我一直在使用NeHe(http://nehe.gamedev.net/article/glsl_an_introduction/25007/)和Lighthouse3D(http://www.lighthouse3d.com/tutorials/glsl-tutorial/simple-texture/)的资源和教程。

我应该改变哪些函数/值以获得仅显示部分纹理的效果?

1 个答案:

答案 0 :(得分:1)

通常,如果您只想显示纹理的一部分,则可以更改与每个顶点关联的纹理坐标。既然你没有显示你如何告诉OpenGL关于你的顶点的代码,我不知道该建议什么。但总的来说,如果您使用较旧的弃用函数,而不是这样做:

// Lower Left of triangle
glTexCoord2f(0,0);
glVertex3f(x0,y0,z0);

// Lower Right of triangle
glTexCoord2f(1,0);
glVertex3f(x1,y1,z1);

// Upper Right of triangle
glTexCoord2f(1,1);
glVertex3f(x2,y2,z2);

你可以这样做:

// Lower Left of triangle
glTexCoord2f(1.0 / 3.0, 0.0);
glVertex3f(x0,y0,z0);

// Lower Right of triangle
glTexCoord2f(2.0 / 3.0, 0.0);
glVertex3f(x1,y1,z1);

// Upper Right of triangle
glTexCoord2f(2.0 / 3.0, 1.0);
glVertex3f(x2,y2,z2);

如果您正在使用VBO,则需要修改纹理坐标数组,以类似方式访问纹理的相应部分。

对于sampler2D,纹理坐标被标准化,以便最左边和最底部的坐标为0,最右边和最顶部的坐标为1.因此,对于300像素宽纹理的示例,绿色截面将在纹理宽度的1/3和2/3之间。