0
\$\begingroup\$

I`m working at VBO terrain renderer. Now i have two troubles:

  1. While try to render 100x100 terrain I have a 50x200 terrain
  2. Textures is not rendering.

I spent really much time about it, and I have really no ideas...

How can I fix this?

Image:

https://i.imgur.com/GiNFKOT.png

My part of code:

public class NGINE2 {
public static int MAX_PICKING_DISTANCE = 20;
public static int RAY_RADIUS = 5;
static int w = 640;
static int h = 480;
static float oldX = 0;
static float oldY = 0;
static float oldZ = 0;

static FloatBuffer cBuffer;
static FloatBuffer vBuffer;
static FloatBuffer tBuffer;

static double[][] map;

int heightmapExaggeration = 7;
static int Size = 100;

Texture floor;

public static void main(String[] args) throws Exception {
    NGINE2 ng = new NGINE2();
    ng.start();
}

void initContext() throws Exception {
    Camera.create();

    w = 800;
    h = 600;

    Display.setDisplayMode(new DisplayMode(w, h));
    Display.setFullscreen(false);
    Display.create();
    glViewport(0, 0, w, h);
    Mouse.setGrabbed(true);

    floor = TextureLoader.getTexture("JPG", ResourceLoader.getResourceAsStream("grassy.jpg"));
}

void renderLoop() {
    long time = 0;
    int frames = 0;
    Random rand = new Random();
    cBuffer = BufferUtils.createFloatBuffer(9 * (Size * Size * 2));
    vBuffer = BufferUtils.createFloatBuffer(9 * (Size * Size * 2));
    tBuffer = BufferUtils.createFloatBuffer(9 * (Size * Size * 2));

    for (int x = 0; x < Size - 1; x++) {
        for (int y = 0; y < Size - 1; y++) {
            tBuffer.put(x * 0.25f).put((float) (map[x][y] * heightmapExaggeration)).put(y * 0.25f);
            tBuffer.put((x + 1) * 0.25f).put((float) (map[x + 1][y] * heightmapExaggeration)).put(y * 0.25f);
            tBuffer.put(x * 0.25f).put((float) (map[x][y + 1] * heightmapExaggeration)).put((y + 1) * 0.25f);
            tBuffer.put((x + 1) * 0.25f).put((float) (map[x + 1][y + 1] * heightmapExaggeration)).put((y + 1) * 0.25f);

            cBuffer.put(rand.nextFloat()).put(rand.nextFloat()).put(rand.nextFloat());
            cBuffer.put(rand.nextFloat()).put(rand.nextFloat()).put(rand.nextFloat());
            cBuffer.put(rand.nextFloat()).put(rand.nextFloat()).put(rand.nextFloat());

            vBuffer.put(x * 0.25f).put((float) (map[x][y] * heightmapExaggeration)).put(y * 0.25f);
            vBuffer.put((x + 1) * 0.25f).put((float) (map[x + 1][y] * heightmapExaggeration)).put(y * 0.25f);
            vBuffer.put(x * 0.25f).put((float) (map[x][y + 1] * heightmapExaggeration)).put((y + 1) * 0.25f);

            cBuffer.put(rand.nextFloat()).put(rand.nextFloat()).put(rand.nextFloat());
            cBuffer.put(rand.nextFloat()).put(rand.nextFloat()).put(rand.nextFloat());
            cBuffer.put(rand.nextFloat()).put(rand.nextFloat()).put(rand.nextFloat());

            vBuffer.put((x + 1) * 0.25f).put((float) (map[x + 1][y + 1] * heightmapExaggeration)).put((y + 1) * 0.25f);
            vBuffer.put((x + 1) * 0.25f).put((float) (map[x + 1][y] * heightmapExaggeration)).put(y * 0.25f);
            vBuffer.put(x * 0.25f).put((float) (map[x][y + 1] * heightmapExaggeration)).put((y + 1) * 0.25f);
        }
    }
    cBuffer.flip();
    vBuffer.flip();
    tBuffer.flip();
    IntBuffer ib = BufferUtils.createIntBuffer(3);

    glGenBuffersARB(ib);
    int vHandle = ib.get(0);
    int cHandle = ib.get(1);
    int tHandle = ib.get(2);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle);
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, vBuffer, GL_STATIC_DRAW_ARB);
    glVertexPointer(3, GL_FLOAT, /* stride */3 << 2, 0L);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, cHandle);
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, cBuffer, GL_STATIC_DRAW_ARB);
    glColorPointer(3, GL_FLOAT, /* stride */3 << 2, 0L);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, tHandle);
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, tBuffer, GL_STATIC_DRAW_ARB);
    glTexCoordPointer(2, GL_FLOAT, /* stride */3 << 2, 0L);

    floor.bind();
    while (!Display.isCloseRequested()) {

        preRender();
        render();

        Display.update();
        Display.sync(60 /* desired fps */);

        // Calc FPS
        frames++;
        if ((System.currentTimeMillis() - time) >= 1000) {
            Display.setTitle(" FPS: " + (int) ((frames * 1000) / (System.currentTimeMillis() - time)));
            time = System.currentTimeMillis();
            frames = 0;
        }
    }
    floor.release();
    glDeleteBuffersARB(ib);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    ib.put(0, vHandle);
    ib.put(1, cHandle);
    Display.destroy();
}

void preRender() {

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    // GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    GLU.gluPerspective(45.0f, ((float) w / (float) h), 0.1f, 100.0f); // fix na błąd z kamerą

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void render() {
    glClearColor(1, 1, 1, 1);

    Camera.acceptInput(0.6f);
    Camera.apply();
    // camera.vector.y = calculateHeight(camera.vector.x*4,
    // camera.vector.z*4)*heightmapExaggeration;

    for (int x = 0; x < Size * Size; x++) {
        glDrawArrays(GL_TRIANGLES, x * 3, 3);
    }
}

public void start() throws Exception {
    NoiseHeightMap nsh = new NoiseHeightMap(500, 24857906);
    nsh.HeightmapPNG(nsh.getHeightmap(), "C:\\Users\\Przemo\\Desktop\\mapka.png");
    map = nsh.getHeightmap();
    initContext();
    renderLoop();
}

public float calculateHeight(float x, float z) {
    float x1, x2, y1, y2, Q11, Q12, Q21, Q22;
    x1 = (int) Math.floor(x);
    x2 = (int) Math.floor(x + 1);
    y1 = (int) Math.floor(z);
    y2 = (int) Math.floor(z + 1);

    Q11 = (float) map[(int) x1][(int) y1];
    Q12 = (float) map[(int) x1][(int) y2];
    Q21 = (float) map[(int) x2][(int) y1];
    Q22 = (float) map[(int) x2][(int) y2];

    return (1f / ((x2 - x1) * (y2 - y1))) * (Q11 * (x2 - x) * (y2 - z) + Q21 * (x - x1) * (y2 - z)
            + Q12 * (x2 - x) * (z - y1) + Q22 * (x - x1) * (z - y1));
}
}
\$\endgroup\$
  • \$\begingroup\$ Why do you have OpenGL 1 in there if you use OpenGL 2 too? Why do you use ARRAY_BUFER_ARBs if those are already supported everywhere and you use OpenGL 2? Why do you use LWJGL 2? \$\endgroup\$ – Bálint Oct 25 '17 at 22:21
  • \$\begingroup\$ I`m using LWJGL2 because LWJGL3 is too hard \$\endgroup\$ – PrzemoVi Oct 25 '17 at 22:54
