Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (762)
Games in Android Showcase (229)
games submitted by our members
Games in WIP (846)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [solved]Blend two textures for one vbo  (Read 6710 times)
0 Members and 1 Guest are viewing this topic.
Offline Alexvice24

Senior Newbie


Medals: 1
Exp: 1 year



« Posted 2014-11-28 16:39:59 »

Hi! This is my first post so I'm not sure if I'm posting this in the right place :/

So I'm trying two blend two textures(earth surface, clouds) onto a simple sphere created using an obj file that I exported from blender. I'm using 4 buffer objects for the vertices, textureCoords, normals and faces. Before adding the second material(clouds) my result looked fine:

Then I added the second material to the rendering code which now looks like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
public void render()
{
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, handles.get(VERTEX));
    glVertexPointer(3, GL_FLOAT, 0, 0);

    material.bind(); // the earth's surface texture
    glBindBuffer(GL_ARRAY_BUFFER, handles.get(TEXTURE));
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    material2.bind(); // the semi transparent cloud texture
    glBindBuffer(GL_ARRAY_BUFFER, handles.get(TEXTURE));
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, handles.get(NORMAL));
    glNormalPointer(GL_FLOAT, 0, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handles.get(FACE));
    glDrawElements(GL_TRIANGLES, modelScheme.getIndices().size(),    GL_UNSIGNED_INT, 0);

    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
}


And enabled blending in the opengl initializing code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);


And the result I'm getting now is this:


Does anyone know why this effect happens instead of the two materials blend together nicely? If anyone is interested the two textures I use for the materials are these:




(In the cloud texture for some reason the transparent parts are not showing here)

I Apologise for the big post and I wish you all the best

Cheers,

Alex
Offline Longarmx
« Reply #1 - Posted 2014-11-28 16:46:28 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
public void render()
{
    ...

    material.bind(); // the earth's surface texture
    glBindBuffer(GL_ARRAY_BUFFER, handles.get(TEXTURE));
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

++  glBindBuffer(GL_ARRAY_BUFFER, handles.get(NORMAL));
++  glNormalPointer(GL_FLOAT, 0, 0);

++  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handles.get(FACE));
++  glDrawElements(GL_TRIANGLES, modelScheme.getIndices().size(),    GL_UNSIGNED_INT, 0);

    material2.bind(); // the semi transparent cloud texture
--  glBindBuffer(GL_ARRAY_BUFFER, handles.get(TEXTURE));
--  glTexCoordPointer(2, GL_FLOAT, 0, 0);

--  glBindBuffer(GL_ARRAY_BUFFER, handles.get(NORMAL));
--  glNormalPointer(GL_FLOAT, 0, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handles.get(FACE));
    glDrawElements(GL_TRIANGLES, modelScheme.getIndices().size(),    GL_UNSIGNED_INT, 0);

    ...
}


You aren't rendering the vbo when you have the earth texture bound. It's getting "overwritten" when you're setting up the clouds material.

Edit: Look at SHC's for a better alternative because it only requires a single pass.

Offline SHC
« Reply #2 - Posted 2014-11-28 16:51:06 »

Use two textures at the same time. Bind one texture to texture unit 0 and another to unit 1. And use uniforms to send them to the shaders. In the shader,

1  
2  
3  
4  
5  
vec4 mapTexel = texture(texMap, texCoords);
vec4 cloudTexel = texture(texCloud, texCoords);

// Final texture color is a blend of both
vec4 texelColor = mapTexel * cloudTexel

That should solve the problem.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Alexvice24

Senior Newbie


Medals: 1
Exp: 1 year



« Reply #3 - Posted 2014-11-28 17:05:15 »

Thanks for the fast replies! I appreciate it!

While obviously SHC's is pointing me toward the right direction, I admit I'm unfamiliar with shaders and I wanted to keep it shader-less for just this example before I move on into more complex examples.

Longarmx I followed your advice but I still can't seem to get it working! (I'm probably doing something silly). I changed the rendering method so it renders the mesh 2 times with the 2 different textures, and now the result has only the earth's surface texture showing!

