के विपरीत क्या पहले कहा गया था, यह निश्चित समारोह पाइप लाइन के साथ संभव है andre, यहां तक कि GL_POINTS
आदिम प्रकार के साथ, जब तक आप ओपन 1.4 या GL_ARB_point_sprite
विस्तार के लिए समर्थन के रूप में। इस दस्तावेज़, या अपनी पसंद के ओपनजीएल कोर विनिर्देश से परामर्श लें: http://www.opengl.org/registry/specs/ARB/point_sprite.txt
GL_ARB_point_sprite
बिंदुओं को "quads" में परिवर्तित करता है, यानी एक विमान के रूप में एक बहुभुज। सटीक आदिम प्रकार को परिवर्तित करने के लिए इसे विनिर्देशन द्वारा परिभाषित नहीं किया जाता है, हालांकि यह महत्वपूर्ण नहीं है। महत्वपूर्ण यह है कि GL_COORD_REPLACE
सक्षम होने पर सतह के लिए बनावट निर्देशांक स्वत: जेनरेट करता है, ताकि आप उन्हें गोलाकार आकार वाले आरजीबीए-बनावट के साथ बनावट बना सकें।
संपादित करें: ऐसा लगता है जैसे आप (पोस्टर) सही है। एंटी-एलाइज्ड अंक अपने त्रिज्या के संबंध में गोल हो जाते हैं। (मैंने 2003 से ओपनजीएल का उपयोग किया है, और मुझे यह नहीं पता था। [/ शर्मनाक]) तो GL_POINT_SMOOTH
को सक्षम करते हुए आपके पास multisample-able
विज़ुअल/पिक्सेलफॉर्मेट है, तो आपको गोल अंक मिलते हैं। फिर भी, बहुआयामी धीमा हो सकता है, इसलिए मैं दोनों को लागू करता हूं। बनावट quads सस्ते हैं।
Xlib साथ multisampling के साथ एक दृश्य के अनुरोध के लिए glXChooseFBConfig() के लिए सूची में इन दोनों विशेषताओं का उपयोग:
GLX_SAMPLE_BUFFERS
- अपने मूल्य True
होना चाहिए। यह एक चालू/बंद टॉगल है।
GLX_SAMPLES
- नमूने की संख्या।
Win32 के साथ एक pixelformat के अनुरोध के लिए ChoosePixelFormat() या wglChoosePixelFormatARB (करने के लिए सूची में इन दो विशेषताओं का उपयोग):
WGL_SAMPLE_BUFFERS_ARB
, उपरोक्त के समान एक टॉगल।
WGL_SAMPLES_ARB
उपरोक्त के समान, नमूने की संख्या।
यह प्रतीत आप कर सकते हैं कि या झंडा GLUT_MULTISAMPLE
glutInitDisplayMode
को भरमार में multisampling प्राप्त करने के लिए, लेकिन आप नमूना बफ़र्स की संख्या का अनुरोध नहीं कर सकते हैं।
यहां बताया गया है कि आपके परीक्षण मामले का उपयोग करके अल्फा-मिश्रित क्वाड कैसे कार्यान्वित किए जा सकते हैं।
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();
}
प्रति-टुकड़ा अल्फा सम्मिश्रण + बनावट का उपयोग कर गोल अंकों की छवि: GL_POINT_SMOOTH
और multisampling का उपयोग करके गोल अंकों की http://www.mechcore.net/images/gfx/sprite0.png
छवि: http://www.mechcore.net/images/gfx/sprite1.png
एक छोटी सी नमूना है जो दोनों तकनीक से पता चलता मैं बना दिया। libSDL और libGLEW संकलित करने के लिए आवश्यक है:
#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();
}
आपने उल्लेख नहीं किया कि आपका लक्षित प्लेटफ़ॉर्म क्या है। कुछ ओपनजीएल विशेषताएं (जैसे GL_POINT_SMOOTH) व्यापक रूप से समर्थित नहीं हैं। यदि आप उपभोक्ता-ग्रेड वीडियो कार्ड पर व्यापक रूप से चलाने के लिए अपने आवेदन का इरादा रखते हैं, तो अपने आप को विदेशी एक्सटेंशन में प्रतिबद्ध करने से पहले परीक्षण करना सुनिश्चित करें। भले ही यह काम प्रतीत होता है, प्रदर्शन की जांच करें। यह आपको सॉफ्टवेयर मोड में छोड़ सकता है। – Alan
नहीं, लेकिन मैंने उल्लेख किया कि मैंने ओपनग्ल के साथ खेलना शुरू किया, एक शौक की तरह;) –
यदि आप बस अपने कोड को अपने कंप्यूटर पर चलाने के लिए चाहते हैं तो हर तरह से, अपने कंप्यूटर पर जो कुछ भी काम करता है। लेकिन यह समझना भी मूल्यवान है कि ओपनजीएल का एक बड़ा नुकसान यह है कि spec के बड़े हिस्से किसी दिए गए प्लेटफॉर्म पर सही तरीके से काम नहीं करेंगे। वास्तव में ये कौन सा हिस्सा एक बहुत ही खराब दस्तावेज रहस्य है। सॉफ़्टवेयर-मोड फ़ॉलबैक असमर्थित सुविधाओं को अस्पष्ट कर देगा। – Alan