2009-05-25 13 views
10

मैं ओपनजीएल में पॉइंट स्प्राइट्स सेट करने की कोशिश कर रहा था ताकि बिलबोर्ड वाले स्प्राइट के रूप में दूरी के साथ आकार बदल सकें, लेकिन मुझे कुछ भी उपयोगी करने के लिए GL_POINT_DISTANCE_ATTENUATION_ARB में मान नहीं मिल सकते हैं। क्या इस पर मूल्यों का एक सहसंबंध है जो किसी दिए गए प्रक्षेपण से मेल खाता है? क्या मैं भी संभव करने की कोशिश कर रहा हूं?क्या बिलबोर्ड sprites अनुकरण करने के लिए ओपनजीएल बिंदु sprites का उपयोग करना संभव है?

प्रस्तुत कोड इस्तेमाल किया जा रहा:

glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)wglGetProcAddress("glPointParameterfARB"); 
glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)wglGetProcAddress("glPointParameterfvARB"); 

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
glLoadIdentity(); 
gluPerspective(100.0, 800.0/600.0, 0.1, 10.0); 

float quadratic[] = { 5.0f, 0.1f, 10.0f }; 
glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic); 

float maxSize = 0.0f; 
glGetFloatv(GL_POINT_SIZE_MAX_ARB, &maxSize); 
if(maxSize > 100.0f) maxSize = 100.0f; 
glPointSize(maxSize); 

glPointParameterfARB(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 0.1f); 
glPointParameterfARB(GL_POINT_SIZE_MIN_ARB, 0.1f); 
glPointParameterfARB(GL_POINT_SIZE_MAX_ARB, maxSize); 

glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); 

glEnable(GL_POINT_SPRITE_ARB); 

glScalef(0.75,1,1); 
glTranslatef(0.00,0.0,-1.0); 
glScalef(0.5,0.5,0.5); 
glRotatef(counter*0.1+0.5,1.0,1.0,0.0); 

glBegin(GL_POINTS); 

for(int i = 0; i < 100; ++i) 
{ 
    glColor4f(i%10*0.1, i/10*0.1, 0.5, 1.0f); 

    glVertex3f(i%10*0.2-1.0,i/10*0.2-1.0, 
    ((i%10-5)*(i%10-5)+(i/10-5)*(i/10-5))*0.01); 
} 

glEnd(); 

glDisable(GL_POINT_SPRITE_ARB); 

उत्तर

7

यहाँ कैसे मैं बिंदु के आकार को मापने के लिए मेरे गरीब आदमी का दृष्टिकोण बनाने है:

void render() { 
    glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); 
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); 
    glEnable(GL_POINT_SPRITE); 
    glActiveTexture(GL_TEXTURE0); 
    glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); 

    /* Activate shader program here */ 
    /* Send pointSize to shader program */ 

    glBegin(GL_POINTS); 
     /* Render points here */ 
     glVertex3f(...); 
    glEnd(GL_POINTS); 
} 

वर्टेक्स शेडर:

uniform float pointSize; 
void main() { 
    gl_Position = ftransform(); 
    gl_PointSize = pointSize/gl_Position.w; 
} 

आप क्या कर सकते हैं जो कुछ भी आप टुकड़ा शेडर में चाहते हैं, लेकिन आप करेंगे रंग, प्रकाश व्यवस्था और खुद को बनावट की गणना करना है।

1

मेरे अनुभव बिंदु आकार क्षीणन में मुसीबत के लायक नहीं है। आप एक बहुत ही सरल जीएलएसएल वर्टेक्स शेडर लिखने से बहुत बेहतर हैं जो आपके द्वारा किए गए कुछ गणनाओं के अनुसार मैन्युअल रूप से बिंदु आकार सेट करता है। मुझे ऐसा करने के लिए आवश्यक सभी जीएलएसएल को खरोंच से सीखने के लिए लगभग आधा दिन लगा।

GLSL कोड इन कुछ पंक्तियों के रूप में सरल हो सकता है:

attribute float psize; 

void main() 
{ 
    gl_FrontColor = gl_Color; 
    gl_PointSize = psize; 
    gl_Position = ftransform(); 
} 

