Subtle Development Space
Subtle Development Space

Reputation: 1254

Opengl multiple textures with mixed colors

Why are the colors of the textures mixed? How can i fix that?

This is how i draw and initialize:

private void initGL_3D() {
    int width = Display.getWidth();
    int height = Display.getHeight();
    glLoadIdentity(); // Reset The Projection Matrix
    GLU.gluPerspective(45.0f, ((float) width / (float) height), 0.1f, 100.0f); // Calculate The Aspect Ratio Of The Window
    glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix

    glLoadIdentity(); // Reset The Modelview Matrix

    glShadeModel(GL_SMOOTH); // Enables Smooth Shading


    glClearDepth(1.0f); // Depth Buffer Setup
    glEnable(GL_DEPTH_TEST); // Enables Depth Testing
    glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
}

private void initGL_2D() {
    int width = Display.getWidth();
    int height = Display.getHeight();

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0f, width, height, 0.0f, 1, -1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glDisable(GL_DEPTH_TEST);

    // Enable transparency
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

private void renderGL() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    int width = Display.getWidth();
    int height = Display.getHeight();

    glEnable(GL_TEXTURE_2D);

    glViewport(0, 0, width, height); // Reset The Current Viewport\
    glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
    if (game){
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
        initGL_3D();
        renderGL_3D();
    }
    initGL_2D();
    renderGL_2D();
}

private void renderGL_3D() {
    glLoadIdentity();

    glTranslatef(0, 0f, -3f);

    glRotatef(rotationX, 1.0f,0.0f,0.0f);

    glRotatef(rotationY/4, 0.0f,1.0f,0.0f);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture1.getTextureID());

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texture2.getTextureID());

    glBegin(GL_TRIANGLES);
    glMultiTexCoord2f(GL_TEXTURE0, 0, 0);
    glVertex3f(0, 0, 0);

    glMultiTexCoord2f(GL_TEXTURE0, 1, 0);
    glVertex3f(1, 0, 0);

    glMultiTexCoord2f(GL_TEXTURE0, 0, 1);
    glVertex3f(0, 1, 0);

    glMultiTexCoord2f(GL_TEXTURE1, 1, 1);
    glVertex3f(1, 1, 0);

    glMultiTexCoord2f(GL_TEXTURE1, 1, 0);
    glVertex3f(1, 0, 0);

    glMultiTexCoord2f(GL_TEXTURE1, 0, 1);
    glVertex3f(0, 1, 0);
    glEnd();
}

private void renderGL_2D() {
    if (mainMenu) {
    gui.setBackground(0);
    glLoadIdentity();
    for (Button button : gui.buttons) {
        float posX;
        float posY;

        if (button.posX == "center") {
            posX = Display.getWidth()/2-button.width/2;
        } else {
            posX = Integer.parseInt(button.posX);
        }

        if (button.posY == "center") {
            posY = Display.getHeight()/2-button.height/2;
        } else {
            posY = Integer.parseInt(button.posY);
        }

        if(guiMouseX > posX && guiMouseY > posY && guiMouseX < posX + button.width && guiMouseY < posY + button.height){
            button.textureOver.bind();
            button.mouseOver.run();
            if (Mouse.isButtonDown(0)) {
                button.mouseDown.run();
            }
        } else {
            button.texture.bind();
        }

        float imageWidth = button.texture.getImageWidth();
        float textureWidth = button.width/imageWidth;
        float imageHeight = button.texture.getImageHeight();
        float textureHeight = button.height/imageHeight;

        glBegin(GL_QUADS);
        glTexCoord2f(0, 0);
        glVertex2f(posX, posY);
        glTexCoord2f(textureWidth, 0);
        glVertex2f(posX + button.width, posY);
        glTexCoord2f(textureWidth, textureHeight);
        glVertex2f(posX + button.width, posY + button.height);
        glTexCoord2f(0, textureHeight);
        glVertex2f(posX, posY + button.height);
        glEnd();
    }
    }
}

Everything draws fine, but the only problem is that the texture colors are mixed!

This is how the textures look when i run the app enter image description here

and these are the textures with theyr normal colors

enter image description here

and

enter image description here

Upvotes: 0

Views: 586

Answers (2)

Izzy
Izzy

Reputation: 412

If you want multitexturing on triangles then there are two problems:

On first triangle you are setting texture coordinates for ONLY texture 1 (should be for texture 2 also),

On second triangle you are setting texture coordinates for ONLY texture 2 (shoudl be for texture 1 also).

Second problem is that instead glActiveTexture(GL_TEXTURE0) you should use glActiveTextureARB:

 //glActiveTexture(GL_TEXTURE0);
 glActiveTextureARB(GL_TEXTURE0_ARB );
 glBindTexture(GL_TEXTURE_2D, texture1.getTextureID());

 //glActiveTexture(GL_TEXTURE1);
 glActiveTextureARB(GL_TEXTURE1_ARB );
 glBindTexture(GL_TEXTURE_2D, texture2.getTextureID());

That is the right way of multitexturing.

If you want two triangles with two different textures:

  • either use atlas texture and set UVs to point to right coordinates
  • skip multitexturing, set first texture, draw triangle, set second texture, draw triangle.

Upvotes: 0

Ani
Ani

Reputation: 10896

Because you're calling "renderGL_3D" from inside "renderGL". This function draws two triangles, one with texture0 and the other with texture1.

The 0th stage texcoords for the triangle in the lower left are all zeros. This makes it sample the top left of the green texture, so it is green as well. Since you have blending on, the second whitish texture is blended on top, making it all green.

To test this, try making the top left pixel of your white texture magenta or some other easily distinguishable color. Now the lower-left triangle should be a dirty magenta (mixed in with some green due to filtering).

As for your solution, you need to disable multi-texturing blending (not GL_BLEND - which blends the final color provided by the rasterizer into the framebuffer). You can do this by

    glActiveTexture(GL_TEXTURE0);
    glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);

and the same for texture unit 1

    glActiveTexture(GL_TEXTURE1);
    glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);

This should work.

Upvotes: 1

Related Questions