Frage

begann ich mit OpenGL und GLUT herum spielen. Ich möchte einige Punkte zeichnen, aber das Problem ist, dass sie sich als Quadrate sein, und ich möchte sie runde Punkte (gefüllte Kreise) sein.

Das ist, was ich tue:

void onInitialization( ) 
{ 
    glEnable( GL_POINT_SMOOTH );
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glPointSize( 6.0 );
}    

void onDisplay()
{
    glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glBegin( GL_POINTS );
        glColor3f( 0.95f, 0.207, 0.031f );
    for ( int i = 0; i < g_numPoints; ++i )
    {
        glVertex2f( g_points[i].X, g_points[i].Y );
    }
    glEnd();
    glFinish();
    glutSwapBuffers();
}

Dies ist das Ergebnis: Ergebnis des obigen Code

Die Punkte zeigen, wo zu erwarten, nur ihre Form ist falsch.

War es hilfreich?

Lösung

Im Gegensatz zu, was vorher gesagt wurde, ist dies mit der Fixed-Function-Pipeline, auch mit dem GL_POINTS Urtyp, solange Sie Unterstützung haben für OpenGL 1.4 oder die GL_ARB_point_sprite Erweiterung. Wenden Sie dieses Dokument oder die OpenGL-Kernspezifikation Ihrer Wahl: http: // www .opengl.org / Registry / specs / ARB / point_sprite.txt

GL_ARB_point_sprite wandelt Punkte in „Quads“, d.h ein Polygon mit der Form einer Ebene. Der genaue Urtyp es umgewandelt wird, um nicht durch die Spezifikation definiert, obwohl es nicht wichtig ist. Was wichtig ist, ist, dass GL_COORD_REPLACE generiert automatisch Texturkoordinaten für die Oberfläche, wenn aktiviert, so dass Sie sie mit einer Kugel förmigen RGBA-Textur Textur-Karte können.

EDIT:. Es scheint, wie Sie (das Plakat) richtig ist Anti-Aliasing Punkte in Bezug auf ihren Radius abgerundet. (Ich habe seit 2003 OpenGL verwendet, und ich habe das nicht wissen. [/ Scham]) So ermöglicht GL_POINT_SMOOTH, während Sie ein multisample-able visuelle / Pixelformat haben, erhalten Sie abgerundete Punkte. Dennoch kann das Multisampling langsam sein, so dass ich beide implementieren würde. Texturierten Quads sind billig.

ein visuellen Zur Anforderung mit Multisampling mit XLib , verwenden Sie diese beiden Attribute in der Liste glXChooseFBConfig ():

GLX_SAMPLE_BUFFERS - sollte sein Wert True sein. Dies ist ein Ein- / Aus-Schalter.
GLX_SAMPLES -. die Anzahl der Proben

ein Pixelformat mit Win32 So fordern , verwenden Sie diese beiden Attribute in der Liste ChoosePixelFormat () oder wglChoosePixelFormatARB ():

WGL_SAMPLE_BUFFERS_ARB Wie oben, ein Schalter.
WGL_SAMPLES_ARB Wie oben, die Anzahl der Proben.

Es scheint, dass Sie können oder in der Flagge GLUT_MULTISAMPLE zu glutInitDisplayMode in GLUT Multisampling erhalten , aber Sie können verlangen, nicht die Anzahl der Probenpuffer.

Hier ist, wie alpha-blended Quads umgesetzt werden könnte Ihren Testfall verwendet wird.

void onInitialization( ) 
{
    glEnable( GL_POINT_SPRITE ); // GL_POINT_SPRITE_ARB if you're
                                 // using the functionality as an extension.

    glEnable( GL_POINT_SMOOTH );
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glPointSize( 6.0 );

    /* assuming you have setup a 32-bit RGBA texture with a legal name */
    glActiveTexture(GL_TEXTURE0);
    glEnable( GL_TEXTURE_2D );
    glTexEnv(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
    glTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glBindTexture(GL_TEXTURE_2D, texture_name);
}    

void onDisplay()
{
    glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glBegin( GL_POINTS );
        glColor4f( 0.95f, 0.207, 0.031f, 1.0f );
    for ( int i = 0; i < g_numPoints; ++i )
    {
        glVertex2f( g_points[i].X, g_points[i].Y );
    }
    glEnd();
    glFinish();
    glutSwapBuffers();
}

Bild von gerundeten Punkten pro-Fragment Alpha-Blending + Texturen:
(Quelle: mechcore.net )
Foto von abgerundeten Spitzen von GL_POINT_SMOOTH mit und Multisampling:
(Quelle: mechcore.net )
Eine kleine Probe habe ich die beide Techniken zeigt. Benötigt libSDL und libGLEW zu kompilieren:

#include <iostream>
#include <exception>
#include <memory>
#include <SDL/SDL.h> 
#include <cmath>
#include <GL/glew.h>
#include <GL/glu.h>

#define ENABLE_TEXTURE
#define ENABLE_MULTISAMPLE

int Width = 800;
int Height = 600;

void Draw(void);
void Init(void);

inline float maxf(float a, float b)
{
    if(a < b)
        return b;
    return a;
}

inline float minf(float a, float b)
{
    if(a > b)
        return b;
    return a;
}

GLuint texture_name;

int main(void)
{
    try {
        SDL_Init(SDL_INIT_VIDEO);
        SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
        #ifdef ENABLE_MULTISAMPLE
            SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
            SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
        #endif
        SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
        SDL_SetVideoMode(Width, Height, 32, SDL_OPENGL);

        glewInit();
        Init();

        SDL_Event event;
        bool running = true;

        while(running){
            while(SDL_PollEvent(&event)){
                switch(event.type)
                {
                    case SDL_KEYDOWN:
                        if(event.key.keysym.sym == SDLK_ESCAPE)
                            running = false;
                    break;
                    case SDL_QUIT:
                        running = false;
                    break;
                }
            }
            Draw();
            SDL_GL_SwapBuffers();
        }
        SDL_Quit();
    }
    catch(std::bad_alloc& e)
    {
        std::cout << "Out of memory. " << e.what() << std::endl;
        exit(-1);
    }
    catch(std::exception& e)
    {
        std::cout << "Runtime exception: " << e.what() << std::endl;
        exit(-1);
    }
    catch(...)
    {
        std::cout << "Runtime exception of unknown type." << std::endl;
        exit(-1);
    }
    return 0;
}

void Init(void)
{
    const GLint texWidth = 256;
    const GLint texHeight = 256;
    const float texHalfWidth = 128.0f;
    const float texHalfHeight = 128.0f;
    printf("INIT: \n");

    unsigned char* pData = new unsigned char[texWidth*texHeight*4];
    for(int y=0; y<texHeight; ++y){
        for(int x=0; x<texWidth; ++x){
            int offs = (x + y*texWidth) * 4;
            float xoffs = ((float)x - texHalfWidth) / texHalfWidth;
            float yoffs = ((float)y - texHalfWidth) / texHalfHeight;
            float alpha = 1.0f - std::sqrt(xoffs*xoffs + yoffs*yoffs);
            if(alpha < 0.0f)
                alpha = 0.0f;
            pData[offs + 0] = 255; //r
            pData[offs + 1] = 0; //g
            pData[offs + 2] = 0; //b
            pData[offs + 3] = 255.0f * alpha; // * 
            //printf("alpha: %f\n", pData[x + y*texWidth + 3]);
        }
    }

    #ifdef ENABLE_TEXTURE
    glGenTextures(1, &texture_name);
    glActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture_name);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pData);
    glEnable(GL_POINT_SPRITE);
    glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    #endif

    glPointSize(32.0f);

    glMatrixMode(GL_PROJECTION);
    glOrtho(0, Width, 0, Height, -1.0f, 1.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_DEPTH_TEST);

    #ifdef ENABLE_MULTISAMPLE
        glEnable(GL_POINT_SMOOTH);
    #endif

    GLenum e;
    do{
        e = glGetError();
        printf("%s\n",gluErrorString(e));
    } while(e != GL_NO_ERROR);

    delete [] pData;
}

void Draw(void)
{
    const int gridWidth = 1024;
    const int gridHeight = 1024;
    float t1, t2;

    t1 = t2 = (float)SDL_GetTicks() * 0.001f;
    t1 = fmod(t1, 10.0f) / 10.0f;
    t2 = fmod(t2, 4.0f) / 4.0f;
    float scale = 0.5f + (-sin(t2 * 2.0 * M_PI) + 1.0f) * 1.2f;
    //glColor4f(0.4f, 0.5f, 0.9f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();

    glTranslatef((Width>>1), (Height>>1), 0.0f);
    glScalef(scale,scale,scale);
    glRotatef(t1 * 360.0f, 0.0f, 0.0f, 1.0f);

    glBegin(GL_POINTS);
    for(int j=0; j<gridHeight; j+=64){
        for(int i=0; i<gridWidth; i+=64){ 
            glVertex2i(i-(gridWidth>>1),j-(gridHeight>>1));
        }
    }
    glEnd();
}

Andere Tipps

Mads' Antwort liefert alles, was Sie brauchen, wenn Sie für die feste Funktion Pipeline gehen. Wenn Sie jedoch ein System, das nicht die ARB_point_sprite Erweiterung bereitstellt oder mit einem gebrochenen Implementierung (einige ATI-Treiber), können Sie diesen Teil auch mit Geometry-Shader lösen. Die ARB_geometry_shader4  Erweiterung ermöglicht es Ihnen, einen Punkt primitiv zu zwei Dreiecken zu konvertieren, die als Quad durch die ARB_point_sprite Erweiterung erstellt verwendet werden können. Auf OpenGL 3.2, Geometrie-Shader sind bereits im Kern unterstützt wird, benötigt keine Verlängerung. Die OpenGL-Wiki hat zwei Beispiele .

Nicht möglich mit einer festen opengl Funktion. Punkte sind immer quadratisch:)

Sie haben einen eigenen Kreis zeichnen (indem Sie es wie ein Kuchen, Stück für Stück bauen) oder ein GL_QUAD mit einer „Kreis“ Textur ziehen auf.

Mit freundlichen Grüßen, andre

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top