Question

I'm using GLSL to draw sprites from a sprite-sheet. I'm using jME 3, yet there are only small differences, and only with regards to deprecated functions.

The most important part of drawing a sprite from a sprite sheet is to draw only a subset/range of pixels, for example the range from (100, 0) to (200, 100). In the following test case sprite-sheet, and using the previous bounds, only the green part of the sprite-sheet would be drawn.

Test case sprite-sheet.

This is what I have so far:

Definition:

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 file:

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;
}

In jME 3, inTexCoord refers to gl_MultiTexCoord0, and inPosition refers to gl_Vertex.

As you can see, I tried to give the texture_coordinate a vec4 type, rather than a vec2, so as to be able to reference its p and q values (texture_coordinate.p and texture_coordinate.q). Modifying them only resulted in different hues.

m_Color refers to the color, inputted by the user, and serves the purpose of altering the hue. In this case, it should be disregarded.

So far, the shader works as expected and the texture displays correctly.

I've been using resources and tutorials from NeHe (http://nehe.gamedev.net/article/glsl_an_introduction/25007/) and Lighthouse3D (http://www.lighthouse3d.com/tutorials/glsl-tutorial/simple-texture/).

Which functions/values I should alter to get the desired effect of displaying only part of the texture?

Was it helpful?

Solution

Generally, if you want to only display part of a texture, then you change the texture coordinates associated with each vertex. Since you don't show your code for how you're telling OpenGL about your vertices, I'm not sure what to suggest. But in general, if you're using older deprecated functions, instead of doing this:

// 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);

You could do this:

// 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);

If you're using VBOs, then you need to modify your array of texture coordinates to access the appropriate section of your texture in a similar manner.

For the sampler2D the texture coordinates are normalized so that the leftmost and bottom-most coordinates are 0, and the rightmost and topmost are 1. So for your example of a 300-pixel-wide texture, the green section would be between 1/3rd and 2/3rds the width of the texture.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top