कहाँ psize बिंदु आकार पैरामीटर उपयोगकर्ता चुनता है।

2

जीएलएसएल एक तरफ, जो आप चाहते हैं वह दूरी क्षीणन के साथ बहुत आसान है। इस बात को देखते हुए कि चीजों का अनुमानित आकार परिप्रेक्ष्य अनुमानों में उनकी दूरी के साथ चौकोर रूप से कैसे घटता है, आपको केवल वर्गबद्ध कारक का उपयोग करने की आवश्यकता है।

यदि आप बिंदु आकार का उपयोग करना चाहते हैं, तो आप आंखों से 150 इकाइयों को मैन्युअल रूप से सेट करते हैं, तो केवल 1/(150^2) को चौकोर कारक के रूप में उपयोग करें (और निरंतर और रैखिक कारकों के लिए शून्य - यदि कुछ भी हो, तो आप शून्य से संभावित डिवीजनों से बचने के लिए निरंतर कारक के लिए 0.01 जैसे कुछ छोटे नंबर का उपयोग करना चाह सकते हैं)।

0

बस pmviewer.sourceforge.net में एक नजर है कोड बिंदु स्प्राइट का उपयोग करके किया जाता है और प्रत्येक बिंदु एक स्वयं के रंग और आकार मात्रा प्रतिपादन अनुकरण करने के लिए है: शिखर शेडर है:

vertexShader

// with ATI hardware, uniform variable MUST be used by output 
    // variables. That's why win_height is used by gl_FrontColor 
    attribute float a_hsml1; 
    uniform float win_height; 
    uniform vec4 cameralocin; 
    void main() 
    { 
    vec4 position=gl_ModelViewMatrix*gl_Vertex; 
    vec4 cameraloc=gl_ModelViewMatrix*cameralocin; 
    float d=distance(vec3(cameraloc),vec3(position)); 
    float a_hsml=gl_Normal.x; 
    float pointSize=win_height*a_hsml/d; // <- point diameter in 
             //pixels (drops like sqrt(1/r^2)) 
    gl_PointSize=pointSize; 
    gl_TexCoord[0]=gl_MultiTexCoord0; 
    gl_Position=ftransform(); 
    gl_FrontColor=vec4(gl_Color.r,gl_Color.g,gl_Color.b,gl_Color.a); 
    } 

pixelShader

uniform sampler2D splatTexture; 
void main() 
{ 
vec4 color = gl_Color * texture2D(splatTexture, gl_TexCoord[0].st); 
gl_FragColor = color;\n" 
} 

बस GPU के कणों भेजने के लिए:

void PutOneArrayToGPU(unsigned int m_vbo, float *hArray, unsigned int num) 
{ 
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); 
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * num, hArray, GL_STATIC_DRAW); 
int size = 0; 
glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); 
if ((unsigned)size != (sizeof(float) *num)) 
    { 
    fprintf(stderr, "WARNING: Pixel Buffer Object allocation failed!\n"); 
    fprintf(stderr, "TurningOff the GPU accelerated rendering\n"); 
    flag_GpuRender=false; 
    } 
return flag_GpuRender; 
} 

फिर उन्हें प्रस्तुत करना:

void DrawPointsByGPU() 
    { 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glBindBuffer(GL_ARRAY_BUFFER, m_vboPos); 
    glVertexPointer(3, GL_FLOAT, 0, 0); 

    glEnableClientState(GL_COLOR_ARRAY); 
    glBindBuffer(GL_ARRAY_BUFFER, m_vboColor); 
    glColorPointer(4, GL_FLOAT, 0, 0); 

    glEnableClientState(GL_NORMAL_ARRAY); 
    glBindBuffer(GL_ARRAY_BUFFER, m_vboHSML); 
    glNormalPointer(GL_FLOAT, 3*sizeof(float), 0); 

    glDrawArrays(GL_POINTS, 0, m_numParticles); 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glDisableClientState(GL_NORMAL_ARRAY); 
    glDisableClientState(GL_COLOR_ARRAY); 
    glDisableClientState(GL_VERTEX_ARRAY); 

    }; 
संबंधित मुद्दे