0

I wrote a little 3D program with VBO, but failed with the textures. Loading them is fine but they just are not displayed. So I wrinte a tiny texture renderer for VBO textures and also took what was in this topic: VBO with texture in LWJGL. But there is still just nothing rendered. Help me just to make this code show a Texture ;)

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;

import java.io.IOException;
import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

public class VBOTextureDemo {

private static Texture texture;

public static void main(String[] args) {
    try {
        Display.setDisplayMode(new DisplayMode(500, 500));
        Display.setTitle("Texture");
        Display.create();
    } catch (LWJGLException e) {
        e.printStackTrace();
        Display.destroy();
        System.exit(1);
    }

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(1, -1, 1, -1, 1, 1);
    glMatrixMode(GL_MODELVIEW);
    glEnable(GL_TEXTURE_2D);
    glLoadIdentity();


    try {
        texture = TextureLoader.getTexture("PNG",
                ResourceLoader.getResourceAsStream("res/images/grass.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }

    final int amountOfVertices = 6;
    final int vertexSize = 3;
    final int texSize = 2;

    FloatBuffer vertexData = BufferUtils.createFloatBuffer(amountOfVertices
            * vertexSize);
    vertexData.put(new float[] { -10f, 10f, 0f, }); // Vertex
    vertexData.put(new float[] { 10f, 10f, 0f, }); // Vertex
    vertexData.put(new float[] { -10f, -10f, 0f, }); // Vertex

    vertexData.put(new float[] { 10f, -10f, 0f, }); // Vertex
    vertexData.put(new float[] { -10f, -10f, 0f, }); // Vertex
    vertexData.put(new float[] { 10f, 10f, 0f, }); // Vertex;
    vertexData.flip();

    FloatBuffer textureData = BufferUtils
            .createFloatBuffer(amountOfVertices * texSize);
    textureData.put(new float[] { 0f, 1f, }); // Texture Coordinate
    textureData.put(new float[] { 1f, 1f, }); // Texture Coordinate
    textureData.put(new float[] { 0f, 0f, }); // Texture Coordinate

    textureData.put(new float[] { 1f, 0f, }); // Texture Coordinate
    textureData.put(new float[] { 0f, 0f, }); // Texture Coordinate
    textureData.put(new float[] { 1f, 1f, }); // Texture Coordinate
    textureData.flip();

    glBindTexture(GL_TEXTURE_2D, texture.getTextureID());

    texture.bind();

    int vboVertexHandle = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
    glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);


    int vboTexCoordHandle = texture.getTextureID();
    glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordHandle);
    glBufferData(GL_ARRAY_BUFFER, textureData, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glClearColor(0.5f, 0.1f, 0f, 1f);



    while (!Display.isCloseRequested()) {
        glClear(GL_COLOR_BUFFER_BIT);

        glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
        glVertexPointer(vertexSize, GL_FLOAT, 0, 0L);

        glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordHandle);
        glTexCoordPointer(2, GL_FLOAT, 0, 0);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glDrawArrays(GL_TRIANGLES, 0, amountOfVertices);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);

        Display.update();
        Display.sync(60);
    }

    glDeleteBuffers(vboVertexHandle);
    glDeleteBuffers(vboTexCoordHandle);
    texture.release();


    Display.destroy();
    System.exit(0);
}

}

Community
  • 1
  • 1
  • I do not see any calls in your code to bind the texture. And since this appears to be the fixed-function pipeline, you also need to enable `GL_TEXTURE_2D` for your bound texture unit. – Andon M. Coleman Sep 14 '13 at 22:15
  • Thanks, i usually had this stuff in it....dunno where it gone ;) #fixed that but it still does not work ): – Theodor Straube Sep 15 '13 at 08:58

1 Answers1

2

I didn't test your code, but there is 2 things I guess that might be bugging!

  1. The vertices are in the wrong order!
  2. The Texture doesn't get loaded, and thereby when calling the bind, nothing gets bound!

Simple Texture Test

Just for testing try using the deprecated methods

  • glBegin(GL_TRIANGLES);
  • glVertex3f(x, y, z);
  • glTexCoord2f(u, v);

Remember to bind the texture of course, but if rendering the triangles using the deprecated methods works, then it's certainly not a texturing problem. Though if nothing appears it might be a texturing program (or the vertices are in the wrong order).

Simple Texture Test Rendering | Code

texture.bind();

glBegin(GL_TRIANGLES);

    glTexCoord2f(0f, 1f);
    glVertex3f(-1f, 1f, 0f);
    glTexCoord2f(1f, 1f);
    glVertex3f(1f, 1f, 0f);
    glTexCoord2f(0f, 0f);
    glVertex3f(-1f, -1f, 0f);

    glTexCoord2f(1f, 0f);
    glVertex3f(1f, -1f, 0f);
    glTexCoord2f(0f, 0f);
    glVertex3f(-1f, -1f, 0f);
    glTexCoord2f(1f, 1f);
    glVertex3f(1f, 1f, 0f);

glEnd();

texture.unbind();

VBO Test

So if the reason it isn't showing is because of the vertices are in the wrong order, then try using the following code, for creating and rendering a Textured VBO.

Creating the VBO | Code

int vertices = 6;

int vertex_size = 3; // X, Y, Z,
int texture_size = 2; // U, V,

FloatBuffer vertex_data = BufferUtils.createFloatBuffer(vertices * vertex_size);
vertex_data.put(new float[] { -1f, 1f, 0f, }); // Vertex
vertex_data.put(new float[] { 1f, 1f, 0f, }); // Vertex
vertex_data.put(new float[] { -1f, -1f, 0f, }); // Vertex

vertex_data.put(new float[] { 1f, -1f, 0f, }); // Vertex
vertex_data.put(new float[] { -1f, -1f, 0f, }); // Vertex
vertex_data.put(new float[] { 1f, 1f, 0f, }); // Vertex

FloatBuffer texture_data = BufferUtils.createFloatBuffer(vertices * texture_size);
texture_data.put(new float[] { 0f, 1f, }); // Texture Coordinate
texture_data.put(new float[] { 1f, 1f, }); // Texture Coordinate
texture_data.put(new float[] { 0f, 0f, }); // Texture Coordinate

texture_data.put(new float[] { 1f, 0f, }); // Texture Coordinate
texture_data.put(new float[] { 0f, 0f, }); // Texture Coordinate
texture_data.put(new float[] { 1f, 1f, }); // Texture Coordinate

vertex_data.flip();
texture_data.flip();

int vbo_vertex_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glBufferData(GL_ARRAY_BUFFER, vertex_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

int vbo_texture_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_texture_handle);
glBufferData(GL_ARRAY_BUFFER, texture_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Rendering the VBO | Code

Also try actually binding and unbinding the texture! That could actually in some weird way be the problem too.

texture.bind();

glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glVertexPointer(vertex_size, GL_FLOAT, 0, 0l);

glBindBuffer(GL_ARRAY_BUFFER, vbo_texture_handle);
glTexCoordPointer(texture_size, GL_FLOAT, 0, 0l);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glDrawArrays(GL_TRIANGLES, 0, vertices); // The vertices is of course the max vertices count, in this case 6

glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, 0);

texture.unbind();

Of course when working with textures, remember to call glEnable(GL_TEXTURE_2D);

Edit

I found the error in the code, you actually say.

int vboTexCoordHandle = texture.getTextureID();
glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordHandle);
glBufferData(GL_ARRAY_BUFFER, textureData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

But you need to say.

int vboTexCoordHandle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordHandle);
glBufferData(GL_ARRAY_BUFFER, textureData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
vallentin
  • 23,478
  • 6
  • 59
  • 81
  • Thanks, I did all that and it just does not work anyway, wtf? – Theodor Straube Sep 16 '13 at 14:02
  • Are you sure that the actual texture gets loaded? – vallentin Sep 16 '13 at 16:01
  • I am never completely sure, but I think, it gets loaded. I added imports to my example, so that you can run it as it is..... – Theodor Straube Sep 16 '13 at 18:59
  • I can't run it as it is, since you use libraries like `slick` which I don't! I've made my own `Texture` class, etc. But try checking the handle/id value of the texture, if the value is something like 0 or -1 then the texture sure doesn't get loaded! – vallentin Sep 19 '13 at 14:44
  • Try to do as I just proposed first! :) – vallentin Sep 19 '13 at 16:38
  • Have you tried calling `glDisable(GL_CULL_FACE);` when you initialize the OpenGL states? – vallentin Sep 21 '13 at 13:45
  • Can anyone get this example to actually render a texture? – Theodor Straube Sep 22 '13 at 14:29
  • Can you render a basic colored triangle or quad without problem? – vallentin Sep 23 '13 at 06:11
  • Yes, just have to add color – Theodor Straube Sep 23 '13 at 13:05
  • Well yes, though I still don't use the `Slick` library. – vallentin Sep 24 '13 at 18:01
  • So, can you give me an example how to render this quad out of triangles with a texture on them which is loaded by another tool? – Theodor Straube Sep 25 '13 at 14:25
  • Here, you can use this to make a custom `Texture` class! http://stackoverflow.com/questions/10801016/lwjgl-textures-and-strings/10872080#10872080 – vallentin Sep 25 '13 at 14:38
  • Mh, seems a bit over-complicated, although, I cant get that to run, because this "MainClass" cant be resolved to a type and im not sure if its meant to be a placholder or not :( – Theodor Straube Oct 07 '13 at 15:46
  • If you don't know 100% how Java works, then you should start by learning it, and wait with OpenGL, because making your own Texture class is the simplest thing! Also you need to make your own matrices like Projection, Model and View Matrix, because you can't use `glMatrixMode`, `glLoadIdentity`, `glTranslate`, `glRotate`, etc. Because they are deprecated, so there you need to create your own Matrix class, and well THAT is complicated. – vallentin Oct 07 '13 at 20:58
  • Couldnt you just explain to me how to get this "simplest" thing running? – Theodor Straube Oct 08 '13 at 18:28
  • Im NOT a professional and yes, I am still learning, many people would say, that its okay to use some code you do not perfectly understand just to get used to it and that the understanding comes with time and practice, which is the actual intention to me to code, even though im sure it will be a bit dirty. So please yust help me to learn something and get it running (: – Theodor Straube Oct 08 '13 at 18:33
  • Understanding comes, by studying and practice, not by time! ;) But, when you say your still learning, then I advice you to take a break from OpenGL and learn Java completely, because if you don't understand the language you're using a 100% then you're going to have a lot more trouble and hard times in the future! Also when you know Java try making some 2D stuff with Graphics2D (Java standard) on a JFrame, when you've mastered that, then try again with OpenGL and I will promise you it will be a lot easier. I'm not saying this to be evil, just trying to help you succeed with programmering! :) – vallentin Oct 08 '13 at 19:20
  • I already did 2D Stuff and lots of basics, please tell me my fault about that texture class ;). Also, at the end of the day, i think, slick is the better way and the bug that it does not map the texture onto the vbos (while it does it for immediate mode) is not caused by the loading of the texture. – Theodor Straube Oct 08 '13 at 19:52
  • "slick is the better way" well no, never, if you want to sell you're game then it's better if you didn't use slick or any other external library, the more external libraries and thing you use, the more license and copyrights you have to check up on. – vallentin Oct 08 '13 at 20:05
  • Ye, we both know, that this wont be a problem for me ;). Would you please finally help me with that MainClass thing? – Theodor Straube Oct 08 '13 at 21:37
  • You're welcome, but could you please accept my answer as the correct one then! Also don't know why I didn't see that in the first place! :) – vallentin Oct 09 '13 at 13:48
  • You're brilliant, awesome answer! This answer definitely deserves more points. I've one more question though, adding things like normals... would it be possible to do this in the same way? – Tim Visée Mar 19 '16 at 14:15
  • 1
    @TimVisée yes you would simply add another buffer, but I wouldn't recommend that, because it gets annoying to have to create a buffer for each element. It's much easier to have a single buffer, and then store x, y, z, r, g, b, nx, ny, nz (and then the next vertex). This isn't what I described in the answer. But check out [this](https://open.gl/drawing), for an example of it. – vallentin Mar 20 '16 at 06:44