diff --git a/GNUmakefile b/GNUmakefile index b40c3d5..343874d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -90,7 +90,7 @@ EXAMPLES = examples/example$(EXEC) examples/rotate$(EXEC) examples/image$(EXEC) ifeq ($(OPENGL),1) L_OBJS += src/widget/opengl.o -EXAMPLES += examples/opengl$(EXEC) examples/gears$(EXEC) +EXAMPLES += examples/gltriangle$(EXEC) examples/glgears$(EXEC) examples/glboing$(EXEC) endif ifeq ($(VULKAN),1) @@ -111,10 +111,7 @@ format: src/libMw$(SO): $(L_OBJS) $(CC) $(L_LDFLAGS) -shared -o $@ $^ $(L_LIBS) -examples/opengl$(EXEC): examples/opengl.o src/libMw$(SO) - $(CC) $(E_LDFLAGS) -o $@ $< $(E_LIBS) $(GL) - -examples/gears$(EXEC): examples/gears.o src/libMw$(SO) +examples/gl%$(EXEC): examples/gl%.o src/libMw$(SO) $(CC) $(E_LDFLAGS) -o $@ $< $(E_LIBS) $(GL) examples/%$(EXEC): examples/%.o src/libMw$(SO) diff --git a/examples/glboing.c b/examples/glboing.c new file mode 100644 index 0000000..a81f93f --- /dev/null +++ b/examples/glboing.c @@ -0,0 +1,207 @@ +/* $Id$ */ +#include +#include + +#include + +MwWidget opengl; + +/* + * Bouncing ball demo. + * + * This program is in the public domain + * + * Brian Paul + */ + +#include +#include + +#define COS(X) cos((X) * 3.14159 / 180.0) +#define SIN(X) sin((X) * 3.14159 / 180.0) + +#define RED 1.0, 0.0, 0.0 +#define WHITE 1.0, 1.0, 1.0 +#define CYAN 0.0, 1.0, 1.0 + +GLuint Ball; +GLenum Mode; +GLfloat Zrot = 0.0, Zstep = 6.0; +GLfloat Xpos = 0.0, Ypos = 1.0; +GLfloat Xvel = 0.2, Yvel = 0.0; +GLfloat Xmin = -4.0, Xmax = 4.0; +GLfloat Ymin = -3.8, Ymax = 4.0; +GLfloat G = -0.1; + +static GLuint make_ball(void) { + GLuint list; + GLfloat a, b; + GLfloat da = 18.0, db = 18.0; + GLfloat radius = 1.0; + GLuint color; + GLfloat x, y, z; + + list = glGenLists(1); + + glNewList(list, GL_COMPILE); + + color = 0; + for(a = -90.0; a + da <= 90.0; a += da) { + + glBegin(GL_QUAD_STRIP); + for(b = 0.0; b <= 360.0; b += db) { + + if(color) { + glColor3f(RED); + } else { + glColor3f(WHITE); + } + + x = COS(b) * COS(a); + y = SIN(b) * COS(a); + z = SIN(a); + glVertex3f(x, y, z); + + x = radius * COS(b) * COS(a + da); + y = radius * SIN(b) * COS(a + da); + z = radius * SIN(a + da); + glVertex3f(x, y, z); + + color = 1 - color; + } + glEnd(); + } + + glEndList(); + + return list; +} + +static void reshape(int width, int height) { + glViewport(0, 0, (GLint)width, (GLint)height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-6.0, 6.0, -6.0, 6.0, -6.0, 6.0); + glMatrixMode(GL_MODELVIEW); +} + +static void draw(void) { + GLint i; + + glClear(GL_COLOR_BUFFER_BIT); + + glColor3f(CYAN); + glBegin(GL_LINES); + for(i = -5; i <= 5; i++) { + glVertex2i(i, -5); + glVertex2i(i, 5); + } + for(i = -5; i <= 5; i++) { + glVertex2i(-5, i); + glVertex2i(5, i); + } + for(i = -5; i <= 5; i++) { + glVertex2i(i, -5); + glVertex2f(i * 1.15, -5.9); + } + glVertex2f(-5.3, -5.35); + glVertex2f(5.3, -5.35); + glVertex2f(-5.75, -5.9); + glVertex2f(5.75, -5.9); + glEnd(); + + glPushMatrix(); + glTranslatef(Xpos, Ypos, 0.0); + glScalef(2.0, 2.0, 2.0); + glRotatef(8.0, 0.0, 0.0, 1.0); + glRotatef(90.0, 1.0, 0.0, 0.0); + glRotatef(Zrot, 0.0, 0.0, 1.0); + + glCallList(Ball); + + glPopMatrix(); + + glFlush(); +} + +static void idle(void) { + static float vel0 = -100.0; + + Zrot += Zstep; + + Xpos += Xvel; + if(Xpos >= Xmax) { + Xpos = Xmax; + Xvel = -Xvel; + Zstep = -Zstep; + } + if(Xpos <= Xmin) { + Xpos = Xmin; + Xvel = -Xvel; + Zstep = -Zstep; + } + Ypos += Yvel; + Yvel += G; + if(Ypos < Ymin) { + Ypos = Ymin; + if(vel0 == -100.0) + vel0 = fabs(Yvel); + Yvel = vel0; + } +} + +static void init(void) { + Ball = make_ball(); + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + glDisable(GL_DITHER); + glShadeModel(GL_FLAT); +} + +static void tick(MwWidget handle, void* user, void* client) { + (void)handle; + (void)user; + (void)client; + + draw(); + idle(); + + MwOpenGLSwapBuffer(opengl); +} + +static void resize(MwWidget handle, void* user, void* client) { + int ww, wh; + + (void)handle; + (void)user; + (void)client; + + ww = MwGetInteger(handle, MwNwidth) - 100; + wh = MwGetInteger(handle, MwNheight) - 100; + + MwVaApply(opengl, + MwNwidth, ww, + MwNheight, wh, + NULL); + + reshape(ww, wh); +} + +int main() { + MwWidget window; + + window = MwVaCreateWidget(MwWindowClass, "main", NULL, 0, 0, 500, 500, + MwNtitle, "boing", + NULL); + opengl = MwCreateWidget(MwOpenGLClass, "opengl", window, 50, 50, 400, 400); + + MwOpenGLMakeCurrent(opengl); + + init(); + reshape(400, 400); + + MwAddUserHandler(window, MwNresizeHandler, resize, NULL); + MwAddUserHandler(window, MwNtickHandler, tick, NULL); + + MwLoop(window); +} diff --git a/examples/gears.c b/examples/glgears.c similarity index 100% rename from examples/gears.c rename to examples/glgears.c diff --git a/examples/opengl.c b/examples/gltriangle.c similarity index 100% rename from examples/opengl.c rename to examples/gltriangle.c