【问题标题】:OpenGL 3.2 Triangles Not DrawingOpenGL 3.2 不绘制三角形
【发布时间】:2013-12-14 17:16:01
【问题描述】:

我正在创建一个以三角形形式显示 OpenGL 基元的应用程序,但由于某种原因,该应用程序实际上不会将图形绘制到上下文中。

问题是三角形不会从黑色改变颜色。我可以将背景颜色设置为白色并看到三角形,但我无法更改它们的颜色,尽管我输入了。

我的主要课程:

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()

    }

}

我的多边形类:

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

}

颜色类:

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 + "]"

}

【问题讨论】:

    标签: scala graphics vbo opengl-3 vao


    【解决方案1】:

    你需要创建和绑定一个程序对象,它告诉 OpenGL 如何渲染你的数据。

    This page 可能会有所帮助。

    一旦您设置了程序,可能会导致问题的另一件事是顶点缓冲区中的每个坐标都有两个分量,但您在 VAO 中指定它有 3 个分量。

    【讨论】:

    • 在这种情况下我不需要使用着色器。我只希望使用 VBO 为我的顶点着色。
    • @user2133268:是的,您确实需要使用着色器。 glVertexAttribPointer (...) 在没有着色器的情况下毫无意义(你很幸运,因为属性指针 0glVertexPointer (...) 相同,但这对于任何其他指针都不起作用)。如果您不打算使用着色器,请返回 glVertexPointer (...)glColorPointer (...)
    【解决方案2】:

    由于您提到您没有使用着色器,因此我冒昧地更正了您的几行代码。

    最重要的是,当您不使用着色器时,您不应该使用glVertexAttribPointer (...)。你对attrib非常幸运。指针 0 保证等同于 glVertexPointer (...) 但此行为不适用于任何其他属性指针。昨天我什至answered a question about this

    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)
    

    应该可以工作,我不确定某些令牌的GL11 版本是否正确,但它应该让您大致了解需要做什么完成。

    此外,如果第 3 个坐标始终为 0,则无需使用 3D 顶点位置浪费内存。 OpenGL 会将二维顶点位置数组解释为:(x, y, 0.0, 1.0)。这样可以节省一点内存。将数据设为 2D 并将 glVertexPointer (...) 中的大小更改为 2

    【讨论】:

    • 使用 glVertexPointer 和 glColorPointer 时出现错误,指出不支持这些功能。应该注意的是,我在我的 OpenGL 上下文中使用了核心配置文件选项。 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.&lt;init&gt;(Polygon.scala:58) at tests.DrawingTest$.main(DrawingTest.scala:25) at tests.DrawingTest.main(DrawingTest.scala)
    • @user2133268:好吧,在这种情况下,您绝对必须使用着色器。要么使用兼容性配置文件,要么编写着色器。
    • 就是这样。我有另一个项目,它使用几乎相同的代码,不包括 LinkedHashMap 到列表的转换,它在使用核心配置文件和相同的 OpenGL 版本时无需着色器即可工作。
    • 实现可以免费支持超出规范要求的其他功能,但请注意,除了 0(顶点位置)之外的任何内容都使用glVertexAttribPointer (...) -函数管道将有未定义的结果。在 NV 驱动程序上,您通常可以使用属性编号 3(您当前使用 1)作为顶点颜色,但在其他驱动程序上,您可以传达顶点颜色的唯一方法在核心配置文件中是使用着色器。如果您想编写可移植的代码,您需要使用着色器并停止依赖未定义的行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 2015-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多