schnelles "drawpixel"



  • Schönen guten Tag!

    Ich habe vor einen interaktiven raytracer zu programmieren(zum rummspielen). Nachdem mich jetzt meine "nicht interaktive" (wie nennt man das? :P) version in java bissl mit den renderzeiten nervt, möchte ich mal was interaktiveres baun.

    was mich ja schon bei java(da gab es auch nen kleinen interaktiven test) beschäftigt hat, war die frage, wie bring ich möglichst schnell die pixel auf die mattscheibe. wie mach ich das am besten mit c++.

    da ich mich fürs fensterbauen und eventing etc für SFML entschieden habe, würde ich gerne dabei bleiben wenns geht.

    mein momentaner aufbau sieht vor, dass ich die pixelchen in ein array packe, mit opengl ein quad male und mit glTexImage2D das array drüberbügle.
    mit dieser vorgehensweise habe ich ca 700fps für eine 512x512 "textur/bildauschnitt/bildgröße" bei nem intel e5300 (wenns 2 varianten gibt dann die neuere) gtx260 (wenn das überhaupt ne rolle spielt, denke mal nicht). größtest problem bei dieser methode ist leider(denk ichmal) das ich nur texturen bauen kann, die 2^x sind .. da sonst alles ziemlich zerstückelt aussieht.

    ich suche einfach nach ner möglichkeit schnell pixel auf die mattscheibe zu toasten. ich denke mal, es wird, der performance zuliebe, wohl meist darauf hinauslaufen, die daten erstmal in ein array zu packen und dann im block zu übergeben..

    impressionen? bin noch ziemlich neu bei opengl (nach längerer pause auch in c++ :P)

    für den interessierten bissl code

    #define WIDTH 512
    #define HEIGHT 512
    
    unsigned char texture[WIDTH][HEIGHT][3];  
    
    void renderTex(float);
    
    float Framerate = 0.0f;
    bool enter = false;
    
    int main()
    {
        // Create the main window
        sf::RenderWindow App(sf::VideoMode(512, 512, 32), "SFML OpenGL");
        //App.PreserveOpenGLStates(true);
    
        // Create a clock for measuring time elapsed
        sf::Clock Clock;
    
        // Set color and depth clear value
        glClearDepth(1.f);
        glClearColor(0.f, 0.f, 0.f, 0.f);
    
        // Enable Z-buffer read and write
    //    glEnable(GL_DEPTH_TEST);
    //    glDepthMask(GL_TRUE);
        glEnable (GL_TEXTURE_2D);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    
        // Setup a perspective projection
    //    glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
    //    gluPerspective(90.f, 1.f, 1.f, 500.f);
    
        // paar pixel bunt machen
        for (int w = 0; w < WIDTH; w++)
        {
            for (int h = 0; h < HEIGHT; h++)
            {
                texture[w][h][0] = 100;
                texture[w][h][1] = 150;
                texture[w][h][2] = 50;
    
                if( (w + h)<255 )
                    texture[w][h][0] = w+h;
                if( (w*h)<255 )
                    texture[w][h][1] = w*h;
                if( (w+h)> 0 && (w*h)/(w+h*20)<255 )
                    texture[w][h][2] = (w*h)/(w+h);
    
            }
        }
    
        // Start game loop
        while (App.IsOpened())
        {
    
            //bissl was zum fps printen
    
            // Process events
            sf::Event Event;
            while (App.GetEvent(Event))
            {
                //.. paar events
            }
    
            renderTex(Clock.GetElapsedTime());
            App.Display();
        }
    
        return EXIT_SUCCESS;
    }
    
    void renderTex(float time)
    {
        glTexImage2D (
            GL_TEXTURE_2D,
            0,
            GL_RGB,
            WIDTH,
            HEIGHT,
            0,
            GL_RGB,
            GL_UNSIGNED_BYTE,
            &texture[0][0][0]
        );
    
        glBegin(GL_QUADS);
            glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0, -1.0);
            glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0, -1.0);
            glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0,  1.0);
            glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0,  1.0);
        glEnd();
    
        glFlush();
    }
    


  • Einige Stichwörter:

    • VBO (Vertex Buffer Object)
    • PBO (Pixel Buffer Object)
    • ggf. VAO (Vertex Array Object)
    • GLSL

    happy google 🙂



  • mhh VBO, VAO für was? für mein gl_quad? nich wirklich oder? oder hab ich da jetzt was falsch von dir verstanden?
    GLSL? ich wollte den raytracer eigentlich nicht als shader programmieren.

    PBO werd ich mal gucken, was es damit auf sich hat in meinem fall ..
    bin nen bissl verwirrt, wie ich das für mein 2D "texturmalen" raytracen verwenden kann.

    mfg



  • lordnaikon schrieb:

    mhh VBO, VAO für was? für mein gl_quad? nich wirklich oder?

    Nein, für ein simples Quad sicherlich nicht. Da wäre es wohl eher überzogen. Ich hab angenommen, dass dies nur ein kurzer Beispielcode sein soll und du final wesentlich mehr Vertices übergibst.



  • das ich nur texturen bauen kann, die 2^x sind ...

    Man nimmt dann einfach eine Textur der Groesse 2^(x+1), kopiert per glTexSubImage2D nur den verwendeten Bereich und passt beim Quad die Texturkoordinaten entsprechend an.

    Oder man nimmt beliebig grosse Texturen und ignoriert die Tatsache dass einige billige Onboard-Grafikloesungen damit nicht umgehen koennen.


Log in to reply