1
\$\begingroup\$

Let's look at some possible mistakes:

1.)

cBuffer = BufferUtils.createFloatBuffer(9 * (Size * Size * 2));
vBuffer = BufferUtils.createFloatBuffer(9 * (Size * Size * 2));
tBuffer = BufferUtils.createFloatBuffer(9 * (Size * Size * 2));

Why do the color and texture buffers take up the same amount of space as the vertex buffer? There should be (size - 1)^2 * 2 * 3 * 3 spaces for the vertices (amount of squares * triangles per square * vertex per triangle * data per vertex), the same amount of color information (if you use RGB) and (size - 1)^2 * 2 * 2 * 3 * 2 texture coordinates.

2.) You only specify 4 texture coordinates for 6 vertices. Im the nested for loops you define the vertices and colors in 2 batches, one for each triangle, so you put 6 values in the vBuffer and cBuffer, but you only put 4 in the texture buffer. Textures can't render this way.

3.) You mix different versions of OpenGL. You have OpenGL 1.0 in the preRender method and a strange mix of OpenGL 1.0 and 2.0 everywhere else. You should either use OpenGL 2 only or something more modern. Don't mix 1.0 with anything.

4.) You should use shaders. The fixed function pipeline is deprecated and it's even losing support.

5.) You pass a stride of 3 << 2 = 12 for some reason. The values go from the beginning (0), just set these to 0 too.

6.) You render every triangle separately. There's no need for that. Just pass a start position of 0 and a length of (size - 1)^2 * 2 * 3 to the drawArray function.

7.) You only draw size^2 triangles, when there's (size-1)^2*2 of them in total.

8.) You never dispose of the floor texture, you only unbind it

\$\endgroup\$
  • \$\begingroup\$ Wtf, gl1?? Where? \$\endgroup\$ – PrzemoVi Oct 26 '17 at 7:19
  • \$\begingroup\$ And texture has only 4coords, how can I define 6 verticles of texture? \$\endgroup\$ – PrzemoVi Oct 26 '17 at 7:20
  • \$\begingroup\$ @PrzemoVi Your while preRender method uses almost purely gl1. You need to define the texture coord for each vertex, there are 6 vertices -> you need to define 6 texture coords for each square. Please try looking up a tutorial about LWJGL., preferably LWJGL 3 \$\endgroup\$ – Bálint Oct 26 '17 at 7:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.