Advertisement

performance drop when drawing a line in OpenGL

Started by April 22, 2020 05:47 PM
6 comments, last by fleabay 4Β years, 9Β months ago

I tried to draw a simple line in OpenGL, the code below

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();

    gluLookAt(0.0, 50.0f , 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0);

    glBegin(GL_LINES);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(50.0f, 50.0f, 50.0f);
    glEnd();

    //glutWireSphere(20.0f, 20.0f, 20.0f);

    glutSwapBuffers();
    glFlush();
}

However, when I run the program, the performance drop significantly then after a few seconds, it stops responding (I have to run task manager and force quit the program). However, when I disable the line and draw the glutWireSphere (or a polygon), the performance is normal.

Is there a problem with my code? Or perhaps GL_LINES is deprecated?

Windows 10, 1070 MaxQ, Visual Studio

Thank you

It looks like you're making a first contact with OpenGL. Nothing wrong with that !

GL_LINES is among the few things that are not deprecated, though it is used in a different context these days, like draw calls and shader pilelines. If you are not forced to use opengl 1, would you mind learning via https://learnopengl.com/​​ or https://www.opengl-tutorial.org/​​ ?

Or, if you love books, OpenGL Programming Guide 9th and OpenGL Superbible 7th ?

Anyway, if you want us to debug for you, we need more than just a ubiquitious looking function.

Advertisement

Please, do not use legacy/deprecated OpenGL 1. I add two tutorials in the list above: http://ogldev.org/​ and https://thebookofshaders.com/​ You can find a lot of very good books about shaders. I like this one: WebGL Programming Guide

This is my example how to draw one line using shaders, WebGL and TypeScript: click to run in playground

Main.ts


import * as $ from "jquery";
import { mat4 } from "gl-matrix";

$(() =>
{
    // Get WebGL context
    let canvas = document.getElementById("renderCanvas") as HTMLCanvasElement;
    let gl = canvas.getContext("webgl");

    let vShaderSource = [
        "attribute vec3 aPosition;",
        "uniform mat4 uProjMatrix;",
        "void main()",
        "{",
        "    gl_Position = uProjMatrix * vec4(aPosition, 1.0);",
        "}"
    ].join("\n");

    let fShaderSource = [
        "void main()",
        "{",
        "    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);",
        "}"
    ].join("\n");

    let vShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vShader, vShaderSource);
    gl.compileShader(vShader);
    let vMessage = gl.getShaderInfoLog(vShader);
    if (vMessage.length > 0) console.log("Verex Shader Error: " + vMessage);

    let fShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fShader, fShaderSource);
    gl.compileShader(fShader);
    let fMessage = gl.getShaderInfoLog(fShader);
    if (fMessage.length > 0) console.log("Fragment Shader Error: " + fMessage);

    let program = gl.createProgram();
    gl.attachShader(program, vShader);
    gl.attachShader(program, fShader);
    gl.linkProgram(program);
    let progMessage = gl.getProgramInfoLog(program);
    if (progMessage.length > 0) console.log("Failed to link a program: " + progMessage);
    gl.useProgram(program);

    let vertexPositions = [
        0.0, 0.0, 0.0,
        70, 70, 0.0
    ];
    
    let vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositions), gl.STATIC_DRAW);

    let aPositionLocation = gl.getAttribLocation(program, "aPosition");
    if (aPositionLocation < 0) console.log ("Failed to get a aPosition location");
    gl.vertexAttribPointer(aPositionLocation, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(aPositionLocation);

    let aProjMatrixLocation = gl.getUniformLocation(program, "uProjMatrix");
    if (!aProjMatrixLocation) console.log("Failed to get a uProjMatrix location");
    let projMatrix = mat4.ortho(mat4.create(), -100, 100, -100, 100, 10, -10);
    gl.uniformMatrix4fv(aProjMatrixLocation, false, projMatrix);

    gl.clearColor(0.9, 0.9, 0.9, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.LINES, 0, 2);
});

jt.tarigan said:
glutWireSphere(20.0f, 20.0f, 20.0f);

There is no any function in modern OpenGL to draw a sphere using a simple one line command. You need to generate is using triangles or lines. But if you want to create shapes using C++ and simple commands you can use render engines like: Ogre3D, Urho3D, Irrlicht and so on.

See how simple to create a wire sphere using Babylon.js and TypeScript. You can rotate in on Mobile devices by finger. Click to run on Plunker: https://plnkr.co/edit/Pr95JxPPbtRUzjB9?preview

Scene3D.ts


import * as BABYLON from "babylonjs";

export default class Scene3D
{
    private _engine: BABYLON.Engine;
    private _scene: BABYLON.Scene;

    public constructor(canvasName: string)
    {
        const canvas = document.getElementById(canvasName) as HTMLCanvasElement;
        this._engine = new BABYLON.Engine(canvas, true);
        this._scene = new BABYLON.Scene(this._engine);
        const camera = new BABYLON.ArcRotateCamera("camera", -120 * Math.PI / 180, 70 * Math.PI / 180, 5, new BABYLON.Vector3(0, 0, 0), this._scene);
        camera.attachControl(canvas, true);
        camera.wheelPrecision = 100;
        camera.minZ = 0.001;

        new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), this._scene);

        const skybox = BABYLON.MeshBuilder.CreateBox("skybox", { size: 1000 }, this._scene);
        skybox.infiniteDistance = true;
        const skyboxMaterial = new BABYLON.StandardMaterial("skybox", this._scene);
        skyboxMaterial.backFaceCulling = false;
        const files = [
            "https://dl.dropboxusercontent.com/s/d6pb1vco30tb1qd/skybox_px.jpg",
            "https://dl.dropboxusercontent.com/s/j8r319homxctq46/skybox_py.jpg",
            "https://dl.dropboxusercontent.com/s/owtkos3hjayv819/skybox_pz.jpg",
            "https://dl.dropboxusercontent.com/s/fn49xqtrz18h6vn/skybox_nx.jpg",
            "https://dl.dropboxusercontent.com/s/jdtd2cgpe13930o/skybox_ny.jpg",
            "https://dl.dropboxusercontent.com/s/shin4itwifrypl5/skybox_nz.jpg"
        ];
        skyboxMaterial.reflectionTexture = BABYLON.CubeTexture.CreateFromImages(files, this._scene);
        skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
        skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
        skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
        skybox.material = skyboxMaterial;

        let sphere = BABYLON.MeshBuilder.CreateSphere("sphere", { segments: 8, diameter: 2 }, this._scene);
        sphere.material = new BABYLON.StandardMaterial("sphereMat", this._scene);
        sphere.material.wireframe = true;

        this.RunRenderLoop();
    }

    private RunRenderLoop(): void
    {
        this._engine.runRenderLoop(() =>
        {
            this._scene.render();
        });

        window.onresize = () =>
        {
            this._engine.resize();
        };
    }
}

None of the above matters.

The advice to not use legacy OpenGL, while good, is actually completely irrelevant to the OP's problem, and it would be really good if people would stop doing this kind of thing.

There are plenty of programs out there that use legacy OpenGL but don't exhibit the problems encountered by the OP. Using legacy OpenGL is not the cause, and moving to modern OpenGL will not fix it.

There's nothing wrong with the OP's code that could cause this problem. So the cause is probably elsewhere, in other code the OP isn't showing us.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Well yes, OP is keeping basic information to tackle the problem, but IMO it is not good advice to let a newcomer start with legacy OpenGL if there is no real requirement to do so. If they can choose, why not choose the so-called modern style. Core context does not support legacy style any more, there is no advanced debugging, and anyway sooner than later they'd have to learn the modern path anyway, there is no way avoiding it. And there are enough first class resources to start with.

It is all true and right, legacy is not the cause and up to date code will not fix a memory leak or some such, be we other newcomers who only had cursory contact with legacy (e.g. when translating old to new from an example we found) can better cover your professional guy's backs answering questions ;-)

And OP has asked if something is deprecated :-)

Advertisement

Any thread that contains glBegin should automatically belong to the beginners forum.

πŸ™‚πŸ™‚πŸ™‚πŸ™‚πŸ™‚<←The tone posse, ready for action.

This topic is closed to new replies.

Advertisement