0

I'm creating an application that displays OpenGL primitives in the form of triangles but for some reason the application won't actually draw the graphics to the context.

The problem is that the triangles won't change their color from black. I can set the background color to white and see the triangles but I can't change their color despite what I enter.

My main class:

package tests

import scala.collection.mutable.HashMap
import org.lwjgl.util.vector.Vector2f
import zeus.core.Color
import zeus.core.Window
import zeus.core.geom.Polygon
import zeus.core.maths.Delta
import scala.collection.mutable.LinkedHashMap

object DrawingTest {

    def main(args: Array[String]) : Unit = {

        val win: Window = new Window(800, 600, "Drawing Test")
        val deltaObj: Delta = new Delta()

        val info: LinkedHashMap[Vector2f, Color] = new LinkedHashMap[Vector2f, Color]

        info.put(new Vector2f(0f, 0f), new Color(1.0f, 1.0f, 1.0f, 1.0f))
        info.put(new Vector2f(1f, 0f), new Color(1.0f, 1.0f, 1.0f, 1.0f))
        info.put(new Vector2f(1f, 1f), new Color(1.0f, 1.0f, 1.0f, 1.0f))

        info.put(new Vector2f(1f, 1f), new Color(1.0f, 1.0f, 1.0f, 1.0f))
        info.put(new Vector2f(0f, 1f), new Color(1.0f, 1.0f, 1.0f, 1.0f))
        info.put(new Vector2f(0f, 0f), new Color(1.0f, 1.0f, 1.0f, 1.0f))

        win.create()

        val p: Polygon = new Polygon(info)

        while(!win.getIsCloseRequested()) {
            win.clear()
            val delta: Int = deltaObj.getDelta()

            p.update(delta)
            p.draw()

            deltaObj.updateFps(true)
            win.update(120)
        }

        p.dispose();
        win.dispose()

    }

}

My Polygon class:

package zeus.core.geom

import zeus.core.traits.Disposable
import org.lwjgl.util.vector.Vector2f
import zeus.core.Color
import scala.collection.mutable.HashMap
import org.lwjgl.BufferUtils
import java.util.ArrayList
import scala.collection.JavaConversions._
import org.lwjgl.opengl.GL30
import org.lwjgl.opengl.GL20
import org.lwjgl.opengl.GL15
import org.lwjgl.opengl.GL11
import scala.collection.mutable.LinkedHashMap

class Polygon(INFO: LinkedHashMap[Vector2f, Color]) extends Disposable {

    private var colorVbo = 0

    private val colorList: ArrayList[Float] = new ArrayList[Float]
    private val vertiList: ArrayList[Float] = new ArrayList[Float]

    INFO.foreach(i => {
        vertiList.add(i._1.getX)
        vertiList.add(i._1.getY)
        vertiList.add(0f)

        colorList.add(i._2.getRed)
        colorList.add(i._2.getGreen)
        colorList.add(i._2.getBlue)
        colorList.add(i._2.getAlpha)
    })

    /**
     * Vertex Buffer
     */
    private val vertexBuffer: java.nio.FloatBuffer = BufferUtils.createFloatBuffer(vertiList.length);
    vertexBuffer.put({
        var a: Array[Float] = new Array[Float](vertiList.size())
        var i = 0;
        for(f: Float <- vertiList) {
            a(i) = f
            i += 1
        }
        a
    })
    vertexBuffer.flip();

    /**
     * VAO
     */
    private val VAO: Int = GL30.glGenVertexArrays()
    GL30.glBindVertexArray(VAO)

    /**
     * VBO
     */
    private val VBO: Int = GL15.glGenBuffers()
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VBO)
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertexBuffer, GL15.GL_STATIC_DRAW)
    GL20.glEnableVertexAttribArray(0)

    GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0)
    GL30.glBindVertexArray(VAO)

    /**
     * Color VBO
     */
    val colorBuffer: java.nio.FloatBuffer = BufferUtils.createFloatBuffer(colorList.length)
    colorBuffer.put({
        var a: Array[Float] = new Array[Float](colorList.size())
        var i = 0;
        for(f: Float <- colorList) {
            a(i) = f
            i += 1
        }
        a
    })
    colorBuffer.flip()

    colorVbo = GL15.glGenBuffers()
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, colorVbo)
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, colorBuffer, GL15.GL_STATIC_DRAW)
    GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 0, 0)
    GL20.glEnableVertexAttribArray(1)

    def update(delta: Int) : Unit = {

    }

    def draw() : Unit = {
        GL30.glBindVertexArray(VAO)
        GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vertiList.length)
        GL30.glBindVertexArray(0)
    }

    override def dispose() : Unit = {
        println("Destroying polygon with VAO of : " + VAO)

        GL20.glDisableVertexAttribArray(0)

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0)
        GL15.glDeleteBuffers(VBO)

        GL30.glBindVertexArray(0)
        GL30.glDeleteVertexArrays(VAO)

        GL15.glDeleteBuffers(colorVbo)
    }

    def getVAO() : Int = return VAO
    def getVBO() : Int = return VBO
    def getVertexBuffer() : java.nio.FloatBuffer = return vertexBuffer
    def getColorBuffer() : java.nio.FloatBuffer = return colorBuffer

}

Color class:

package zeus.core

class Color(R: Float, G: Float, B: Float, A: Float) {

    private var r: Float = R
    private var g: Float = G
    private var b: Float = B
    private var a: Float = A

    def getRed()    : Float = r
    def getGreen()  : Float = g
    def getBlue()   : Float = b
    def getAlpha()  : Float = a

    def setRed(to: Float)       : Unit = r = to
    def setGreen(to: Float)     : Unit = g = to
    def setBlue(to: Float)      : Unit = b = to
    def setAlpha(to: Float)     : Unit = a = to

    override def toString() : String = "Color[" + r + ", " + g + ", " + b + ", " + a + "]"

}
Liam Potter
  • 1,732
  • 8
  • 24
  • 47

2 Answers2

0

You need to create and bind a program object, that tells OpenGL how to render your data.

This page might help.

Another thing that might cause problems once you have a program set up is that each coordinate in your vertex buffer has two components, but you are specifying in your VAO that it has 3.

bwroga
  • 5,379
  • 2
  • 23
  • 25
  • I don't need to use shaders in this instance. I only wish to color my vertices using a VBO. – Liam Potter Dec 14 '13 at 20:58
  • @user2133268: Yes, you do need to use shaders. `glVertexAttribPointer (...)` is meaningless without shaders (you got very lucky in that attrib pointer **0** is the same thing as `glVertexPointer (...)`, but this does not work portably for any other pointer). If you are not going to use shaders, then go back to `glVertexPointer (...)` and `glColorPointer (...)`. – Andon M. Coleman Dec 14 '13 at 21:53
0

I took the liberty of correcting a few lines of your code since you mentioned you are not using shaders.

Above all, you should not be using glVertexAttribPointer (...) when you are not using shaders. You got very lucky with attrib. pointer 0 is guaranteed to be equivalent to glVertexPointer (...) but this behavior does not work portably for any other attrib pointer. I even answered a question about this yesterday.

private val VBO: Int = GL15.glGenBuffers()
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VBO)
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertexBuffer, GL15.GL_STATIC_DRAW)
GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0)
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY)

GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, colorVbo)
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, colorBuffer, GL15.GL_STATIC_DRAW)
GL11.glColorPointer(3, GL11.GL_FLOAT, 0, 0)
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY)

This ought to work, I am not sure if the GL11 versions for some of the tokens are correct but it should give you the general idea what needs to be done.

Also, you do not need to waste memory using a 3D vertex position if the 3rd coordinate is always 0. OpenGL will interpret an array of 2D vertex positions as: (x, y, 0.0, 1.0). You can save a little bit of memory this way. Make the data 2D and change the size in glVertexPointer (...) to 2.

Community
  • 1
  • 1
Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • When using glVertexPointer and glColorPointer I get errors stating that the functions are not supported. It should be noted that I am using the core profile option on my OpenGL Context. `Exception in thread "main" java.lang.IllegalStateException: Function is not supported at org.lwjgl.BufferChecks.checkFunctionAddress(BufferChecks.java:58) at org.lwjgl.opengl.GL11.glVertexPointer(GL11.java:2679) at zeus.core.geom.Polygon.(Polygon.scala:58) at tests.DrawingTest$.main(DrawingTest.scala:25) at tests.DrawingTest.main(DrawingTest.scala) ` – Liam Potter Dec 14 '13 at 23:45
  • @user2133268: Well, in that case you absolutely have to use shaders. Either use a compatibility profile, or write shaders. – Andon M. Coleman Dec 15 '13 at 00:24
  • That's the thing though. I have another project which uses pretty much the same code excluding the LinkedHashMap to List conversions and it works without Shaders while using the core profile and the same OpenGL version. – Liam Potter Dec 15 '13 at 00:37
  • Implementations are free to support additional features above and beyond what the specification requires, but be aware that using `glVertexAttribPointer (...)` for anything but **0** (vertex position) in the fixed-function pipeline will have undefined results. On NV drivers you can usually get away with using attribute number **3** (you are currently using **1**) for vertex color, but on other drivers the only way you can communicate vertex color in a core profile is to use shaders. If you want to write code that works portably, you need to use shaders and stop relying on undefined behavior. – Andon M. Coleman Dec 15 '13 at 00:48