I've loaded a .obj cube in my scene and I want to draw a sphere on every vertices (vertices + origin).
##
## Three-D Library generated .obj file
## cube
##
mtllib cube.mtl
usemtl red
# 0 materials
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
# 8 vertices
In my draw() function:
if(spheres){
i=0, j=0;
while (1){
printf("%d : %f %f %f\n", j, model->vertices[i], model->vertices[i+1], model->vertices[i+2]);
glTranslatef(model->vertices[i], model->vertices[i+1], model->vertices[i+2]);
glColor3f(0.0, 0.0, 1.0);
glutSolidSphere(0.4, 5, 5);
if(j >= model->numvertices)
break;
i=i+3;
j++;
}
}
where 'model' is
GLMmodel* model; /* glm model data structure */
http://www.teina.org/TER_3DModeler/glm_8h-source.html
BUT when I draw them, they are not in correct positions.
In the picture above I draw them "manually":
glTranslatef(-1.000000, -1.000000, 1.000000);
glColor3f(0.0, 0.0, 1.0);
glutSolidSphere(0.3, 5, 5);
glTranslatef(-1.000000, 1.000000, 1.000000);
glColor3f(0.0, 0.0, 1.0);
glutSolidSphere(0.3, 5, 5);
with no success.
All code:
/*
gc_smooth.c
Nate Robins, 1998
Giulio Casciola, 2008
Model viewer program. Exercises the glm library.
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <GL/glut.h>
#include "gltb.h"
#include "glm.h"
#include "dirent32.h"
#pragma comment( linker, "/entry:\"mainCRTStartup\"" ) // set the entry point to be main()
#define DATA_DIR "data/"
#define NUM_FRAMES 5
char* model_file = NULL; /* name of the obect file */
GLuint model_list = 0; /* display list for object */
GLMmodel* model; /* glm model data structure */
GLfloat scale; /* original scale factor */
GLfloat smoothing_angle = 90.0; /* smoothing angle */
GLfloat weld_distance = 0.00001; /* epsilon for welding vertices */
GLboolean facet_normal = GL_FALSE; /* draw with facet normal? */
GLboolean bounding_box = GL_FALSE; /* bounding box on? */
GLboolean spheres = GL_FALSE;
GLboolean performance = GL_FALSE; /* performance counter on? */
GLboolean stats = GL_FALSE; /* statistics on? */
GLuint material_mode = 0; /* 0=none, 1=color, 2=material, 3=texture */
GLint entries = 0; /* entries in model menu */
GLdouble pan_x = 0.0;
GLdouble pan_y = 0.0;
GLdouble pan_z = 0.0;
char texnames[1][64] = {"foto_rgb.ppm"};
//char texnames[1][64] = {"grid.ppm"};
GLint w,h;
GLubyte* texture;
#define CLK_TCK 1000
#if defined(_WIN32)
#include <sys/timeb.h>
#else
#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/times.h>
#endif
float elapsed(void){
static long begin = 0;
static long finish, difference;
#if defined(_WIN32)
static struct timeb tb;
ftime(&tb);
finish = tb.time*1000+tb.millitm;
#else
static struct tms tb;
finish = times(&tb);
#endif
difference = finish - begin;
begin = finish;
return (float)difference/(float)CLK_TCK;
}
void shadowtext(int x, int y, char* s) {
int lines;
char* p;
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, glutGet(GLUT_WINDOW_WIDTH),
0, glutGet(GLUT_WINDOW_HEIGHT), -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor3ub(0, 0, 0);
glRasterPos2i(x+1, y-1);
for(p = s, lines = 0; *p; p++) {
if (*p == '\n') {
lines++;
glRasterPos2i(x+1, y-1-(lines*18));
}
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *p);
}
glColor3ub(0, 128, 255);
glRasterPos2i(x, y);
for(p = s, lines = 0; *p; p++) {
if (*p == '\n') {
lines++;
glRasterPos2i(x, y-(lines*18));
}
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *p);
}
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glEnable(GL_DEPTH_TEST);
}
void lists(void){
GLfloat ambient[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
GLfloat specular[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat shininess = 65.0;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialf(GL_FRONT, GL_SHININESS, shininess);
if (model_list)
glDeleteLists(model_list, 1);
glDisable(GL_TEXTURE_2D);
/* generate a list */
switch (material_mode)
{
case 0:
if (facet_normal)
model_list = glmList(model, GLM_FLAT);
else
model_list = glmList(model, GLM_SMOOTH);
break;
case 1:
if (facet_normal)
model_list = glmList(model, GLM_FLAT | GLM_COLOR);
else
model_list = glmList(model, GLM_SMOOTH | GLM_COLOR);
break;
case 2:
if (facet_normal)
model_list = glmList(model, GLM_FLAT | GLM_MATERIAL);
else
model_list = glmList(model, GLM_SMOOTH | GLM_MATERIAL);
break;
case 3:
glEnable(GL_TEXTURE_2D);
model_list = glmList(model, GLM_TEXTURE);
// glDisable(GL_TEXTURE_2D);
break;
}
}
void init(void){
gltbInit(GLUT_LEFT_BUTTON);
/* read in the model */
model = glmReadOBJ(model_file);
scale = glmUnitize(model);
glmFacetNormals(model);
glmVertexNormals(model, smoothing_angle);
if (model->nummaterials > 0)
material_mode = 2;
/* create new display lists */
lists();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable(GL_DEPTH_TEST);
}
void reshape(int width, int height){
gltbReshape(width, height);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat)height / (GLfloat)width, 1.0, 128.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.0);
}
void display(void){
static char s[256], t[32];
static char* p;
static int frames = 0;
int i=0,j=0;
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(pan_x, pan_y, 0.0);
gltbMatrix();
#if 0 /* glmDraw() performance test */
swith(material_mode)
{
case 0:
if (facet_normal)
glmDraw(model, GLM_FLAT);
else
glmDraw(model, GLM_SMOOTH);
break;
case 1:
if (facet_normal)
glmDraw(model, GLM_FLAT | GLM_COLOR);
else
glmDraw(model, GLM_SMOOTH | GLM_COLOR);
break;
case 2:
if (facet_normal)
glmDraw(model, GLM_FLAT | GLM_MATERIAL);
else
glmDraw(model, GLM_SMOOTH | GLM_MATERIAL);
break;
case 3:
glEnable(GL_TEXTURE_2D);
glmDraw(model, GLM_TEXTURE );
// glDisable(GL_TEXTURE_2D);
break;
}
#else
glCallList(model_list);
#endif
glDisable(GL_LIGHTING);
if (bounding_box) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
glColor4f(1.0, 0.0, 0.0, 0.25);
glutSolidCube(2.0);
glDisable(GL_BLEND);
}
if(spheres){
//i=0, j=0;
//while (1){
printf("%d : %f %f %f\n", j, model->vertices[i], model->vertices[i+1], model->vertices[i+2]);
glTranslatef(-1.000000, -1.000000, 1.000000);
glColor3f(0.0, 0.0, 1.0);
glutSolidSphere(0.3, 5, 5);
glTranslatef(-1.000000, 1.000000, 1.000000);
glColor3f(0.0, 0.0, 1.0);
glutSolidSphere(0.3, 5, 5);
//if(j >= model->numvertices)
// break;
//i=i+3;
//j++;
//}
}
glPopMatrix();
if (stats) {
/* XXX - this could be done a _whole lot_ faster... */
int height = glutGet(GLUT_WINDOW_HEIGHT);
glColor3ub(0, 0, 0);
sprintf(s, "%s\n%d vertices\n%d triangles\n%d normals\n"
"%d texcoords\n%d groups\n%d materials",
model->pathname, model->numvertices, model->numtriangles,
model->numnormals, model->numtexcoords, model->numgroups,
model->nummaterials);
shadowtext(5, height-(5+18*1), s);
}
/* spit out frame rate. */
frames++;
if (frames > NUM_FRAMES) {
sprintf(t, "%g fps", frames/elapsed());
frames = 0;
}
if (performance) {
shadowtext(5, 5, t);
}
glutSwapBuffers();
glEnable(GL_LIGHTING);
}
void keyboard(unsigned char key, int x, int y){
GLint params[2];
switch (key) {
case 'h':
printf("help\n\n");
printf("w - Toggle wireframe/filled\n");
printf("c - Toggle culling\n");
printf("n - Toggle facet/smooth normal\n");
printf("b - Toggle bounding box\n");
printf("r - Reverse polygon winding\n");
printf("m - Toggle color/material/none/texture mode\n");
printf("p - Toggle performance indicator\n");
printf("s/S - Scale model smaller/larger\n");
printf("t - Show model stats\n");
printf("o - Weld vertices in model\n");
printf("+/- - Increase/decrease smoothing angle\n");
printf("W - Write model to file (out.obj)\n");
printf("q/escape - Quit\n\n");
break;
case 't':
stats = !stats;
break;
case 'p':
performance = !performance;
break;
case 'm':
material_mode++;
if (material_mode > 3)
material_mode = 0;
printf("material_mode = %d\n", material_mode);
lists();
break;
case 'd':
glmDelete(model);
init();
lists();
break;
case 'w':
glGetIntegerv(GL_POLYGON_MODE, params);
if (params[0] == GL_FILL)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
break;
case 'c':
if (glIsEnabled(GL_CULL_FACE))
glDisable(GL_CULL_FACE);
else
glEnable(GL_CULL_FACE);
break;
case 'b':
bounding_box = !bounding_box;
break;
case 'n':
facet_normal = !facet_normal;
lists();
break;
case 'r':
glmReverseWinding(model);
lists();
break;
case 's':
glmScale(model, 0.8);
lists();
break;
case 'S':
glmScale(model, 1.25);
lists();
break;
case 'o':
//printf("Welded %d\n", glmWeld(model, weld_distance));
glmVertexNormals(model, smoothing_angle);
lists();
break;
case 'O':
weld_distance += 0.01;
printf("Weld distance: %.2f\n", weld_distance);
glmWeld(model, weld_distance);
glmFacetNormals(model);
glmVertexNormals(model, smoothing_angle);
lists();
break;
case '-':
smoothing_angle -= 1.0;
printf("Smoothing angle: %.1f\n", smoothing_angle);
glmVertexNormals(model, smoothing_angle);
lists();
break;
case '+':
smoothing_angle += 1.0;
printf("Smoothing angle: %.1f\n", smoothing_angle);
glmVertexNormals(model, smoothing_angle);
lists();
break;
case 'W':
glmScale(model, 1.0/scale);
glmWriteOBJ(model, "out.obj", GLM_SMOOTH | GLM_MATERIAL);
break;
case 'R':
{
GLuint i;
GLfloat swap;
for (i = 1; i <= model->numvertices; i++) {
swap = model->vertices[3 * i + 1];
model->vertices[3 * i + 1] = model->vertices[3 * i + 2];
model->vertices[3 * i + 2] = -swap;
}
glmFacetNormals(model);
lists();
break;
}
case 'v':
{
spheres = !spheres;
/*printf("Il modello ha %u vertici \n", model->numvertices);
int i=0, j=0;
while (1){
printf("%d : %f %f %f\n", j, model->vertices[i], model->vertices[i+1], model->vertices[i+2]);
if(j >= model->numvertices)
break;
i=i+3;
j++;
}*/
break;
}
case 27:
exit(0);
break;
}
glutPostRedisplay();
}
void menu(int item){
int i = 0;
DIR* dirp;
char* name;
struct dirent* direntp;
if (item > 0) {
keyboard((unsigned char)item, 0, 0);
} else {
dirp = opendir(DATA_DIR);
while ((direntp = readdir(dirp)) != NULL) {
if (strstr(direntp->d_name, ".obj")) {
i++;
if (i == -item)
break;
}
}
if (!direntp)
return;
name = (char*)malloc(strlen(direntp->d_name) + strlen(DATA_DIR) + 1);
strcpy(name, DATA_DIR);
strcat(name, direntp->d_name);
model = glmReadOBJ(name);
scale = glmUnitize(model);
glmFacetNormals(model);
glmVertexNormals(model, smoothing_angle);
if (model->nummaterials > 0)
material_mode = 2;
else
material_mode = 0;
lists();
free(name);
glutPostRedisplay();
}
}
static GLint mouse_state;
static GLint mouse_button;
void mouse(int button, int state, int x, int y){
GLdouble model[4*4];
GLdouble proj[4*4];
GLint view[4];
/* fix for two-button mice -- left mouse + shift = middle mouse */
if (button == GLUT_LEFT_BUTTON && glutGetModifiers() & GLUT_ACTIVE_SHIFT)
button = GLUT_MIDDLE_BUTTON;
gltbMouse(button, state, x, y);
mouse_state = state;
mouse_button = button;
if (state == GLUT_DOWN && button == GLUT_MIDDLE_BUTTON) {
glGetDoublev(GL_MODELVIEW_MATRIX, model);
glGetDoublev(GL_PROJECTION_MATRIX, proj);
glGetIntegerv(GL_VIEWPORT, view);
gluProject((GLdouble)x, (GLdouble)y, 0.0,
model, proj, view,
&pan_x, &pan_y, &pan_z);
gluUnProject((GLdouble)x, (GLdouble)y, pan_z,
model, proj, view,
&pan_x, &pan_y, &pan_z);
pan_y = -pan_y;
}
glutPostRedisplay();
}
void motion(int x, int y){
GLdouble model[4*4];
GLdouble proj[4*4];
GLint view[4];
gltbMotion(x, y);
if (mouse_state == GLUT_DOWN && mouse_button == GLUT_MIDDLE_BUTTON) {
glGetDoublev(GL_MODELVIEW_MATRIX, model);
glGetDoublev(GL_PROJECTION_MATRIX, proj);
glGetIntegerv(GL_VIEWPORT, view);
gluProject((GLdouble)x, (GLdouble)y, 0.0,
model, proj, view,
&pan_x, &pan_y, &pan_z);
gluUnProject((GLdouble)x, (GLdouble)y, pan_z,
model, proj, view,
&pan_x, &pan_y, &pan_z);
pan_y = -pan_y;
}
glutPostRedisplay();
}
/* ppmRead: read a PPM raw (type P6) file. The PPM file has a header
that should look something like:
P6
# comment
width height max_value
rgbrgbrgb...
where "P6" is the magic cookie which identifies the file type and
should be the only characters on the first line followed by a
carriage return. Any line starting with a # mark will be treated
as a comment and discarded. After the magic cookie, three integer
values are expected: width, height of the image and the maximum
value for a pixel (max_value must be < 256 for PPM raw files). The
data section consists of width*height rgb triplets (one byte each)
in binary format (i.e., such as that written with fwrite() or
equivalent).
The rgb data is returned as an array of unsigned chars (packed
rgb). The malloc()'d memory should be free()'d by the caller. If
an error occurs, an error message is sent to stderr and NULL is
returned.
*/
unsigned char*
ppmRead(char* filename, int* width, int* height)
{
FILE* fp;
int i, w, h, d;
unsigned char* image;
char head[70]; /* max line <= 70 in PPM (per spec). */
fp = fopen(filename, "rb");
if (!fp) {
perror(filename);
return NULL;
}
/* grab first two chars of the file and make sure that it has the
correct magic cookie for a raw PPM file. */
fgets(head, 70, fp);
if (strncmp(head, "P6", 2)) {
fprintf(stderr, "%s: Not a raw PPM file\n", filename);
return NULL;
}
/* grab the three elements in the header (width, height, maxval). */
i = 0;
while(i < 3) {
fgets(head, 70, fp);
if (head[0] == '#') /* skip comments. */
continue;
if (i == 0)
i += sscanf(head, "%d %d %d", &w, &h, &d);
else if (i == 1)
i += sscanf(head, "%d %d", &h, &d);
else if (i == 2)
i += sscanf(head, "%d", &d);
}
/* grab all the image data in one fell swoop. */
image = (unsigned char*)malloc(sizeof(unsigned char)*w*h*3);
fread(image, sizeof(unsigned char), w*h*3, fp);
fclose(fp);
*width = w;
*height = h;
return image;
}
textures(void)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/* XXX - RE bug - must enable texture before bind. */
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 1);
texture = (GLubyte*)ppmRead(texnames[0], &w, &h);
// glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0,
// GL_RGB, GL_UNSIGNED_BYTE, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, w, h,
GL_RGB, GL_UNSIGNED_BYTE, texture);
free(texture);
/* XXX - RE bug - must enable texture before bind. */
glDisable(GL_TEXTURE_2D);
}
int main(int argc, char** argv){
int buffering = GLUT_DOUBLE;
struct dirent* direntp;
DIR* dirp;
int models;
glutInitWindowSize(512, 512);
glutInit(&argc, argv);
while (--argc) {
if (strcmp(argv[argc], "-sb") == 0)
buffering = GLUT_SINGLE;
else
model_file = argv[argc];
}
if (!model_file) {
// model_file = "data/dolphins.obj";
model_file = "data/boeing_2.obj";
}
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | buffering);
glutCreateWindow("Smooth");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(motion);
/* Image data packed tightly. */
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
textures();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
// glEnable(GL_TEXTURE_2D);
models = glutCreateMenu(menu);
dirp = opendir(DATA_DIR);
if (!dirp) {
fprintf(stderr, "%s: can't open data directory.\n", argv[0]);
} else {
while ((direntp = readdir(dirp)) != NULL) {
if (strstr(direntp->d_name, ".obj")) {
entries++;
glutAddMenuEntry(direntp->d_name, -entries);
}
}
closedir(dirp);
}
glutCreateMenu(menu);
glutAddMenuEntry("Smooth", 0);
glutAddMenuEntry("", 0);
glutAddSubMenu("Models", models);
glutAddMenuEntry("", 0);
glutAddMenuEntry("[w] Toggle wireframe/filled", 'w');
glutAddMenuEntry("[c] Toggle culling on/off", 'c');
glutAddMenuEntry("[n] Toggle face/smooth normals", 'n');
glutAddMenuEntry("[b] Toggle bounding box on/off", 'b');
glutAddMenuEntry("[p] Toggle frame rate on/off", 'p');
glutAddMenuEntry("[t] Toggle model statistics", 't');
glutAddMenuEntry("[m] Toggle color/material/none/texture mode", 'm');
glutAddMenuEntry("[r] Reverse polygon winding", 'r');
glutAddMenuEntry("[s] Scale model smaller", 's');
glutAddMenuEntry("[S] Scale model larger", 'S');
glutAddMenuEntry("[o] Weld redundant vertices", 'o');
glutAddMenuEntry("[+] Increase smoothing angle", '+');
glutAddMenuEntry("[-] Decrease smoothing angle", '-');
glutAddMenuEntry("[W] Write model to file (out.obj)", 'W');
glutAddMenuEntry("", 0);
glutAddMenuEntry("[Esc] Quit", 27);
glutAttachMenu(GLUT_RIGHT_BUTTON);
init();
glutMainLoop();
return 0;
}
glTranslatef() multiples the translation transform by the current matrix. Your code seems to be assuming that it overwrites the the current matrix.
Push, translate, draw, pop:
if(spheres){
i=0, j=0;
while (1){
printf("%d : %f %f %f\n", j, model->vertices[i], model->vertices[i+1], model->vertices[i+2]);
glPushMatrix();
glTranslatef(model->vertices[i], model->vertices[i+1], model->vertices[i+2]);
glColor3f(0.0, 0.0, 1.0);
glutSolidSphere(0.4, 5, 5);
glPopMatrix();
if(j >= model->numvertices)
break;
i=i+3;
j++;
}
}
Related
I want to do something like a 3d-shooter.
The calculations seems to be correct, but it is works every other time with a spread with 180 degree rotation on every call glutPostRedisplay(). I understood that thanks to that red line.
I do this with such IDE: Code Blocks / Qt Creator under Linux(Ubuntu x64).
main.cpp
#include "Functions.h"
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(wnd_width, wnd_height);
glutInitWindowPosition(300, 100);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
glutCreateWindow("OpenGL my");
glutDisplayFunc(display);
glutIdleFunc(Idle);
glutSpecialFunc(KeyPressed);
GLdouble aspect = wnd_width/wnd_height;
gluPerspective(90, aspect, 0.1, 10);
glTranslatef(0, -0.3, 0);
glutMainLoop();
return 0;
}
Functions.h
#include <GL/glut.h>
#include <math.h>
#include <iostream>
int wnd_width=1300;
int wnd_height=900;
float pos_x=0, pos_z=0.1;
float angle = 0;
float speed = 0.1;
void DrawFloor(){
glVertex3d(1, 0, 2.5);
glVertex3d(1, 0, 0);
glVertex3d(-1, 0, 0);
glVertex3d(-1, 0, 2.5);
}
void DrawWall(float x, float width, float height){
glVertex3f(x, height, 0);
glVertex3f(x, height, width);
glVertex3f(x, 0, width);
glVertex3f(x, 0, 0);
}
void DrawLine(){
glVertex3f(0, 0.1, -1);
glVertex3f(0, 0.1, 1);
}
void KeyPressed(int key, int x, int y){
switch (key) {
case GLUT_KEY_UP: {
//pos_x = speed * cos(3.14*angle/180);
//pos_z = speed * sin(3.14*angle/180);
pos_z+=0.1;
break;
}
case GLUT_KEY_DOWN: {
pos_x = speed*cos(angle);
pos_z = speed*sin(angle);
break;
}
case GLUT_KEY_LEFT: {
angle += 1;
pos_x = speed * cos(3.14 * angle/180);
pos_z = speed * sin(3.14 * angle/180);
break;
}
case GLUT_KEY_RIGHT: {
angle -= 3;
pos_x = speed * cos(3.14 * angle/180);
pos_z = speed * sin(3.14 * angle/180);
break;
}
}
std::cout<<"x: "<<pos_x<<'\t';
std::cout<<"z: "<<pos_z<<'\n';
glutPostRedisplay();
}
void display(){
glClearColor(0.6, 0.8, 1, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluLookAt(pos_x, 0, pos_z, pos_x, 0, pos_z+0.2, 0, 1, 0);
glBegin(GL_QUADS);
glColor3f(0, 0, 0.7);
DrawFloor();
glColor3f(0, 0.8, 0.1);
DrawWall(-0.5, 2, 0.7);
DrawWall(0.5, 2, 0.7);
glEnd();
glLineWidth(2);
glColor3f(0.7, 0.2, 0.2);
glBegin(GL_LINES);
DrawLine();
glEnd();
glutSwapBuffers();
}
void Idle(){
//pos_z+=0.01;
//glutPostRedisplay();
}
You're using the fixed function stack, so you'll have to learn what glMatrixMode does and how transformation matrices are managed in those old ways.
Anyway, consider this a possible implementation of glMatrixMode
void glMatrixMode(GLenum m)
{
switch(m){
case GL_MODELVIEW: ctx->M = &ctx->matrix_modelview; break;
case GL_PROJECTION: ctx->M = &ctx->matrix_projection; break;
case GL_TEXTURE: ctx->M = &ctx->matrix_texture; break;
case GL_COLOR: ctx->M = &ctx->matrix_color; break;
}
}
On other words, there's a (context) global matrix selected with glMatrixMode, that's subsequently used for all folloing matrix manipulations.
Hence, glMatrixMode is not some form of initialization, but something you use to switch (often several times) during rendering a frame! Your use of it in the main function is kind of pointless. You must use it in your drawing function.
Furthermore, every matrix manipulation multiplies on top, of what's currently in ctx->M. gluLookAt is normally used with a identity matrix. If you don't reset you identity, that gluLookAt will work relative to the look-at done previously. So what you want is this:
void display(){
glClearColor(0.6, 0.8, 1., 1.); /* <<<----* */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTIOM);
glLoadIdentity();
setup_projection_here();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(pos_x, 0, pos_z, pos_x, 0, pos_z+0.2, 0, 1, 0);
glBegin(GL_QUADS);
/* ... */
glutSwapBuffers();
}
(*) Also you normally want to clear to alpha = 1 on the main framebuffer, unless you're planning on drawing window-translucent imagery. With alpha = 0 things might look correct in the window, but if a screenshot is taken, or some screen recording or sharing is used, it may cause undesired transparence.
#include <stdio.h> // this library is for standard input and output
#include "glut.h"// this library is for glut the OpenGL Utility Toolkit
#include <math.h>
float squareX = 0.0f;
float squareY = -0.3f;
float squareZ = 0.0f;
static int flag = 1;
void drawShape(void) {
glTranslatef(squareX, squareY, squareZ);
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(162, 50);
glVertex2f(162, 10);
glVertex2f(220, 10);
glVertex2f(220, 50);
glVertex2f(162, 50);
glEnd();
}
void initRendering() {
glEnable(GL_DEPTH_TEST);
}
// called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, (float)w, 0.0f, (float)h, -1.0f, 1.0f);
}
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawShape();
glutSwapBuffers();
}
// make the square go up
void update(int value) {
if (flag) {
squareY += 1.0f;
if (squareY > 400.0) {
flag = 0;
}
}
glutPostRedisplay();
glutTimerFunc(25, update, 0);
}
// make the square go right
/* void update(int value) {
if (flag) {
squareX += 1.0f;
if (squareX > 400.0) {
flag = 0;
}
}
glutPostRedisplay();
glutTimerFunc(25, update, 0);
} */
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
glutCreateWindow("Moving Square");
initRendering();
glutDisplayFunc(drawScene);
glutReshapeFunc(handleResize);
glutTimerFunc(25, update, 0);
glutMainLoop();
return(0);
}
I have uploaded this code before but this time I made the square go all the way up. The code just moves the square up, but I don't know how to position it on the left once it reaches the top, so then I can make it move to the right. I have uploaded a demonstration on how I want it to look below.
Preview:
What I want it to do next:
I recommend to initialize the variables squareX, squareY and squareZ with the start position of the rectangle:
float squareX = 162.0f;
float squareY = 0.0f;
float squareZ = 0.0f;
Do not draw a rectangle specific position, but draw a rectangle on the position (0,0) with a length (width, height). Let the model matrix (set by glTranslatef), do the job of the positioning:
void drawShape(void)
{
float width = 58.0f;
float height = 40.0f;
glTranslatef(squareX, squareY, squareZ);
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(0, 0);
glVertex2f(width, 0);
glVertex2f(width, height);
glVertex2f(0, height);
glVertex2f(0, 0);
glEnd();
}
Use a variable state, which has stated the direction of the current movement:
int state = 1; // 0: stop; 1: move up; 2: move right
If the rectangle a certain position has reached, then the state has to be changed and a the new start position can be set. At the final position, the rectangle can stop or the process can even be restarted:
void update(int value)
{
if (state == 1) // 1 : move up
{
squareY += 1.0f;
if (squareY > 400.0)
{
state = 2;
squareX = 0.0f;
squareY = 180.0f;
}
}
else if (state == 2) // 2 : move right
{
squareX += 1.0f;
if (squareX > 400.0)
{
state = 0;
// restart
//state = 1;
//squareX = 162.0f;
//squareY = 0.0f;
}
}
glutPostRedisplay();
glutTimerFunc(25, update, 0);
}
I'm using OpenGl to animate a graph that looks something like this:
Here's the code I've got so far:
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0,1,0); //Green
// Frequency Line
glLineWidth(3.0);
glBegin(GL_LINE_STRIP);
glVertex2f(-1,0);
glVertex2f(x1,y1);
glEnd();
y1 = randVarGen();
x1 = randVarGen();
and I have a timer to redraw the graph every 50 ms. I want to start with a straight line and based on variables from an audio file(I'm using random variables for now), the graph should go up and down sort of like a music visualizer.
You need to sample the function you want to plot.
glBegin(GL_LINE_STRIP);
glVertex2f(0f, 0f);
for (float x = 1f; x < 100f; x += 1f)
glVertex2f(x, randVarGen());
glVertex2f(100f, 0f);
glEnd();
Wikibooks OpenGL tutorial example
Tested on Ubuntu 16.04.
https://en.wikibooks.org/wiki/OpenGL_Programming/Scientific_OpenGL_Tutorial_01
https://gitlab.com/wikibooks-opengl/modern-tutorials/tree/2d8a441d8db81b4a619cf583769d1ea1451f4529/graph01
The key files of that repo are:
graph.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include "../common/shader_utils.h"
#include "res_texture.c"
GLuint program;
GLint attribute_coord2d;
GLint uniform_offset_x;
GLint uniform_scale_x;
GLint uniform_sprite;
GLuint texture_id;
GLint uniform_mytexture;
float offset_x = 0.0;
float scale_x = 1.0;
int mode = 0;
struct point {
GLfloat x;
GLfloat y;
};
GLuint vbo;
int init_resources() {
program = create_program("graph.v.glsl", "graph.f.glsl");
if (program == 0)
return 0;
attribute_coord2d = get_attrib(program, "coord2d");
uniform_offset_x = get_uniform(program, "offset_x");
uniform_scale_x = get_uniform(program, "scale_x");
uniform_sprite = get_uniform(program, "sprite");
uniform_mytexture = get_uniform(program, "mytexture");
if (attribute_coord2d == -1 || uniform_offset_x == -1 || uniform_scale_x == -1 || uniform_sprite == -1 || uniform_mytexture == -1)
return 0;
/* Enable blending */
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* Enable point sprites (not necessary for true OpenGL ES 2.0) */
#ifndef GL_ES_VERSION_2_0
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
/* Upload the texture for our point sprites */
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res_texture.width, res_texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, res_texture.pixel_data);
// Create the vertex buffer object
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// Create our own temporary buffer
point graph[2000];
// Fill it in just like an array
for (int i = 0; i < 2000; i++) {
float x = (i - 1000.0) / 100.0;
graph[i].x = x;
graph[i].y = sin(x * 10.0) / (1.0 + x * x);
}
// Tell OpenGL to copy our array to the buffer object
glBufferData(GL_ARRAY_BUFFER, sizeof graph, graph, GL_STATIC_DRAW);
return 1;
}
void display() {
glUseProgram(program);
glUniform1i(uniform_mytexture, 0);
glUniform1f(uniform_offset_x, offset_x);
glUniform1f(uniform_scale_x, scale_x);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
/* Draw using the vertices in our vertex buffer object */
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(attribute_coord2d);
glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, 0);
/* Push each element in buffer_vertices to the vertex shader */
switch (mode) {
case 0:
glUniform1f(uniform_sprite, 0);
glDrawArrays(GL_LINE_STRIP, 0, 2000);
break;
case 1:
glUniform1f(uniform_sprite, 1);
glDrawArrays(GL_POINTS, 0, 2000);
break;
case 2:
glUniform1f(uniform_sprite, res_texture.width);
glDrawArrays(GL_POINTS, 0, 2000);
break;
}
glutSwapBuffers();
}
void special(int key, int x, int y) {
switch (key) {
case GLUT_KEY_F1:
mode = 0;
printf("Now drawing using lines.\n");
break;
case GLUT_KEY_F2:
mode = 1;
printf("Now drawing using points.\n");
break;
case GLUT_KEY_F3:
mode = 2;
printf("Now drawing using point sprites.\n");
break;
case GLUT_KEY_LEFT:
offset_x -= 0.1;
break;
case GLUT_KEY_RIGHT:
offset_x += 0.1;
break;
case GLUT_KEY_UP:
scale_x *= 1.5;
break;
case GLUT_KEY_DOWN:
scale_x /= 1.5;
break;
case GLUT_KEY_HOME:
offset_x = 0.0;
scale_x = 1.0;
break;
}
glutPostRedisplay();
}
void free_resources() {
glDeleteProgram(program);
}
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(640, 480);
glutCreateWindow("My Graph");
GLenum glew_status = glewInit();
if (GLEW_OK != glew_status) {
fprintf(stderr, "Error: %s\n", glewGetErrorString(glew_status));
return 1;
}
if (!GLEW_VERSION_2_0) {
fprintf(stderr, "No support for OpenGL 2.0 found\n");
return 1;
}
GLfloat range[2];
glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, range);
if (range[1] < res_texture.width)
fprintf(stderr, "WARNING: point sprite range (%f, %f) too small\n", range[0], range[1]);
printf("Use left/right to move horizontally.\n");
printf("Use up/down to change the horizontal scale.\n");
printf("Press home to reset the position and scale.\n");
printf("Press F1 to draw lines.\n");
printf("Press F2 to draw points.\n");
printf("Press F3 to draw point sprites.\n");
if (init_resources()) {
glutDisplayFunc(display);
glutSpecialFunc(special);
glutMainLoop();
}
free_resources();
return 0;
}
graph.f.glsl
uniform sampler2D mytexture;
varying vec4 f_color;
uniform float sprite;
void main(void) {
if (sprite > 1.0)
gl_FragColor = texture2D(mytexture, gl_PointCoord) * f_color;
else
gl_FragColor = f_color;
}
graph.v.glsl
attribute vec2 coord2d;
varying vec4 f_color;
uniform float offset_x;
uniform float scale_x;
uniform lowp float sprite;
void main(void) {
gl_Position = vec4((coord2d.x + offset_x) * scale_x, coord2d.y, 0, 1);
f_color = vec4(coord2d.xy / 2.0 + 0.5, 1, 1);
gl_PointSize = max(1.0, sprite);
}
I am a beginner at using openGL.
I have used a program which I found over the internet to draw a cube on the screen and translate, scale and rotate it according to certain keyboard strokes.
Bellow, I have attached the code for doing this:
#define RADDEG 57.29577951f
float XUP[3] = {1,0,0}, XUN[3] = {-1, 0, 0},
YUP[3] = {0,1,0}, YUN[3] = { 0,-1, 0},
ZUP[3] = {0,0,1}, ZUN[3] = { 0, 0,-1},
ORG[3] = {0,0,0};
GLfloat viewangle = 0, tippangle = 0, traj[120][3];
GLfloat d[3] = {0.1, 0.1, 0.1};
GLfloat xAngle = 0.0, yAngle = 0.0, zAngle = 0.0;
GLfloat scaleF = 0.2;
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
// Use arrow keys to rotate entire scene !!!
void Special_Keys (int key, int x, int y)
{
switch (key) {
case GLUT_KEY_LEFT : viewangle -= 5; break;
case GLUT_KEY_RIGHT: viewangle += 5; break;
case GLUT_KEY_UP : tippangle -= 5; break;
case GLUT_KEY_DOWN : tippangle += 5; break;
default: printf (" Special key %c == %d\n", key, key);
}
glutPostRedisplay();
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
void Keyboard (unsigned char key, int x, int y)
{
switch (key) {
case 'j' : d[0] += 0.1; break;
case 'k' : d[0] -= 0.1; break;
case 'n' : d[1] += 0.1; break;
case 'm' : d[1] -= 0.1; break;
//case 'l' : d[2] += 0.1; break;
case 'z' : xAngle += 5; break;
case 'x' : yAngle += 5; break;
case 'c' : zAngle += 5; break;
case 'q' : scaleF += 0.1; break;
case 'w' : scaleF -= 0.1; break;
default: cout<< "Redo a valid keystroke;"<<endl;
}
glutPostRedisplay();
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
void Triad (void)
{
glColor3f (1.0, 1.0, 1.0);
glBegin (GL_LINES);
glVertex3fv (ORG); glVertex3fv (XUP);
glVertex3fv (ORG); glVertex3fv (YUP);
glVertex3fv (ORG); glVertex3fv (ZUP);
glEnd ();
glRasterPos3f (1.1, 0.0, 0.0);
glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, 'X');
glRasterPos3f (0.0, 1.1, 0.0);
glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, 'Y');
glRasterPos3f (0.0, 0.0, 1.1);
glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, 'Z');
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
void Draw_Box (void)
{
glBegin (GL_QUADS);
glColor3f(1,0,0);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
glVertex3f(-1,-1,1);
glVertex3f(1,-1,1);
glColor3f(0,1,1);
glVertex3f(1,1,-1);
glVertex3f(-1,1,-1);
glVertex3f(-1,-1,-1);
glVertex3f(1,-1,-1);
glColor3f(0,1,0);
glVertex3f(1,1,1);
glVertex3f(1,-1,1);
glVertex3f(1,-1,-1);
glVertex3f(1,1,-1);
glColor3f(1,0,1);
glVertex3f(-1,1,1);
glVertex3f(-1,-1,1);
glVertex3f(-1,-1,-1);
glVertex3f(-1,1,-1);
glColor3f(0,0,1);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
glVertex3f(-1,1,-1);
glVertex3f(1,1,-1);
glColor3f(1,1,0);
glVertex3f(1,-1,1);
glVertex3f(-1,-1,1);
glVertex3f(-1,-1,-1);
glVertex3f(1,-1,-1);
glEnd();
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
void redraw (void)
{
int v;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable (GL_DEPTH_TEST);
glLoadIdentity ();
glTranslatef (0, 0, -3);
glRotatef (tippangle, 1,0,0); // Up and down arrow keys 'tip' view.
glRotatef (viewangle, 0,1,0); // Right/left arrow keys 'turn' view.
glDisable (GL_LIGHTING);
Triad ();
glPushMatrix ();
glTranslatef (d[0], d[1], d[2]); // Move box down X axis.
glScalef (scaleF, scaleF, scaleF);
glRotatef (zAngle, 0,0,1);
glRotatef (yAngle, 0,1,0);
glRotatef (xAngle, 1,0,0);
Draw_Box ();
glPopMatrix ();
glutSwapBuffers();
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
void wait ( int seconds )
{
clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC ;
while (clock() < endwait) {}
}
int main (int argc, char **argv)
{
glutInit (&argc, argv);
glutInitWindowSize (900, 600);
glutInitWindowPosition (300, 300);
glutInitDisplayMode (GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow ("Orbital Font Demo");
glutDisplayFunc ( redraw );
glutKeyboardFunc ( Keyboard );
//glutSpecialFunc (Special_Keys);
glClearColor (0.1, 0.0, 0.1, 1.0);
glMatrixMode (GL_PROJECTION);
gluPerspective (60, 1.5, 1, 10);
glMatrixMode (GL_MODELVIEW);
glutPostRedisplay();
glutMainLoop ();
return 1;
}
//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
The thing is that I want to copy this code into another C++ program where I am using openCV libraries to connect my VGA camera. Based on the movements performed in front of the camera, I am classifying the performed movements using a SVM model.
I want to use the output of the SVM model which is basically a integer value and pass it to the openGL code in order to move the cube in the window.
In the above mentioned code, this procedure is performed by using keystrokes, and implicitly the glKeyboardFunc function. What functions should I use in order to connect the output of the SVM model to the redraw function of the above mentioned code?
You should use glutIdle to check whether there is a new frame. If there is you should update textures with new image using glTexSubImage2D*.
*You should use a texture to display a custom image.
//
// This code was created by Lionel Brits / Jeff Molofee '99
//
// If you've found this code useful, please let me know.
//
// Visit NeHe Productions at www.demonews.com/hosted/nehe
//
/**************************************************************/
// This code was ported to MacOS by Tony Parker.
// I'd also appreciate it if you could drop me a line if you found
// this code useful.
//
// Tony Parker - asp#usc.edu
//
// Have a nice day.
#include <stdio.h> // Header File For Standard Input / Output
#include <stdarg.h> // Header File For Variable Argument Routines
#include <string.h> // Header File For String Management
#include <stdlib.h>
#include <stdbool.h>
#include <OpenGL/gl.h> // Header File For The OpenGL32 Library
#include <OpenGL/glu.h> // Header File For The GLu32 Library
#include <GLUT/glut.h> // Header File For The GLUT Library
#include "math.h"
#include "model.h"
// Constants ----------------------------------------------------------------------
#define kWindowHeight 400
#define kWindowWidth 400
// Structures ----------------------------------------------------------------
typedef struct // Create A Structure
{
GLubyte *imageData; // Image Data (Up To 32 Bits)
GLuint bpp; // Image Color Depth In Bits Per Pixel.
GLuint width; // Image Width
GLuint height; // Image Height
GLuint texID; // Texture ID Used To Select A Texture
} TextureImage; // Structure Name
// Function Prototypes -------------------------------------------------------
bool LoadTGA(TextureImage *texture, char *filename);
float rad(float angle);
void readstr(FILE *f,char *string);
void SetupWorld(void);
GLvoid InitGL(GLvoid);
GLvoid DrawGLScene(GLvoid);
GLvoid ReSizeGLScene(int Width, int Height);
GLvoid Idle(GLvoid);
GLvoid LoadGLTextures(void);
GLvoid Keyboard(unsigned char key, int x, int y);
// Global Variables ----------------------------------------------------------
char *worldfile = "world.txt";
bool light; // Lighting ON/OFF
bool gBlend; // Blending ON/OFF
GLfloat xrot; // X Rotation
GLfloat yrot; // Y Rotation
GLfloat xspeed; // X Rotation Speed
GLfloat yspeed; // Y Rotation Speed
GLfloat walkbias = 0;
GLfloat walkbiasangle = 0;
GLfloat lookupdown = 0.0f;
const float piover180 = 0.0174532925f;
float heading, xpos, zpos;
GLfloat camx=0, camy=0, camz=0; // Camera Location
GLfloat therotate;
GLfloat z=0.0f; // Depth Into The Screen
GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f }; // Ambient Light
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // Diffuse Light
GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f }; // Light Position
GLuint filter; // Which Filter To Use
TextureImage texture[3]; // Storage for 3 textures
// Our Model Goes Here:
SECTOR sector1;
// rad -----------------------------------------------------------------------
// Converts Degrees To Radians. There Are 2 PI Radians In 360 Degrees.
float rad(float angle)
{
return angle * piover180;
}
// readstr -------------------------------------------------------------------
void readstr(FILE *f,char *string)
{
do
{
fgets(string, 255, f);
} while ((string[0] == '/') || (string[0] == '\n'));
return;
}
// SetupWorld ----------------------------------------------------------------
void SetupWorld(void)
{
float x, y, z, u, v;
int numtriangles;
FILE *filein;
char oneline[255];
filein = fopen(worldfile, "rt");
readstr(filein,oneline);
sscanf(oneline, "NUMPOLLIES %d\n", &numtriangles);
sector1.triangle = new TRIANGLE[numtriangles];
sector1.numtriangles = numtriangles;
int loop;
for ( loop = 0; loop < numtriangles; loop++)
{
int vert;
for ( vert = 0; vert < 3; vert++)
{
readstr(filein,oneline);
sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v);
sector1.triangle[loop].vertex[vert].x = x;
sector1.triangle[loop].vertex[vert].y = y;
sector1.triangle[loop].vertex[vert].z = z;
sector1.triangle[loop].vertex[vert].u = u;
sector1.triangle[loop].vertex[vert].v = v;
}
}
fclose(filein);
return;
}
#pragma mark -
// Main ----------------------------------------------------------------------
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(kWindowWidth, kWindowHeight);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
SetupWorld();
InitGL();
glutDisplayFunc(DrawGLScene);
glutReshapeFunc(ReSizeGLScene);
glutKeyboardFunc(Keyboard);
glutMainLoop();
return 0;
}
// InitGL ---------------------------------------------------------------------
GLvoid InitGL(GLvoid)
{
LoadGLTextures(); // Load The Texture ( ADD )
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( ADD )
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
gluPerspective(45.0f, (GLfloat) kWindowWidth / (GLfloat) kWindowHeight, 0.1f, 100.0f);
// Calculate The Aspect Ratio Of The Window
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);
glEnable(GL_LIGHT1);
}
// Idle ---------------------------------------------------------------------
GLvoid Idle(GLvoid)
{
glutPostRedisplay();
}
// Keyboard -----------------------------------------------------------------
void Keyboard(unsigned char key, int x, int y)
{
#pragma unused (x, y)
switch(key)
{
case 'b': // turn blending on/off
gBlend = !gBlend;
if (!gBlend)
{
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
}
else
{
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
}
break;
case 'f':
filter+=1;
if (filter > 2)
{
filter = 0;
}
break;
case 'l':
light = !light;
if (!light)
glDisable(GL_LIGHTING);
else
glEnable(GL_LIGHTING);
break;
case 'w': // walk forward
xpos -= (float)sin(heading*piover180) * 0.05f;
zpos -= (float)cos(heading*piover180) * 0.05f;
if (walkbiasangle >= 359.0f)
walkbiasangle = 0.0f;
else
walkbiasangle+= 10;
walkbias = (float)sin(walkbiasangle * piover180)/20.0f;
//lookupdown -= 1.0f;
break;
case 'x': // walk back
xpos += (float)sin(heading*piover180) * 0.05f;
zpos += (float)cos(heading*piover180) * 0.05f;
if (walkbiasangle <= 1.0f)
walkbiasangle = 359.0f;
else
walkbiasangle-= 10;
walkbias = (float)sin(walkbiasangle * piover180)/20.0f;
//lookupdown += 1.0f;
break;
case 'd': // turn right
heading -= 1.0f;
yrot = heading;
break;
case 'a': // turn left
heading += 1.0f;
yrot = heading;
break;
case 'q':
z += 0.02f;
break;
case 'z':
z += 0.02f;
break;
default:
break;
}
glutPostRedisplay();
}
// DrawGLScene -------------------------------------------------------------
GLvoid DrawGLScene(GLvoid)
{
GLfloat x_m, y_m, z_m, u_m, v_m;
GLfloat xtrans, ztrans, ytrans;
GLfloat sceneroty;
xtrans = -xpos;
ztrans = -zpos;
ytrans = -walkbias-0.25f;
sceneroty = 360.0f- yrot;
int numtriangles;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glRotatef(lookupdown,1.0f,0,0);
glRotatef(sceneroty,0,1.0f,0);
glTranslatef(xtrans, ytrans, ztrans);
glBindTexture(GL_TEXTURE_2D, texture[filter].texID);
numtriangles = sector1.numtriangles;
// Process Each Triangle
int loop_m;
for ( loop_m = 0; loop_m < numtriangles; loop_m++)
{
glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
x_m = sector1.triangle[loop_m].vertex[0].x;
y_m = sector1.triangle[loop_m].vertex[0].y;
z_m = sector1.triangle[loop_m].vertex[0].z;
u_m = sector1.triangle[loop_m].vertex[0].u;
v_m = sector1.triangle[loop_m].vertex[0].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
x_m = sector1.triangle[loop_m].vertex[1].x;
y_m = sector1.triangle[loop_m].vertex[1].y;
z_m = sector1.triangle[loop_m].vertex[1].z;
u_m = sector1.triangle[loop_m].vertex[1].u;
v_m = sector1.triangle[loop_m].vertex[1].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
x_m = sector1.triangle[loop_m].vertex[2].x;
y_m = sector1.triangle[loop_m].vertex[2].y;
z_m = sector1.triangle[loop_m].vertex[2].z;
u_m = sector1.triangle[loop_m].vertex[2].u;
v_m = sector1.triangle[loop_m].vertex[2].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
glEnd();
}
glutSwapBuffers();
glFlush();
}
// ReSizeGLScene ------------------------------------------------------------
GLvoid ReSizeGLScene(int Width, int Height)
{
glViewport (0, 0, (GLsizei) Width, (GLsizei) Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat) Width / (GLfloat) Height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// LoadGLTextures ------------------------------------------------------------
GLvoid LoadGLTextures(GLvoid)
{
//load texture
LoadTGA(&texture[0], "mud.tga");
LoadTGA(&texture[1], "mud.tga");
LoadTGA(&texture[2], "mud.tga");
// Create Nearest Filtered Texture
glBindTexture(GL_TEXTURE_2D, texture[0].texID);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
//glTexImage2D(GL_TEXTURE_2D, 0, 3, texture1->sizeX, texture1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture1->data);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture[0].width, texture[0].height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[0].imageData);
// Create Linear Filtered Texture
glBindTexture(GL_TEXTURE_2D, texture[1].texID);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
//glTexImage2D(GL_TEXTURE_2D, 0, 3, texture1->sizeX, texture1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture1->data);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture[1].width, texture[1].height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[1].imageData);
// Create MipMapped Texture
glBindTexture(GL_TEXTURE_2D, texture[2].texID);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texture[2].width, texture[2].height, GL_RGB, GL_UNSIGNED_BYTE, texture[2].imageData);
}
/********************> LoadTGA() <*****/
bool LoadTGA(TextureImage *texture, char *filename) // Loads A TGA File Into Memory
{
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header
GLubyte TGAcompare[12]; // Used To Compare TGA Header
GLubyte header[6]; // First 6 Useful Bytes From The Header
GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File
GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram
GLuint temp; // Temporary Variable
GLuint type=GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP)
FILE *file = fopen(filename, "rb"); // Open The TGA File
if( file==NULL || // Does File Even Exist?
fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || // Are There 12 Bytes To Read?
memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || // Does The Header Match What We Want?
fread(header,1,sizeof(header),file)!=sizeof(header)) // If So Read Next 6 Header Bytes
{
fclose(file); // If Anything Failed, Close The File
return false; // Return False
}
texture->width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte)
texture->height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte)
if( texture->width <=0 || // Is The Width Less Than Or Equal To Zero
texture->height <=0 || // Is The Height Less Than Or Equal To Zero
(header[4]!=24 && header[4]!=32)) // Is The TGA 24 or 32 Bit?
{
fclose(file); // If Anything Failed, Close The File
return false; // Return False
}
texture->bpp = header[4]; // Grab The TGA's Bits Per Pixel (24 or 32)
bytesPerPixel = texture->bpp/8; // Divide By 8 To Get The Bytes Per Pixel
imageSize = texture->width*texture->height*bytesPerPixel; // Calculate The Memory Required For The TGA Data
texture->imageData=(GLubyte *)malloc(imageSize); // Reserve Memory To Hold The TGA Data
if( texture->imageData==NULL || // Does The Storage Memory Exist?
fread(texture->imageData, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved?
{
if(texture->imageData!=NULL) // Was Image Data Loaded
free(texture->imageData); // If So, Release The Image Data
fclose(file); // Close The File
return false; // Return False
}
GLuint i;
for( i=0; i<imageSize; i= i + bytesPerPixel) // Loop Through The Image Data
{ // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
temp=texture->imageData[i]; // Temporarily Store The Value At Image Data 'i'
texture->imageData[i] = texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte
texture->imageData[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
}
fclose (file); // Close The File
if (texture[0].bpp==24) // Was The TGA 24 Bits
{
type=GL_RGB; // If So Set The 'type' To GL_RGB
}
// Build A Texture From The Data
// We're doing this in a different function in this tutorial
glGenTextures(1, &texture[0].texID); // Generate OpenGL texture IDs
/*
glBindTexture(GL_TEXTURE_2D, texture[0].texID); // Bind Our Texture
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered
glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);
*/
return true; // Texture Building Went Ok, Return True
}
NEED HELP.
I got this error:
/Users//Desktop/XcodeGLUT/../gora.cs.illinois.edu:display:cs418sp11:Home/Lesson
10 Folder/main.c:126:0
/Users//Desktop/XcodeGLUT/../gora.cs.illinois.edu:display:cs418sp11:Home/Lesson
10 Folder/main.c:126: error: 'new'
undeclared (first use in this
function)
rename the file to main.cpp, seems the file is compiled using the c-compiler and not the C++ compiler where new is a keyword for allocating on the heap (instead of malloc/calloc)