简体   繁体   中英

opengl y-axis not scaling with x or z

I'm not really sure how to even describe this problem so please excuse the terrible title. I have a simple model ( it is actually a tile but I made it a cube to better illustrate the issue ) that is 2 units high, wide and deep. To draw a continuous field of these I simply increment X and Z by 2 appropriately and they all render nicely next to one another. If I want to create a step up so my flat field has a new level to it I add 2 to the Y value for a segment of the field expecting that the bottom of the top level would then align perfectly with the top of the lower level.

What actually happens is the top level renders a fair distance above the lower level. Why? What would cause this? I ran some tests and found that I'd have to increment Y by a number somewhere between 0.6 and 0.7 for the bottom to align properly with the top.

I thought maybe it was the viewport but I think that is fine. The models don't look warped. Has anyone run into something like this before?

See the attached image for an example of what I'm talking about. The red line illustrates this strange separation of the top and bottom layers.

测试图像说明问题

The Render function

public void draw() throws Exception {

    float x = 0;
    double y = 0;
    float z = 0;
    int cidx = 0;
    boolean firstCube = true;

    glfwSwapBuffers(window); // swap the color buffers

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer

    //calc rotate camera
    if (updatecamera == true){
        updateCamera();
    }

    glUseProgram(shader.iProgram);

    //some lighting...
       Vector4f lp = new Vector4f(lightX, lightY, lightZ,1.0f);
       //float[] lp = {xa, ya + 100, za - 120,1.0f}; //set light source to same as camera eye for now.

       shader.setUniform(iLightCam, camera);
       shader.setUniform(iLightVec, lp);

    //get picking ray
    if (worldClicked == true){
        pick = makeRay(pick, cursorX, (DISPLAY_HEIGHT - ((DISPLAY_HEIGHT - VP_HEIGHT) / 2)) - cursorY);
    }


    for(Iterator<Quad> qd = quads.iterator(); qd.hasNext(); ) {
        //init cull check
        frust.cullIn = 0;
        frust.cullOut = 0;

        quad = qd.next();

        pickthisQuad = false;

        firstCube = true; //the first cube is used to set the values of the Quad OBB.

        for(Iterator<Cube> i = quad.cubes.iterator(); i.hasNext(); ) {

            cb = i.next(); 
            x = cb.x;
            z = cb.z;
            //y = cb.y;

            //testing odd Y behaviour
            if ( y == 0) {
                y = lightX;
            }else{
                y = 0;
            }

            System.out.println(" y: " + y);

            //init
            model.setIdentity();

            //ROTATE
            //set translate
            vTrans.set(transx + x, (float) (transy + y), transz + z);   
            Matrix4f.translate(vTrans, model1, model);                  

            vTrans.set(-(transx + x), (float) (-transy + y), -(transz + z));    
            Matrix4f.translate(vTrans, model, model);
            Matrix4f.rotate((float) Math.toRadians(rotY), new Vector3f(0,1,0), model, model);
            vTrans.set((transx + x), (float) (transy + y), (transz + z));   
            Matrix4f.translate(vTrans, model, model);

            Matrix4f.mul(model, camera, modelview); 
            shader.setUniform(iModelView, modelview);

            Matrix3f norm = new Matrix3f();
            norm.m00 = modelview.m00;
            norm.m01 = modelview.m01;
            norm.m02 = modelview.m02;
            norm.m10 = modelview.m10;
            norm.m11 = modelview.m11;
            norm.m12 = modelview.m12;
            norm.m20 = modelview.m20;
            norm.m21 = modelview.m21;
            norm.m22 = modelview.m22;

            shader.setUniform(iNorm, norm);
            shader.setUniform(iProj, projection);
            shader.setUniform(iCam, camera);
            shader.setUniform(iModel, model);

            test_renderFrustumandCrosslines();

            manageTextures(cb);

            render();

            cidx++;

        }//cubes


        cidx = 0;

    }//quads

/**
* TESTING
*/
    glUseProgram(shaderLine.iProgram);
    Matrix4f mvp = new Matrix4f();
    mvp.setIdentity();
    Matrix4f.mul(projection,  camera, mvp);
    shaderLine.setUniform(iMVPLine, mvp);
    renderLine();
    renderCross();

    worldClicked = false;

    glFinish();
}

Is there any special thoughts about the 2 first translates in the rotation code? The x ans z translations will cancel each other out but not the y axis. Which could be the source of the problem.

        vTrans.set(transx + x, (float) (transy + y), transz + z);   
        Matrix4f.translate(vTrans, model1, model);                  

        vTrans.set(-(transx + x), (float) (-transy + y), -(transz + z));    
        Matrix4f.translate(vTrans, model, model);

What happens if you remove these 4 lines? You still do the translation after the rotation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM