3

I have created two textures for two images. Now I want to show this textures in opengl in an order that left part of image2, full image1, right part of image2. I have done like below. Image1 shows at the center of opengl screen. But left and right part of screen is not correct (which should show left part of image2 and right part of image2 respectively)

Vertex shader:

attribute vec3 a_position;
varying vec2 vTexCoord;
void main() {
    vTexCoord = (a_position.xy + 1) / 2;
    gl_Position = vec4(a_position,1);
}

Fragment shader:

precision highp float;
uniform sampler2D sTexture;//texture for image 1
uniform sampler2D sTexture1;//texture for image 2
varying vec2 vTexCoord;

void main () {
    if ( vTexCoord.x<=0.25 )
        gl_FragColor = texture2D (sTexture1, vec2(vTexCoord.x/2.0, vTexCoord.y));
    else if ( vTexCoord.x>0.25 && vTexCoord.x<0.75 )
        gl_FragColor = texture2D (sTexture, vec2(vTexCoord.x*2.0, vTexCoord.y));
    else if(vTexCoord.x>=0.75 )
        gl_FragColor = texture2D (sTexture1,  vec2(vTexCoord.x*2.0-1.0, vTexCoord.y));
}

Compiling shaders:

void CreateShaders() {
    /***********Vert Shader********************/
    vertShader = GL.CreateShader(ShaderType.VertexShader);
    GL.ShaderSource(vertShader, vertexShaderSource);
    GL.CompileShader(vertShader);

    /***********Frag Shader ****************/
    fragShader = GL.CreateShader(ShaderType.FragmentShader);
    GL.ShaderSource(fragShader, fragmentShaderSource);
    GL.CompileShader(fragShader);
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
nsds
  • 961
  • 4
  • 13
  • 39
  • Can you please reformat this code so that it's actually readable? – Bartek Banachewicz Nov 22 '18 at 11:23
  • please check now – nsds Nov 22 '18 at 11:27
  • What do you mean by "But left and right part of screen is not correct"? You need to provide a full detail on what is going on. "not correct" can be anything from being black, being green, seeing garbage, seeing the wrong texture with correct coordinates, seeing correct texture with wrong coordinates (not the correct part of it)... – Matic Oblak Nov 22 '18 at 12:14
  • Also define what is your expected result. Are you expecting to see all 3 images as a whole stacked one next to another or do you want to simply overlay the middle part of `image1` with `image2`? – Matic Oblak Nov 22 '18 at 12:16

1 Answers1

2

I want to show this textures in opengl in an order that left part of image2, full image1, right part of image2

If the texture coordinate is less than 0.25 then you want to show the rang [0, 0.5] of image2. You have to map the x component of the texture coordinate from [0.0, 0.25] to [0, 0.5]:

vec2( vTexCoord.x*2.0, vTexCoord.y );

If the texture coordinate is grater then you want to show the rang [0.5, 1] of image2. You have to map the x component of the texture coordinate from [0.75, 1.0] to [0.5, 1.0]:

vec2( (vTexCoord.x-0.75)*2.0 + 0.5, vTexCoord.y );

or

vec2( vTexCoord.x*2.0 - 1.0, vTexCoord.y );

If the texture coordinate is grater than 0.25 and less than 0.75 then you want to show the full range of image1. You have to map the x component of the texture coordinate from [0.25, 0.75] to [0.0, 1.0]:

vec2( vTexCoord.x*2.0 - 0.5, vTexCoord.y );

The shader code my look like this

precision highp float;
uniform sampler2D sTexture;//texture for image 1
uniform sampler2D sTexture1;//texture for image 2
varying vec2 vTexCoord;

void main ()
{
    float u = vTexCoord.x*2.0;
    float a = 0.0; 
    if( vTexCoord.x > 0.75 )
    {
       u -= 1.0;
    }
    else if ( vTexCoord.x >= 0.25 )
    { 
       u -= 0.5;
       a  = 1.0;
    }

    vec4 color1 = texture2D(sTexture1, vec2(u, texCoord.y));
    vec4 color2 = texture2D(sTexture,  vec2(u, texCoord.y));

    gl_FragColor = mix(color2, color1, a);
}

Extension to the answer:

if I want to show only a portion of right image,for example (0.6,0.8).

You want to map [0.75, 1.0] to [0.6, 0.8]:

  1. [0.75, 1.0] to [0, 1]: u' = (u-0.75)/0.25

  2. [0, 1] to [0.6, 0.8]: u'' = u'*0.2+0.6

This leads to:

u = (vTexCoord.x-0.75)*0.2/0.25 + 0.6;

when mapping [0.75, 1.0] to [0.6, 0.8] i wish to display the remain portion of [0.75, 1.0] with black/white color. when using (vTexCoord.x-0.75)*0.2/0.25 + 0.6 image with portion [.6,.8] is filled in [0.75, 1.0]

You have to convert the RGB color to grayscal. I recommend to use the a formula for Relative luminance:

float grayscale = dot(color1, vec3(0.2126, 0.7152, 0.0722));
color1.rgb      = vec3(grayscale);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Hi, I want to to flip the left portion. tried like below.but failed. if ( vTexCoord.x <= 0.25 ) { gl_FragColor = texture2D(sTexture1, vec2(1.0- (vTexCoord.x*2.0), vTexCoord.y)); } – nsds Nov 23 '18 at 10:51
  • 1
    The coordinates of the left part are in range [0, 0.5], so it has to be `0.5-vTexCoord.x*2.0` - `gl_FragColor = texture2D(sTexture1, vec2(0.5-vTexCoord.x*2.0, vTexCoord.y));` – Rabbid76 Nov 23 '18 at 10:53
  • hi, if I want to show only a portion of right image,for example (0.6,0.8). I have tried like below . else if(vTexCoord.x >= 0.75 ) { vec2( (vTexCoord.x-0.75)*2.0 + 0.6, vTexCoord.y ); } But it shows a blurred area only. – nsds Nov 26 '18 at 06:20
  • sorry I couldn't understand the logic. why need to divide by .25 ? – nsds Nov 26 '18 at 07:00
  • as you mentioned earlier, to map the x component of the texture coordinate from [0.75, 1.0] to [0.0, 1.0] we have to perform u'=(u-0.75)*2.0 + 0.0 right? then how is this become u'=(u-0.75)/(1.0-0.75) – nsds Nov 26 '18 at 07:29
  • 1
    @nsds I never said `u'=(u-0.75)*2.0` I said `u' = (u-0.75)/0.25`! To map fro [0, 0.25] to [0, 1] you have to multiply by 4 respectively divide by 0.25 because `1/4 = 0.25` and `4 == 1/0.25`. I used 0.25 because the size of the range is 0.25 and can be calculated by `1-0.75`. I tried to point out how the values of the range change the formula. – Rabbid76 Nov 26 '18 at 07:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/184255/discussion-between-nsds-and-rabbid76). – nsds Nov 26 '18 at 08:13
  • when mapping [0.75, 1.0] to [0.6, 0.8] i wish to display the remain portion of [0.75, 1.0] with black/white color. when using (vTexCoord.x-0.75)*0.2/0.25 + 0.6 image with portion [.6,.8] is filled in [0.75, 1.0] – nsds Nov 26 '18 at 09:34
  • "when mapping [0.75, 1.0] to [0.6, 0.8] i wish to display the remain portion of [0.75, 1.0] with black/white color" - means I want to display the areas [0.5,0.6] and [0.8,1.0] in black/white color.and [.6,.8] should show that portion of image – nsds Nov 26 '18 at 10:47
  • Please note that the construct you're propagating here is actually _undefined_ in the GL: For example GLSL spec 3.30, section 8.7 states: "Some texture functions (non-“`Lod`” and non-“`Grad`” versions) may require implicit derivatives. Implicit derivatives are undefined within non-uniform control flow and for vertex and geometry shader texture fetches.". Note that the derivatives are not only used for mipmapping and anisotropic filtering, but also to select between minification / magnification. While the whole conecept is fishy, in practice, you might see some artifacts at the transitions. – derhass Nov 26 '18 at 14:10
  • 1
    Well, "this reason" at least could be fixed by editing it to use the explicit `Lod` versions. However, these are not allowed in the FS in the early GLSL versions, and that code seems to use 1.10 or 1.20, so that option isn't really there, either. The other quick-fix would be to always sample both textures and store the results in two different variables, and only conditionally decide between those. That would be well-defined, at least. – derhass Nov 26 '18 at 14:51
  • @Rabbid76 Do you want to delete this answer? – nsds Nov 27 '18 at 03:32
  • @nsds Not I corrected it by using the suggestions of the comments – Rabbid76 Nov 27 '18 at 05:48
  • @Rabbid76 Could you please help me on this doubt? https://stackoverflow.com/questions/53429788/show-half-portion-of-image-side-by-side-opengl/53431171?noredirect=1#comment93823133_53431171 – nsds Aug 03 '20 at 09:11