Skip to content

Instantly share code, notes, and snippets.

@snipsnipsnip
Forked from takuma104/spherical_panorama_sample.rb
Last active August 24, 2019 15:34
Show Gist options
  • Save snipsnipsnip/141327 to your computer and use it in GitHub Desktop.
Save snipsnipsnip/141327 to your computer and use it in GitHub Desktop.
spherical_panorama_sample.c
#ifndef DEBUG_H_
#define DEBUG_H_
#ifdef _MSC_VER
# define DEBUG_H_FUNCTION_NAME __FUNCTION__
#else
# define DEBUG_H_FUNCTION_NAME __func__
#endif
#define PrintInfoFormatIntlIntl(p,line) \
stderr, __FILE__ " " DEBUG_H_FUNCTION_NAME " " #line ": " p "\n"
#define PrintInfoFormatIntl(p,line) PrintInfoFormatIntlIntl(p,line)
#define PrintInfoFormat(p) PrintInfoFormatIntl(p,__LINE__)
#define PrintInfo(p) fprintf(PrintInfoFormat(p))
#define PrintInfo1(p,x) fprintf(PrintInfoFormat(p), x)
#define PrintInfo2(p,x,y) fprintf(PrintInfoFormat(p), x, y)
#define PrintInfo3(p,x,y,z) fprintf(PrintInfoFormat(p), x, y, z)
#define PrintInfo4(p,x,y,z,w) fprintf(PrintInfoFormat(p), x, y, z, w)
#define PrintInfo5(p,x,y,z,w,v) fprintf(PrintInfoFormat(p), x, y, z, w, v)
#define EnsureIntl(x) \
do \
{ \
if (!(x)) \
{ \
PrintInfo("ensure failed: " #x); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define Ensure(x) EnsureIntl(x)
#endif /* DEBUG_H_ */
#include <stdio.h>
#include <stdlib.h>
#include <glut.h>
#include <wand/studio.h>
#include "debug.h"
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
typedef struct
{
int x;
int y;
}
Coordinates;
static Coordinates viewpos, viewpos_saved, drag_start_pos;
static int wireframe = 0;
static GLUquadric *qo = NULL;
static GLuint texture = -1;
static int draw_cylinder = 0;
static GLuint slice = 48;
static double radius = 1.3;
static float angle = 80.0f;
static float aspect = 0.75f;
void cleanup(void)
{
PrintInfo("start");
if (glIsTexture(texture))
{
glDeleteTextures(1, &texture);
}
if (qo != NULL)
{
gluDeleteQuadric(qo);
}
PrintInfo("end");
}
unsigned char *load_texture_rawdata(const char *filename, unsigned long *width, unsigned long *height)
{
size_t length = 0;
unsigned char *blob;
MagickWand *wand;
PrintInfo("start");
Ensure(wand = NewMagickWand());
Ensure(MagickReadImage(wand, filename));
Ensure(MagickSetDepth(wand, 8));
Ensure(MagickSetFormat(wand, "RGBA"));
Ensure(blob = MagickGetImagesBlob(wand, &length));
*width = MagickGetImageWidth(wand);
*height = MagickGetImageHeight(wand);
DestroyMagickWand(wand);
PrintInfo3("image size %lux%lu (%lu byte)", *height, *width, length);
PrintInfo("end");
return blob;
}
void load_texture(const char *filename)
{
unsigned long width, height;
unsigned char *raw;
PrintInfo1("start (filename \"%s\")", filename);
raw = load_texture_rawdata(filename, &width, &height);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, raw);
Ensure(0 == gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, GL_RGBA, GL_UNSIGNED_BYTE, raw));
free(raw);
PrintInfo("end");
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glLoadIdentity();
glRotated(viewpos.y, 1, 0, 0);
glRotated(viewpos.x, 0, 0, 1);
gluQuadricDrawStyle(qo, wireframe ? GLU_LINE : GLU_FILL);
gluSphere(qo, radius, slice, slice); // draw sphere
if (draw_cylinder)
{
glTranslated(0, 0, -radius);
gluCylinder(qo, radius, radius, radius * 2, slice, slice);
}
glPopMatrix();
glFlush();
glutSwapBuffers();
}
// mouse down/up event
void mouse(int button, int state, int x, int y)
{
if (state == 0)
{
drag_start_pos.x = x;
drag_start_pos.y = y;
viewpos_saved = viewpos;
}
}
// mouse move event
void motion(int x, int y)
{
double fac = 0.2;
viewpos.x = viewpos_saved.x + ((int)((x - drag_start_pos.x) * fac)) % 360;
viewpos.y = viewpos_saved.y + ((int)((drag_start_pos.y - y) * fac)) % 360;
glutPostRedisplay(); // to redraw
}
void jelly(int count)
{
PrintInfo1("count %d", count);
if (count == 48 * 2)
{
return;
}
if (count == 0)
{
slice = 3;
}
else if (count % 2 == 0)
{
slice++;
}
glutPostRedisplay();
glutTimerFunc(1000 / 30, jelly, count + 1);
}
void help(void)
{
puts("Z or X: increment/decrement slice");
puts("A or S: increment/decrement radius");
puts("D or F: increment/decrement view angle");
puts("J: jelly");
puts("C: toggle cylinder");
puts("R: reset parameters");
puts("H: show this help");
puts("Q or ESC: exit");
}
void reset_perspective(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(angle, aspect, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void reset_parameters(void)
{
Coordinates viewpos_initial = { 0, 90 };
Coordinates drag_start_pos_initial = { 0, 0 };
viewpos = viewpos_initial;
viewpos_saved = viewpos_initial;
drag_start_pos = drag_start_pos_initial;
wireframe = 0;
draw_cylinder = 0;
radius = 1.3;
slice = 48;
angle = 80.0f;
aspect = 0.75f;
}
// keyboard down event
void keyboard(unsigned char key, int x, int y)
{
PrintInfo1("key: '%c'", key);
switch (key)
{
case 'd':
angle++;
reset_perspective();
break;
case 'f':
angle--;
reset_perspective();
break;
case 'z':
slice++;
break;
case 'x':
slice--;
break;
case 'a':
radius += 0.1;
break;
case 's':
radius -= 0.1;
break;
case 'j':
glutTimerFunc(1000 / 30, jelly, 0);
PrintInfo("start jelly");
return;
case 'c':
draw_cylinder = !draw_cylinder;
break;
case 'w':
wireframe = !wireframe;
break;
case 'r':
reset_parameters();
break;
case 'h':
help();
return;
case 'q':
case 27:
exit(1);
}
PrintInfo4("slice: %d, radius: %lf, angle: %f, wireframe: %d", slice, radius, angle, wireframe);
glutPostRedisplay();
}
void init_glut(int *argc, char **argv)
{
char *window_caption;
glutInit(argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
Ensure(argc != NULL);
Ensure(*argc > 1);
Ensure(window_caption = malloc(sizeof("Panorama View: \"\"") + strlen(argv[1])));
sprintf(window_caption, "Panorama View: \"%s\"", argv[1]);
glutCreateWindow(window_caption);
free(window_caption);
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
aspect = width/(float)height;
reset_perspective();
}
void init_gl(void)
{
reshape(WINDOW_WIDTH, WINDOW_HEIGHT);
glEnable(GL_TEXTURE_2D);
glClearColor(0.2, 0.2, 0.2, 1.0);
Ensure(qo = gluNewQuadric());
gluQuadricNormals(qo, GLU_SMOOTH);
gluQuadricTexture(qo, GL_TRUE);
}
void init(int argc, char **argv)
{
atexit(cleanup);
init_glut(&argc, argv);
init_gl();
load_texture(argv[1]);
reset_parameters();
}
void run_glut(void)
{
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutReshapeFunc(reshape);
glutMainLoop();
}
int main(int argc, char **argv)
{
help();
init(argc, argv);
run_glut();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment