Opengl simple quad rendering - opengl

Do you have any idea why this isn't working?
The old immediate mode works but I want to use VAO and VBOs.
(PS: I know the VOA creation should only be created once, but I build it all in this method for the test. I will move thoses lines after testing)
private void allocateIndexBuffer(GL2 graphics, int[] indices) {
int[] id = new int[1];
graphics.glGenBuffers(1, id, 0);
int vboId = id[0];
graphics.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, vboId);
IntBuffer buffer = IntBuffer.allocate(indices.length);
buffer.put(0, indices);
buffer.flip();
graphics.glBufferData(GL2.GL_ELEMENT_ARRAY_BUFFER, indices.length, buffer, GL2.GL_DYNAMIC_DRAW);
//graphics.glDeleteBuffers(vboId, buffer); TODO: clean up when on closing
}
private void allocateAttributeBuffer(GL2 graphics, int attribute, float[] data) {
int[] id = new int[1];
graphics.glGenBuffers(1, id, 0);
int vboId = id[0];
graphics.glBindBuffer(GL2.GL_ARRAY_BUFFER, vboId); //juste remplir vboId ou le remplacer à chaque fois ?
FloatBuffer buffer = FloatBuffer.allocate(data.length);
buffer.put(0, data);
buffer.flip();
graphics.glBufferData(GL2.GL_ARRAY_BUFFER, data.length, buffer, GL2.GL_DYNAMIC_DRAW);
graphics.glVertexAttribPointer(0, 2, GL2.GL_FLOAT, false, 0, 0); //once the buffer is bound
graphics.glEnableVertexAttribArray(0);
graphics.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
//graphics.glDeleteBuffers(vboId, buffer); TODO: clean up when on closing
//graphics.glDeleteVertexArrays(vboId, null); TODO: clean up vaos
}
#Override
protected void draw(GL2 graphics) {
String mode = "new";
if (mode.equals("new")) {
float[] vertices = {
bounds.getX(), bounds.getY(),
bounds.getX(), bounds.getY() + bounds.getHeight(),
bounds.getX() + bounds.getWidth(), bounds.getY() + bounds.getHeight(),
bounds.getX() + bounds.getWidth(), bounds.getY(),
};
int[] indices = { 0, 1, 2, 2, 1, 3 };
//creation vao
int[] id = new int[1];
graphics.glGenVertexArrays(1, id, 0);
int vaoId = id[0];
graphics.glBindVertexArray(vaoId);
allocateIndexBuffer(graphics, indices);
allocateAttributeBuffer(graphics, 0, vertices);
graphics.glBindVertexArray(0);
//render
graphics.glBindVertexArray(vaoId);
graphics.glEnableVertexAttribArray(0);
graphics.glDrawElements(GL2.GL_TRIANGLES, indices.length, GL2.GL_UNSIGNED_INT, 0);
graphics.glDisableVertexAttribArray(0);
graphics.glBindVertexArray(0);
graphics.glFlush();
} else if (mode.equals("old")) {
graphics.glColor3f(255, 0, 0);
graphics.glBegin(GL2.GL_QUADS);
graphics.glVertex2f(bounds.getX(), bounds.getY());
graphics.glVertex2f(bounds.getX() + bounds.getWidth(), bounds.getY());
graphics.glVertex2f(bounds.getX() + bounds.getWidth(), bounds.getY() + bounds.getHeight());
graphics.glVertex2f(bounds.getX(), bounds.getY() + bounds.getHeight());
graphics.glEnd();
}
}

The size of the buffer has to be specified in bytes (see glBufferData);
graphics.glBufferData(GL2.GL_ELEMENT_ARRAY_BUFFER, indices.length, buffer, GL2.GL_DYNAMIC_DRAW);
graphics.glBufferData(GL2.GL_ELEMENT_ARRAY_BUFFER, indices.capacity() * 4,
buffer, GL2.GL_DYNAMIC_DRAW);
graphics.glBufferData(GL2.GL_ARRAY_BUFFER, data.length, buffer, GL2.GL_DYNAMIC_DRAW);
graphics.glBufferData(GL2.GL_ARRAY_BUFFER, data.capacity() * 4,
buffer, GL2.GL_DYNAMIC_DRAW);

Related

OpenGL can not delete buffer

I draw objects with using glBufferData. I want to replace drawing data consecutively. And I want to delete bufferdata and I rewrite new buffer data but I can not do it. Because memory can not being released. And After a few times, I am taking System Out of Memory errors. How can I delete data? GLDeleteBuffer is not running.
My codes are given as below.
public void ReDraw()
{
for (int xx = 0; xx < 500; xx++)
{
this.DeleteBuffers(0)
this.LoadDrawDatas(0, Obje);
this.openGLControl.Invalidate();
}
}
private void DeleteBuffers(int data)
{
if (this.texturesBuffer[data] != null)
{
GL.DeleteBuffers(this.texturesBuffer[data].Length, this.texturesBuffer[data]);
GL.DeleteTextures(1, this.textures[data]);
}
if (this.vertex!= null)
{
GL.DeleteBuffers(this.vertex[data].Length, this.vertex[data]);
GL.DeleteVertexArrays(this.vertex[data].Length, this.vertex[data);
GL.DeleteFramebuffers(this.vertex[data].Length, this.vertex[data]);
GL.DeleteRenderbuffers(this.vertex[data].Length, this.vertex[data]);
}
if (this.normal != null)
{
GL.DeleteBuffers(this.normal[data].Length, this.normal[data]);
GL.DeleteFramebuffers(this.normal[data].Length, this.normal[data]);
GL.DeleteRenderbuffers(this.normal[data].Length, this.normal[data]);
GL.DeleteVertexArrays(this.normal[data].Length, this.normal[data]);
}
}
private void LoadDrawDatas(int data,UcBoyutluNesneBilgisi obje)
{
Rectangle r1 = new Rectangle(0, 0, obje.Texture.Width, obje.Texture.Height);
GL.GenTextures(1, this.textures[data]);
GL.ActiveTexture(TextureUnit.Texture0);
GL.Enable(EnableCap.Texture2D);
GL.BindTexture(TextureTarget.Texture2D, this.textures[data][0]);
System.Drawing.Imaging.BitmapData bitmapData21 = obje.Texture.LockBits(r1, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, obje.Texture.Width, obje.Texture.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, bitmapData21.Scan0);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
obje.Texture.UnlockBits(bitmapData21);
GL.GenBuffers(1, this.texturesBuffer[data]);
GL.BindBuffer(BufferTarget.PixelPackBuffer, this.texturesBuffer[data][0]);
GL.BufferData(BufferTarget.PixelPackBuffer, (IntPtr)(obje.texturesCoord.Count * sizeof(float)), obje.texturesCoord.ToArray(), BufferUsageHint.StreamDraw);
GL.GenBuffers(1, this.normal[data]);
GL.BindBuffer(BufferTarget.PixelPackBuffer, this.normal[data][0]);
GL.BufferData(BufferTarget.PixelPackBuffer, (IntPtr)(obje.Normals.Count * sizeof(float)), obje.Normals.ToArray(), BufferUsageHint.StreamDraw);
GL.GenBuffers(1, this.vertex[data]);
GL.BindBuffer(BufferTarget.PixelPackBuffer, this.vertex[data][0]);
GL.BufferData(BufferTarget.PixelPackBuffer, (IntPtr)(obje.VertexKoordinatlari.Count * sizeof(float)), IntPtr.Zero, BufferUsageHint.StreamDraw);
GL.BufferSubData(BufferTarget.PixelPackBuffer, IntPtr.Zero, (obje.Vertexs.Count * sizeof(float)), obje.VertexsToArray());
GL.GenBuffers(1, this.indeks[data]);
GL.BindBuffer(BufferTarget.PixelPackBuffer, this.indeks[data][0]);
GL.BufferData(BufferTarget.PixelPackBuffer, (IntPtr)this.indexsData[data].Length * sizeof(int)), this.indexsData[data], BufferUsageHint.StreamDraw);
}
private void openGLControl_Paint(object sender, PaintEventArgs e)
{
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.Rotate(X, 1, 0, 0);
GL.Rotate(Y, 0, 1, 0);
GL.Rotate(Z, 0, 0, 1);
GL.Scale(this.zoom* 0.01f, this.zoom * 0.01f, this.zoom * 0.01f);
GL.PushMatrix();
GL.EnableClientState(ArrayCap.NormalArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, normals[0]);
GL.NormalPointer(NormalPointerType.Float, 0, 0);
GL.EnableClientState(ArrayCap.VertexArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertex[0]);
GL.VertexPointer(3, VertexPointerType.Float, 0, IntPtr.Zero);
if (texturesBuffer!= null)
{
GL.EnableClientState(ArrayCap.TextureCoordArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, texturesBuffer[0]);
GL.TexCoordPointer(2, TexCoordPointerType.Float, 0, IntPtr.Zero);
}
GL.BindBuffer(BufferTarget.ElementArrayBuffer, indeks[0]);
GL.DrawElements(PrimitiveType.Triangles, indexsData.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
GL.DisableClientState(ArrayCap.NormalArray);
GL.DisableClientState(ArrayCap.VertexArray);
GL.DisableClientState(ArrayCap.TextureCoordArray);
GL.PopMatrix();
}
You don't need to call glGenBuffers everytime you want to upload data to your VBO (the buffers created by glGenBuffers are called VBOs).
Once your VBOs are created, you can simply overwrite the data using glBufferData. OpenGL will reallocate the memory on the GPU by itself in the background.
Also, for better performance, if your VBOs are the same size from one frame to another, you can use glBufferSubData to update the content of your buffers without suffering the performance penalty of OpenGL reallocating the memory on the GPU

LWJGL texture with shaders produced skewed image

I'm trying to do 2D graphics in orthogonal mode. The code loads a picture of a cat and 2 simple shaders, which just pass through their input, unmodified. I expect the program to display the picture of the cat (or at least a part of it) in the middle of the screen, without any rotation or skew.
The program executes successfully, but I can't figure out why the result looks like this:
An OpenGL guru might spot the problem quickly, but I can't find it. I have the feeling that the problem might be at the "Create buffer for vertex and texture coordinates" part, but everything looked okay.
The cat image:
Vertex shader:
#version 150 core
in vec4 in_Position;
in vec2 in_TextureCoord;
out vec2 pass_TextureCoord;
void main(void) {
gl_Position = in_Position;
pass_TextureCoord = in_TextureCoord;
}
Pixel shader:
#version 150 core
uniform sampler2D texture_diffuse;
in vec2 pass_TextureCoord;
out vec4 out_Color;
void main(void) {
out_Color = texture(texture_diffuse, pass_TextureCoord);
}
Java (LWJGL) code:
package lwjgl_test1;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.*;
import javax.imageio.ImageIO;
import org.lwjgl.*;
import org.lwjgl.opengl.*;
import static org.lwjgl.glfw.GLFW.*;
import java.util.concurrent.TimeUnit;
import static org.lwjgl.opengl.GL11.*;
public class Main {
public static void main(String[] args) {
try {
if (!glfwInit()) {
throw(new Exception("Can't init glfw."));
}
/*
* Create Window
*/
glfwWindowHint(GLFW_RESIZABLE, 0);
long windowGlID = glfwCreateWindow(1024, 768, "Example OpenGL App", 0, 0);
glfwSetWindowPos(windowGlID, 50, 50);
glfwMakeContextCurrent(windowGlID);
glfwShowWindow(windowGlID);
/*
* Initialize OpenGL
*/
GL.createCapabilities();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1024, 768, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
/*
* Load texture
*/
int cat = loadTexture("cat.png");
/*
* Load shaders
*/
int vertexShader = loadShader("vertex_shader.txt", GL20.GL_VERTEX_SHADER);
int pixelShader = loadShader("pixel_shader.txt", GL20.GL_FRAGMENT_SHADER);
int pId = GL20.glCreateProgram();
GL20.glAttachShader(pId, vertexShader);
GL20.glAttachShader(pId, pixelShader);
// Position information will be attribute 0
GL20.glBindAttribLocation(pId, 0, "in_Position");
// Textute information will be attribute 1
GL20.glBindAttribLocation(pId, 1, "in_TextureCoord");
GL20.glLinkProgram(pId);
GL20.glValidateProgram(pId);
exitOnGLError("Compiling shaders failed.");
/*
* Create buffer for vertex and texture coordinates
*/
float size = 120.0f;
FloatBuffer vertex_data = BufferUtils.createFloatBuffer(20);
vertex_data.put(new float[] { -size, -size, 0f, 0f, 0f }); // (Vx, Vy, Vz, Tx, Ty)
vertex_data.put(new float[] { size, -size, 0f, 0f, 1f });
vertex_data.put(new float[] { size, size, 0f, 1f, 1f });
vertex_data.put(new float[] { -size, size, 0f, 1f, 0f });
vertex_data.flip();
int vbo_vertex_handle = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo_vertex_handle);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertex_data, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 2 * 4, 0); // mark vertex coordinates
GL20.glVertexAttribPointer(1, 2, GL11.GL_FLOAT, false, 3 * 4, 3 * 4); // mark texture coordinates
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
exitOnGLError("Creating buffers failed.");
/*
* Main rendering loop
*/
while(true) {
/*
* Clear screen
*/
glClearColor(0.0f, 1.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*
* Apply shader program
*/
GL20.glUseProgram(pId);
// Bind the texture
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, cat);
/*
* Draw (use buffers)
*/
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo_vertex_handle);
GL11.glDrawArrays(GL11.GL_QUADS, 0, 4); // Draw an entity with 4 vertices
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
exitOnGLError("Draw failed.");
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL20.glUseProgram(0); // deselect
/*
* Swap buffers
*/
glfwSwapBuffers(windowGlID);
/*
* Events
*/
glfwPollEvents();
if (glfwWindowShouldClose(windowGlID)) {
break;
}
TimeUnit.MILLISECONDS.sleep(10);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static int loadTexture(String path) throws Exception {
int[] pixels = null;
BufferedImage image = null;
image = ImageIO.read(new FileInputStream(path));
int width = image.getWidth();
int height = image.getHeight();
pixels = new int[width * height];
image.getRGB(0, 0, width, height, pixels, 0, width);
int[] data = new int[width * height];
for (int i = 0; i < width * height; i++) {
int a = (pixels[i] & 0xff000000) >> 24;
int r = (pixels[i] & 0xff0000) >> 16;
int g = (pixels[i] & 0xff00) >> 8;
int b = (pixels[i] & 0xff);
data[i] = a << 24 | b << 16 | g << 8 | r;
}
IntBuffer intBuffer1 = ByteBuffer.allocateDirect(data.length << 2).order(ByteOrder.nativeOrder()).asIntBuffer();
intBuffer1.put(data).flip();
int result = glGenTextures();
glBindTexture(GL_TEXTURE_2D, result);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, intBuffer1);
glBindTexture(GL_TEXTURE_2D, 0);
exitOnGLError("Loading texture '"+ path +"' failed.");
return result;
}
private static int loadShader(String filename, int type) {
StringBuilder shaderSource = new StringBuilder();
int shaderID = 0;
try {
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line;
while ((line = reader.readLine()) != null) {
shaderSource.append(line).append("\n");
}
reader.close();
} catch (IOException e) {
System.err.println("Could not read file.");
e.printStackTrace();
System.exit(-1);
}
shaderID = GL20.glCreateShader(type);
GL20.glShaderSource(shaderID, shaderSource);
GL20.glCompileShader(shaderID);
if (GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.err.println("Could not compile shader.");
System.exit(-1);
}
return shaderID;
}
private static void exitOnGLError(String errorMessage) throws Exception {
int errorValue = GL11.glGetError();
if (errorValue != GL11.GL_NO_ERROR) {
throw new Exception(errorMessage);
}
}
}
The problem lies in the stride parameter in this lines:
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 2 * 4, 0);
GL20.glVertexAttribPointer(1, 2, GL11.GL_FLOAT, false, 3 * 4, 3 * 4);
Stride tells OpenGL how many bytes apart from each other the begin of two consecutive entries are. Since you are using 5 floats per vertex, this has to be 5 * 4 in both lines:
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 5 * 4, 0);
GL20.glVertexAttribPointer(1, 2, GL11.GL_FLOAT, false, 5 * 4, 3 * 4);

What's the meaning of the indirect cmd used in glMultiDrawElementsIndirect

I'm confused about using glMultiDrawElementsIndirect(), could anyone explain to me the meaning of the cmd struct used by that drawing command?
struct cmd:
count = ..
primCount = ..
firstIndex = ..
baseVertex = ..
baseInstance = ..
if I have three different triangle strips to draw, would that be like this?
for (int n = 0; n < 3; n++)
{
count = indexCount;
primCount = 1;
firstIndex = n * count;
baseVertex = 0;
baseInstance = n;
...
}
Setup Buffers:
protected void setupBuffers()
{
gl.glGenVertexArrays(1, vaoBuff);
gl.glBindVertexArray(vaoBuff.get(0));
gl.glGenBuffers(5, vboBuff);
//bind indirect buffer object
gl.glBindBuffer(GL4.GL_DRAW_INDIRECT_BUFFER, vboBuff.get(0));
gl.glBufferData(GL4.GL_DRAW_INDIRECT_BUFFER, instanceCount * 5 * Integer.SIZE / 8, null, GL4.GL_STATIC_DRAW);
gl.glBufferSubData(...);
//bind draw instance ID in the shader with a buffer object
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboBuff.get(1));
gl.glBufferData(GL4.GL_ARRAY_BUFFER, instanceCount * Integer.SIZE / 8, drawIndexBuff, GL4.GL_STATIC_DRAW);
gl.glVertexAttribIPointer(d_idLoc, 1, GL4.GL_UNSIGNED_INT, 0, 0);
gl.glVertexAttribDivisor(d_idLoc, 1);
gl.glEnableVertexAttribArray(d_idLoc);
//bind vertex data buffer object
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboBuff.get(2));
gl.glBufferData(GL4.GL_ARRAY_BUFFER, instanceCount / column_subdivision * vertBuffSize * Float.SIZE / 8, null, GL4.GL_STATIC_DRAW);
gl.glBufferSubData(...);
gl.glVertexAttribPointer(verPosLoc, 3, GL4.GL_FLOAT, false, 0, 0);
gl.glEnableVertexAttribArray(verPosLoc);
//bind vertex index data buffer object
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, vboBuff.get(3));
gl.glBufferData(GL4.GL_ELEMENT_ARRAY_BUFFER, instanceCount / column_subdivision * indexBuffSize * Integer.SIZE / 8, null, GL4.GL_STATIC_DRAW);
gl.glBufferSubData(...);
//bind texture coordinate data buffer object
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboBuff.get(4));
gl.glBufferData(GL4.GL_ARRAY_BUFFER, instanceCount / column_subdivision * texBuffSize * Float.SIZE / 8, null, GL4.GL_STATIC_DRAW);
gl.glBufferSubData(...);
gl.glVertexAttribPointer(tc_inLoc, 2, GL4.GL_FLOAT, false, 0, 0);
gl.glEnableVertexAttribArray(tc_inLoc);
}
drawing command:
gl.glBindVertexArray(vaoBuff.get(0));
glBindBuffer(GL4.GL_DRAW_INDIRECT_BUFFER, vboBuff.get(0));
gl.glMultiDrawElementsIndirect(GL4.GL_TRIANGLE_STRIP, GL4.GL_UNSIGNED_INT, null, 3, 0);
Fixed it, there're some problems within the vertex data. The other is all correct.

Setting up vertex attributes with OpenTK

I am having trouble setting the position, normal, and texture coordinate attributes in my shader. I am using meshomatic to load obj files, here is how the attributes are added to a single vbo:
void LoadBuffers(MeshData m)
{
float[] verts, norms, texcoords;
uint[] indices;
m.OpenGLArrays(out verts, out norms, out texcoords, out indices);
GL.GenBuffers(1, out dataBuffer);
GL.GenBuffers(1, out indexBuffer);
// Set up data for VBO.
// We're going to use one VBO for all geometry, and stick it in
// in (VVVVNNNNCCCC) order. Non interleaved.
int buffersize = (verts.Length + norms.Length + texcoords.Length);
float[] bufferdata = new float[buffersize];
vertOffset = 0;
normOffset = verts.Length;
texcoordOffset = (verts.Length + norms.Length);
verts.CopyTo(bufferdata, vertOffset);
norms.CopyTo(bufferdata, normOffset);
texcoords.CopyTo(bufferdata, texcoordOffset);
bool v = false;
for (int i = texcoordOffset; i < bufferdata.Length; i++)
{
if (v)
{
bufferdata[i] = 1 - bufferdata[i];
v = false;
}
else
{
v = true;
}
}
// Load geometry data
GL.BindBuffer(BufferTarget.ArrayBuffer, dataBuffer);
GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(buffersize * sizeof(float)), bufferdata,
BufferUsageHint.StaticDraw);
// Load index data
GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer);
GL.BufferData<uint>(BufferTarget.ElementArrayBuffer,
(IntPtr)(indices.Length * sizeof(uint)), indices, BufferUsageHint.StaticDraw);
}
And here is how I am drawing:
void DrawBuffer()
{
// Push current Array Buffer state so we can restore it later
GL.PushClientAttrib(ClientAttribMask.ClientVertexArrayBit);
GL.ClientActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, diff);
GL.EnableVertexAttribArray(positionIndex);
GL.BindBuffer(BufferTarget.ArrayBuffer, dataBuffer);
GL.VertexAttribPointer(positionIndex, 3, VertexAttribPointerType.Float, false, 0, vertOffset);
GL.EnableVertexAttribArray(texcoordIndex);
GL.BindBuffer(BufferTarget.ArrayBuffer, dataBuffer);
GL.VertexAttribPointer(texcoordIndex, 2, VertexAttribPointerType.Float, false, 0, texcoordOffset);
GL.EnableVertexAttribArray(normalIndex);
GL.BindBuffer(BufferTarget.ArrayBuffer, dataBuffer);
GL.VertexAttribPointer(normalIndex, 3, VertexAttribPointerType.Float, false, 0, normOffset);
// Index array
GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer);
GL.DrawElements(PrimitiveType.Triangles, m.Tris.Length * 3, DrawElementsType.UnsignedInt, IntPtr.Zero);
// Restore the state
GL.PopClientAttrib();
}
However my texture coordinates are wrong. It seems that only a single pixel from my texture is used to cover the entire obj. I think I am using GL.VertexAttribPointer(...) incorrectly. What is the second arg int "size"?

glDrawElements Fails to draw

I'm working on what will eventually be a terrain drawer, however at the moment I am just trying to get a basic pair of triangles to draw with glDrawElements. The code looks as such:
public class TerrainFlat extends AbstractTerrain {
IntBuffer ib = BufferUtils.createIntBuffer(3);
int vHandle = ib.get(0);
int cHandle = ib.get(1);
int iHandle = ib.get(2);
FloatBuffer vBuffer = BufferUtils.createFloatBuffer(19);
FloatBuffer cBuffer = BufferUtils.createFloatBuffer(18);
ShortBuffer iBuffer = BufferUtils.createShortBuffer(6);
#Override
public void initilize(){
float[] vertexData = {50, 20, 100, 50, -20, 100, 10, -20, 100, -10, -20, 100, -50, -20, 100, -50, 20, 100};
float[] colorData = {1, 0, 0, 0, 1, 0, 0, 0, 1, 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 0 };
short[] indexData = {0,1,2,3,4,5};
vBuffer.put(vertexData);
vBuffer.flip();
cBuffer.put(colorData);
cBuffer.flip();
iBuffer.put(indexData);
iBuffer.flip();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iHandle);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, vBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cHandle);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, cBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
#Override
public void setUp(float posX, float posY, float posZ){
}
#Override
public void draw(){
glClear(GL_COLOR_BUFFER_BIT);
glGenBuffersARB(ib);
vHandle = ib.get(0);
cHandle = ib.get(1);
iHandle = ib.get(2);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle);
glVertexPointer(3, GL_FLOAT, 3 << 2 , 0L);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cHandle);
glColorPointer(3, GL_FLOAT, 3 << 2 , 0L);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iHandle);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0L);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
#Override
public void destroy(){
ib.put(0, vHandle);
ib.put(1, cHandle);
ib.put(2, iHandle);
glDeleteBuffersARB(ib);
}
}
This does not draw anything, the screen is entirely black. GL_CULL_FACE is not enabled, and there is no lighting (or lack thereof) to cause this error. Moving the data binding into the Draw() function lets it work (if you want I can add that code to this). This however means I create my buffer's every draw function (ie: bad). I'm wondering outright what I'm doing wrong here, because I've moved it around and slapped it silly for 4 days now.
You're setting vHandle, cHandle and iHandle to 0.
You never need to create the IntBuffer in line 1 anyway. Replace
int vHandle = ib.get(0);
int cHandle = ib.get(1);
int iHandle = ib.get(2);
with
int vHandle = glGenBuffers();
int cHandle = glGenBuffers();
int iHandle = glGenBuffers();