Question

J'ai commencé à jouer avec OpenGL et GLUT. Je voudrais tirer quelques points, mais le problème est qu'ils se révèlent être des places, et je les aime à être des points ronds (cercles pleins).

Voici ce que je fais:

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

Ceci est le résultat: Résultat du code ci-dessus

Les points où apparaissent attendu, que leur forme ne va pas.

Était-ce utile?

La solution

Contrairement à ce qui a été dit précédemment, cela est possible avec la conduite à fonction fixe, même avec le GL_POINTS type primitif, aussi longtemps que vous avez le support d'OpenGL 1.4 ou l'extension GL_ARB_point_sprite. Consultez ce document, ou la spécification de base OpenGL de votre choix: http: // www .opengl.org / registre / spécifications / ARB / point_sprite.txt

GL_ARB_point_sprite convertit les points en « quad », i.e. un polygone ayant la forme d'un avion. Le type primitif exact où elle est convertie en est pas défini par la spécification, mais il n'a pas d'importance. Ce qui est important est que l'auto-génère GL_COORD_REPLACE coordonnées de texture pour la surface lorsqu'elle est activée, vous pouvez-carte texture avec une texture RGBA en forme de sphère.

EDIT:. Il semble que vous (l'affiche) est droite Points anticrénelage se arrondi par rapport à leur rayon. (Je l'ai utilisé OpenGL depuis 2003, et je ne savais pas. [/ Honte]) Permettant ainsi GL_POINT_SMOOTH si vous avez un multisample-able visuel / pixelformat, vous obtenez des points arrondis. Pourtant, MultiSampling peut être lent, donc je mettre en œuvre à la fois. quadriceps texturés ne coûtent pas cher.

Pour obtenir un visuel avec multiéchantillonnage avec XLib , utiliser ces deux attributs dans la liste à glXChooseFBConfig ():

GLX_SAMPLE_BUFFERS - sa valeur doit être True. Ceci est une bascule on / off.
GLX_SAMPLES -. le nombre d'échantillons

Pour demander une pixelformat avec Win32 , utiliser ces deux attributs dans la liste à ChoosePixelFormat () ou wglChoosePixelFormatARB ():

WGL_SAMPLE_BUFFERS_ARB comme ci-dessus, une bascule.
WGL_SAMPLES_ARB comme ci-dessus, le nombre d'échantillons.

Il semble que vous pouvez ou dans le GLUT_MULTISAMPLE de drapeau glutInitDisplayMode pour obtenir multiéchantillonnage dans GLUT , mais vous ne pouvez pas demander le nombre de tampons d'échantillons.

Voici comment alpha-quadriceps mélangés pourraient être mises en œuvre en utilisant votre cas de test.

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

Image de points arrondis à l'aide de mélange alpha par fragment + textures:
(source: mechcore.net )
Image de points arrondis à l'aide GL_POINT_SMOOTH et multiéchantillonnage:
(source: mechcore.net )
Un petit échantillon que je fait qui montre à la fois techniques. LibSDL et nécessite libGLEW à compilent:

#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();
}

Autres conseils

La réponse de Mads fournit tout ce dont vous avez besoin si vous allez pour le pipeline de fonction fixe. Toutefois, si vous avez un système qui ne fournit pas l'extension de ARB_point_sprite ou avec une mise en œuvre brisée (certains pilotes ATI), vous pouvez résoudre cette partie aussi avec les shaders de géométrie. ARB_geometry_shader4  extension vous permet de convertir un point primitif à deux triangles, qui peuvent être utilisés comme le quad créé par l'extension ARB_point_sprite. OpenGL 3.2, shaders de géométrie sont déjà pris en charge dans le noyau, aucune extension nécessaire. Le wiki OpenGL a deux exemples .

Pas possible avec une fonction opengl fixe. Les points sont toujours carrés:)

Vous devez dessiner votre propre cercle (en le construisant comme un gâteau, morceau par morceau) ou dessiner une GL_QUAD avec une texture « cercle » sur.

Cordialement, andre

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top