If you're trying to implement OpenGL within the context of this game, I'd honestly suggest you look at what I did to build a particle system that doesn't use SpriteAPI any more than it has to.
Basically... you use SpriteAPI as an image loader to assign a texture and store it, once only, then do OpenGL work with said texture:
public final SpriteAPI fx_muzzleflash_001 = Global.getSettings().getSprite("fx", "fx_muzzleflash_001");
As Alex just pointed out, using non-power-of-two textures means some adjustments in later code; it's generally better to plan out your textures as power-of-two for ease later on, as otherwise the game has to handle it and you'll have to handle it, too.
Then you use the stored texture to do the drawing, and it's pretty simple, actually.
//OpenGL Start
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for (Map.Entry<Integer, ArrayList<fx_Particle>> entry : fx_SharedLib.particleList.entrySet()) {
int key = entry.getKey();
glBindTexture(GL_TEXTURE_2D, key);
glBegin(GL_QUADS);
for(fx_Particle particle : entry.getValue()){
if (particle.isDead()) continue;
handleParticle(particle);
float size = particle.size.getX() / 2f;
glColor4ub((byte)particle.curColor.getRed(),(byte)particle.curColor.getGreen(),(byte)particle.curColor.getBlue(),(byte)particle.curColor.getAlpha());
glTexCoord2f(0, 1);
Vector2f vec = MathUtils.getPointOnCircumference(particle.position, size, particle.angle + 315f);
glVertex2f(vec.getX(),vec.getY());
glTexCoord2f(0, 0);
vec = MathUtils.getPointOnCircumference(particle.position, size, particle.angle + 225f);
glVertex2f(vec.getX(),vec.getY());
glTexCoord2f(1, 0);
vec = MathUtils.getPointOnCircumference(particle.position, size, particle.angle + 135f);
glVertex2f(vec.getX(),vec.getY());
glTexCoord2f(1, 1);
vec = MathUtils.getPointOnCircumference(particle.position, size, particle.angle + 45f);
glVertex2f(vec.getX(),vec.getY());
}
glEnd();
}
Please read through FX_Plugin and fx_Particle in my FX project to understand how to do that in detail (storing texture ids within a body of data so that you can reduce the number glTexture() calls to a bare minimum is massively important for excellent performance, for example).
But, for a simple ring where you're not worrying about this at all, you could do something like this:
//How round do we want this to be?
int segments = 64;
//We're setting the center of the ring to 0,0 here; obviously, you'll want to adjust that later
Vector2f position = new Vector2f(0f,0f);
//How big is the outer edge?
float outerRing = 256f;
//How big is the inner edge?
float innerRing = 200f;
//OpenGL setup stuff; the only thing that's really important here is the glBlendFunc (in this case, it's "normal", non-additive blending).
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//The value of "key" our texture ID, that we'll use in a second, needs to be assigned. One quick-and-dirty way to do that would be like this:
SpriteAPI myRingSprite= Global.getSettings().getSprite("fx", "fx_RingSprite");
int key = myRingSprite.getTextureId();
//Generally speaking, you only ever want to do any of this ONCE. You shouldn't generally be doing this within renderInWorldCoords().
//But to keep things simple in this example, I've done it this way.
//Now that we have the key value, we can bind it for traditional OpenGL here.
glBindTexture(GL_TEXTURE_2D, key);
//NOTE: If you're going to render multiple rings per frame, and you want this to be efficient, do this part ONLY ONCE. glBindTexture() is expensive!
//Use a HashMap or an ArrayList to store the positions / sizes / colors / blend states / whatever of all your rings and then process them below, essentially.
//If you're going to have some rings that are additive and some that aren't, you'll need to deal with that properly, too.
//The best answer typically is to draw the non-additive stuff first, then the additive stuff. Otherwise, it'll look pretty funky, heh.
//I've only built it this way to make it simpler to understand the code flow.
//Start drawing our quads for this ring.
glBegin(GL_QUADS);
//Draws a quad for each segment of our ring.
//Goes in clock-wise order (it won't work correctly otherwise!)
for(int i=0; i<360; i++360/segments){
//Left-top ring segment quad vertex
glTexCoord2f(0, 1);
Vector2f vec = MathUtils.getPointOnCircumference(position, outerRing, (float) i);
glVertex2f(vec.getX(),vec.getY());
//Right-top ring segment quad vertex
glTexCoord2f(0, 0);
vec = MathUtils.getPointOnCircumference(position, outerRing, (float) i + (float) 360/segments);
glVertex2f(vec.getX(),vec.getY());
//Right-bottom ring segment quad vertex
glTexCoord2f(1, 0);
vec = MathUtils.getPointOnCircumference(position, innerRing, (float) i + (float) 360/segments);
glVertex2f(vec.getX(),vec.getY());
//Left-bottom ring segment quad vertex
glTexCoord2f(1, 1);
vec = MathUtils.getPointOnCircumference(position, innerRing, (float) i);
glVertex2f(vec.getX(),vec.getY());
}
glEnd();
Now... I haven't tested the above, so buyer beware... but it should work. Makes me wonder if I ought to put a ring-renderer into the FX project; it would be pretty easy.