The rendering method looks like this following your directions
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
    public void render()
    {
        ....
        glBindBuffer(GL_ARRAY_BUFFER, handles.get(VERTEX));
        glVertexPointer(3, GL_FLOAT, 0, 0);
       
        glBindBuffer(GL_ARRAY_BUFFER, handles.get(NORMAL));
        glNormalPointer(GL_FLOAT, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER, handles.get(TEXTURE));
        glTexCoordPointer(2, GL_FLOAT, 0, 0);

        material.bind(); // the earth's surface texture
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handles.get(FACE));
        glDrawElements(GL_TRIANGLES, modelScheme.getIndices().size(),    GL_UNSIGNED_INT, 0);
       
        material2.bind();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handles.get(FACE));
        glDrawElements(GL_TRIANGLES, modelScheme.getIndices().size(),    GL_UNSIGNED_INT, 0);
   
        ...
    }
Offline Longarmx
« Reply #4 - Posted 2014-11-28 17:17:51 »

You may be experiencing an issue where some z-fighting is going on. The cloud texture would be rendered, but the earth texture would be obstructing the cloud texture. Try to move the camera around and see if parts of the cloud texture flashes intermittently.

Offline Alexvice24

Senior Newbie


Medals: 1
Exp: 1 year



« Reply #5 - Posted 2014-11-28 17:29:30 »

I'll play around with my code and see if I can find the source of the issue.
It appears that only the first glDrawElements call actually happens. It is not a texturing issue.

Anyway many thanks for your interest in helping me Smiley
Offline Longarmx
« Reply #6 - Posted 2014-11-28 17:34:45 »

One last thing to try is to setup all the pointers before each of the draw calls. I don't know why it would do anything (maybe pointers are reset in special conditions?), but it's worth a shot Pointing

Offline Alexvice24

Senior Newbie


Medals: 1
Exp: 1 year



« Reply #7 - Posted 2014-11-28 17:51:38 »

Wow I finally did it Cheesy

It was as Longarmx proposed! The earth's surface texture was obstructing the clouds' one.

With a quick scaling fix the rendering code is now functional Smiley
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
 
    public void render()
    {
        ....
        glBindBuffer(GL_ARRAY_BUFFER, handles.get(VERTEX));
        glVertexPointer(3, GL_FLOAT, 0, 0);
       
        glBindBuffer(GL_ARRAY_BUFFER, handles.get(NORMAL));
        glNormalPointer(GL_FLOAT, 0, 0);

        glBindBuffer(GL_ARRAY_BUFFER, handles.get(TEXTURE));
        glTexCoordPointer(2, GL_FLOAT, 0, 0);

        material.bind(); // the earth's surface texture
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handles.get(FACE));
        glDrawElements(GL_TRIANGLES, modelScheme.getIndices().size(), GL_UNSIGNED_INT, 0);
       
       
        MatrixUtils.pushMatrix();
        {
            MatrixUtils.scalef(1.02f);
     
            material2.bind();
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handles.get(FACE));
            glDrawElements(GL_TRIANGLES, modelScheme.getIndices().size(), GL_UNSIGNED_INT, 0);
        }
        MatrixUtils.popMatrix();
        .....
    }

And the evidence Azn
Pages: [1]
  ignore  |  Print  
 
 

 
EgonOlsen (351 views)
2018-06-10 19:43:48

EgonOlsen (344 views)
2018-06-10 19:43:44

EgonOlsen (292 views)
2018-06-10 19:43:20

DesertCoockie (518 views)
2018-05-13 18:23:11

nelsongames (843 views)
2018-04-24 18:15:36

nelsongames (830 views)
2018-04-24 18:14:32

ivj94 (1259 views)
2018-03-24 14:47:39

ivj94 (395 views)
2018-03-24 14:46:31

ivj94 (1058 views)
2018-03-24 14:43:53

Solater (413 views)
2018-03-17 05:04:08
Java Gaming Resources
by philfrei
2017-12-05 19:38:37

Java Gaming Resources
by philfrei
2017-12-05 19:37:39

Java Gaming Resources
by philfrei
2017-12-05 19:36:10

Java Gaming Resources
by philfrei
2017-12-05 19:33:10

List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!