Building a simple 2D graphics library in SDL
You are not reinventing the wheel.
Sir, e^iπ + 1 = 0, hence God exists; reply!
unknown Wrote:You are not reinventing the wheel.Writing a routine that draws a rectangle? That seems to me a bit like reinventing the wheel.
Google turned up a number of libraries for OpenGL:
CPW
Fast Light Toolkit
Freeglut
GLFW
GLOW Toolkit
GLT and GlutMaster
NGL
OpenML
Does anyone who has used any of these know if one is particularly well suited to what I need to do?
There aren't any libraries that are better suited to what your stated requirements at the top of this thread are than plain old OpenGL. Making a routine to draw a rectangle in OpenGL is not considered reinventing the wheel -- it's pretty basic and only takes a few lines. Trying to stack another library on top isn't going to help for your project. Annoying as it may seem, maybe you should take a stab at it. Start at http://nehe.gamedev.net/ to find the basics you're looking for.
you say:
and
then:
I say, wtf are you asking about reinventing the wheel then, eh?
You are not reinventing the wheel because everyone in the world isn't going to start using your design, its just something you should get done asap so you can do somthing more interesting and non trivial sooner.
edit: Maybe you want to try out somthing like METAL BASIC http://www.iit.edu/~sarimar/GDS/
Quote:Like I said, I don't want to reinvent the wheel, and these seem like such basic things, though the setup to do them in OpenGL is annoying enough that a 2D OpenGL library ought to exist.
and
Quote:I just want to make sure I'm not going to be reinventing the wheel before I go at it.
then:
Quote:Writing a routine that draws a rectangle? That seems to me a bit like reinventing the wheel.
I say, wtf are you asking about reinventing the wheel then, eh?
You are not reinventing the wheel because everyone in the world isn't going to start using your design, its just something you should get done asap so you can do somthing more interesting and non trivial sooner.
edit: Maybe you want to try out somthing like METAL BASIC http://www.iit.edu/~sarimar/GDS/
Sir, e^iπ + 1 = 0, hence God exists; reply!
jab630 Wrote:Writing a routine that draws a rectangle? That seems to me a bit like reinventing the wheel.
But you're not doing that, you're writing a routine which calls an API call to draw a rectangle, and you're giving it the specifics of that rectangle, such as it's texture, position, size, place of each vertex etc. The wheel has already been invented, and what you're doing is utilising it.
glBegin(GL_QUADS);
//4 glVertex2f calls
glEnd();
that's pretty damn easy. Even the circle, which would normally be the hardest, is made easy with a gluDisk call.
//4 glVertex2f calls
glEnd();
that's pretty damn easy. Even the circle, which would normally be the hardest, is made easy with a gluDisk call.
Or just glRect().
heh, I forgot all about that.
The only things you're doing that will require writing any much code at all are images and circles. You should be able to use some trig you learned age 14 to do the circle in 10 minutes. That only leaves images, and yes, there are plenty of third-party libraries for loading images. Which one you choose will depend on your requirements.
Quote:You should be able to use some trig you learned age 14 to do the circle in 10 minutes.How would you code a circle? personally i woud just take a big circle bitmap and then scale it at the right size. Otherwise use a gluDisk.
if not what, draw it "by lines"? (calculate the left_x and the right_x for every y and draw the horizonta line?) That would work in a "pixelated" enviroment, but wouldn't fit nicely in the more "abstract" opengl setting. Or just replicate a gluDisk?
©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
The circle bitmap might be the right approach, but depending on the size variation of the circles, you might have to do some funky stuff to use different resolution textures.
The "obvious" way to do it with geometry is to draw it with a single TRIANGLE_FAN -- put the initial point in the center of the circle, and calculate some number of points around the circumference using basic trig.
The "obvious" way to do it with geometry is to draw it with a single TRIANGLE_FAN -- put the initial point in the center of the circle, and calculate some number of points around the circumference using basic trig.
Here, I wrote the library. You have to provide the OpenGL context. You also have to provide the image loading, which is noted in the source. Then simply call INIT once at startup, and call UPDATE every frame, giving it the bounds of your GL context. I didn't spend even one brain-cycle on doing *any* optimizations -- It's all brute force here ;-) There are probably a whole bunch of mistakes in there too, but I tested it minimally and it works just fine as far as I can tell.
If somebody sees something that really bothers them or they'd like to add to it, or change it, then feel free to knock yourself out ;-) Maybe actually code the circle function using something other than gluDisk as I did. Maybe write a silly little texture loader? Whatever, have fun with it...
Here's the header "jab630LIB.h":
Here's the C file "jab630LIB.c":
If somebody sees something that really bothers them or they'd like to add to it, or change it, then feel free to knock yourself out ;-) Maybe actually code the circle function using something other than gluDisk as I did. Maybe write a silly little texture loader? Whatever, have fun with it...
Here's the header "jab630LIB.h":
Code:
typedef const char* String;
void CIRCLE(String ID, int x, int y, int radius, int R, int G, int B);
void RECTANGLE(String ID, int x, int y, int width, int height, int R, int G, int B);
void IMAGE(String ID, String filename, int x, int y, int width, int height);
void HIDE(String ID);
void DELETE(String ID);
void SHOW(String ID);
void MOVE(String ID, int x, int y);
void RESIZE(String ID, int width, int height);
void ROTATE(String ID, int degrees);
void UPDATE(int boundsWidth, int boundsHeight);
void INIT(void);
void QUIT();Here's the C file "jab630LIB.c":
Code:
#include "jab630LIB.h"
#include <stdlib.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/glu.h>
#define MAX_ENTITIES 256
#define kVISIBLE 1
#define kHIDDEN 0
enum
{
kNOTHING,
kCIRCLE,
kRECTANGLE,
kIMAGE
};
typedef struct
{
GLint type;
GLint visibility;
GLubyte R, G, B;
GLint x, y;
GLint width, height;
GLint heading;
GLuint imageID;
} Entity;
Entity entity[MAX_ENTITIES];
GLUquadricObj *circle = NULL;
static void DrawCircle(Entity *entity);
static void DrawRectangle(Entity *entity);
static void DrawSprite(Entity *entity);
void CIRCLE(String ID, int x, int y, int radius, int R, int G, int B)
{
int i;
i = atoi(ID);
if (i > MAX_ENTITIES - 1 || i < 0) return;
entity[i].type = kCIRCLE;
entity[i].visibility = kVISIBLE;
entity[i].R = R;
entity[i].G = G;
entity[i].B = B;
entity[i].x = x;
entity[i].y = y;
entity[i].width = radius * 2;
entity[i].height = radius * 2;
entity[i].heading = 0;
entity[i].imageID = 0;
}
void RECTANGLE(String ID, int x, int y, int width, int height, int R, int G, int B)
{
int i;
i = atoi(ID);
if (i > MAX_ENTITIES - 1 || i < 0) return;
entity[i].type = kRECTANGLE;
entity[i].visibility = kVISIBLE;
entity[i].R = R;
entity[i].G = G;
entity[i].B = B;
entity[i].x = x;
entity[i].y = y;
entity[i].width = width;
entity[i].height = height;
entity[i].heading = 0;
entity[i].imageID = 0;
}
void IMAGE(String ID, String filename, int x, int y, int width, int height)
{
int i;
i = atoi(ID);
if (i > MAX_ENTITIES - 1 || i < 0) return;
entity[i].type = kIMAGE;
entity[i].visibility = kVISIBLE;
entity[i].R = 255;
entity[i].G = 255;
entity[i].B = 255;
entity[i].x = x;
entity[i].y = y;
entity[i].width = width;
entity[i].height = height;
entity[i].heading = 0;
// ***** TBD *****
// get your own texture id from OpenGL using something like:
// entity[i].imageID = LoadMyImage(filename);
// - for now it's just a meaningless placeholder
// - you'll have to ask someone for help if you don't know what to do here
entity[i].imageID = 0;
}
void HIDE(String ID)
{
int i;
i = atoi(ID);
if (i > MAX_ENTITIES - 1 || i < 0) return;
entity[i].visibility = kHIDDEN;
}
void DELETE(String ID)
{
int i;
i = atoi(ID);
entity[i].type = kNOTHING;
}
void SHOW(String ID)
{
int i;
i = atoi(ID);
if (i > MAX_ENTITIES - 1 || i < 0) return;
entity[i].visibility = kVISIBLE;
}
void MOVE(String ID, int x, int y)
{
int i;
i = atoi(ID);
if (i > MAX_ENTITIES - 1 || i < 0) return;
entity[i].x += x;
entity[i].y += y;
}
void RESIZE(String ID, int width, int height)
{
int i;
i = atoi(ID);
if (i > MAX_ENTITIES - 1 || i < 0) return;
entity[i].width = width;
entity[i].height = height;
}
void ROTATE(String ID, int degrees)
{
int i;
i = atoi(ID);
if (i > MAX_ENTITIES - 1 || i < 0) return;
entity[i].heading += degrees;
while (entity[i].heading > 360)
entity[i].heading -= 360;
while (entity[i].heading < 0)
entity[i].heading += 360;
}
void UPDATE(int boundsWidth, int boundsHeight)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, (GLfloat)boundsWidth, (GLfloat)boundsHeight);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
gluOrtho2D(0.0f, (GLfloat)boundsWidth, 0.0f, (GLfloat)boundsHeight);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
for (i = 0; i < MAX_ENTITIES; i++)
{
if (entity[i].type == kNOTHING ||
entity[i].visibility != kVISIBLE) continue;
switch (entity[i].type)
{
case kCIRCLE:
DrawCircle(&entity[i]);
break;
case kRECTANGLE:
DrawRectangle(&entity[i]);
break;
case kIMAGE:
DrawSprite(&entity[i]);
break;
default:
continue;
}
}
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void INIT(void)
{
int i;
for (i = 0; i < MAX_ENTITIES; i++)
{
entity[i].type = kNOTHING;
}
if (circle == NULL)
{
circle = gluNewQuadric();
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
}
void QUIT(void)
{
ExitToShell();
}
static void DrawCircle(Entity *entity)
{
GLdouble radius;
radius = (GLdouble)entity->width * 0.25;
glPushMatrix();
glDisable(GL_TEXTURE_2D);
glColor3ub(entity->R, entity->G, entity->B);
glTranslatef((GLfloat)entity->x, (GLfloat)entity->y, 0.0f);
gluDisk(circle, 0.0, radius, 20, 1);
glPopMatrix();
}
static void DrawRectangle(Entity *entity)
{
GLint halfWidth = entity->width * 0.5f;
GLint halfHeight = entity->height * 0.5f;
glPushMatrix();
glDisable(GL_TEXTURE_2D);
glColor3ub(entity->R, entity->G, entity->B);
glTranslatef((GLfloat)entity->x, (GLfloat)entity->y, 0.0f);
glRotatef(entity->heading, 0.0f, 0.0f, 1.0f);
glRecti(-halfWidth, -halfHeight, halfWidth, halfHeight);
glPopMatrix();
}
static void DrawSprite(Entity *entity)
{
GLint halfWidth = entity->width * 0.5f;
GLint halfHeight = entity->height * 0.5f;
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, entity->imageID);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glTranslatef((GLfloat)entity->x, (GLfloat)entity->y, 0.0f);
glRotatef(entity->heading, 0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2i(- halfWidth, -halfHeight);
glTexCoord2f(1.0f, 0.0f);
glVertex2i(halfWidth, -halfHeight);
glTexCoord2f(1.0f, 1.0f);
glVertex2i(halfWidth, halfHeight);
glTexCoord2f(0.0f, 1.0f);
glVertex2i(-halfWidth, halfHeight);
glEnd();
glPopMatrix();
}
AnotherJake:
Thanks for going above and beyond. I'm actually going to stick with SDL for the following reasons:
- The graphics I'm doing are so simple that it will be plenty fast enough.
- The most important thing is that this be simple and straightforward to maintain since I'm graduating this semester and the people who will be using it don't have that much programming experience and no OpenGL experience.
- Someone on gamedev.net just told me about sdl_draw (http://sourceforge.net/projects/sdl-draw/), which is exactly what I'm looking for.
Thanks anyway,
Josh
Thanks for going above and beyond. I'm actually going to stick with SDL for the following reasons:
- The graphics I'm doing are so simple that it will be plenty fast enough.
- The most important thing is that this be simple and straightforward to maintain since I'm graduating this semester and the people who will be using it don't have that much programming experience and no OpenGL experience.
- Someone on gamedev.net just told me about sdl_draw (http://sourceforge.net/projects/sdl-draw/), which is exactly what I'm looking for.
Thanks anyway,
Josh
You could also check out sdl_prim and sdl_gfx. I've used those before.
Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
jab630 Wrote:AnotherJake:Sure, no problem. I was under the impression that you were looking for speed, so I figured I'd demonstrate just how easy it is to do with OpenGL. It's less than 300 lines including the header -- maybe only fifty of which have anything to do with OpenGL. But anyway, hey, if you think you've found a better way to suit your needs, then by all means, rock on!
Thanks for going above and beyond. I'm actually going to stick with SDL for the following reasons...
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Free, Portable Graphics loading library/Header | Jones | 5 | 2,849 |
Feb 7, 2006 12:15 PM Last Post: Zekaric |
|
| Building SDL Framework & miniaturize fix | PowerMacX | 3 | 3,414 |
Oct 22, 2004 06:31 PM Last Post: PowerMacX |
|
| SDL Simple Graphics? | IBethune | 1 | 2,872 |
Jun 29, 2003 04:51 AM Last Post: OneSadCookie |
|

