Tutorial
13 :
Objek Kompleks
Dalam latihan ke 13
ini kita akan membuat ilustrasi tentang bagaimana kita membaca file model 3D
dan menggunakannya dalam program berbasis openGL dan GLUT. Pertama file dalam world
.txt yang kita buat sendiri. dan disetiap bagian diberi gambar texture, sama
dengan langkah sebelumnya (Pada Tutorial ke 1) buat sebuah Project dengan nama
Tutor13 dan di tambah File : Tutor13.cpp, yang kita butuhkan kemudian anda
ketikan Source Code dibawah ini
#include <windows.h>
#include <math.h>
// Math Library Header File
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <GL/glut.h>
#include <GL/glaux.h>
const float
piover180 = 0.0174532925f;
float heading;
float xpos;
float zpos;
GLfloat yrot; // Y Rotation
GLfloat walkbias = 0;
GLfloat walkbiasangle = 0;
GLfloat lookupdown = 0.0f;
GLfloat z=0.0f; // Depth Into The Screen
GLuint filter; // Which Filter To Use
GLuint texture[3]; // Storage For 3 Textures
typedef struct
tagVERTEX
{
float x, y, z;
float u, v;
} VERTEX;
typedef struct
tagTRIANGLE
{
VERTEX
vertex[3];
} TRIANGLE;
typedef struct
tagSECTOR
{
int numtriangles;
TRIANGLE*
triangle;
} SECTOR;
SECTOR sector1; // Our Model Goes Here:
void readstr(FILE *f,char *string)
{
do
{
fgets(string,
255, f);
}
while ((string[0] == '/')
|| (string[0] == '\n'));
return;
}
void SetupWorld()
{
float x, y, z, u, v;
int numtriangles;
FILE
*filein;
char oneline[255];
filein
= fopen("Data/World.txt", "rt"); // File
To Load World Data From
readstr(filein,oneline);
sscanf(oneline,
"NUMPOLLIES %d\n",
&numtriangles);
sector1.triangle
= new TRIANGLE[numtriangles];
sector1.numtriangles
= numtriangles;
for (int loop = 0;
loop < numtriangles; loop++)
{
for (int 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;
}
AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A
Bitmap Image
{
FILE
*File=NULL; // File Handle
if (!Filename) // Make Sure
A Filename Was Given
{
return NULL; // If Not
Return NULL
}
File=fopen(Filename,"r"); // Check
To See If The File Exists
if (File) // Does The File
Exist?
{
fclose(File);
// Close The Handle
return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer
}
return NULL; // If Load
Failed Return NULL
}
int LoadGLTextures() // Load Bitmaps And Convert To Textures
{
int Status=FALSE; // Status
Indicator
AUX_RGBImageRec
*TextureImage[1]; // Create Storage Space For The
Texture
memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL
// Load The Bitmap, Check For Errors, If Bitmap's Not Found
Quit
if (TextureImage[0]=LoadBMP("Data/Mud.bmp"))
{
Status=TRUE;
// Set The Status To TRUE
glGenTextures(3,
&texture[0]); // Create Three Textures
// Create Nearest Filtered Texture
glBindTexture(GL_TEXTURE_2D,
texture[0]);
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, TextureImage[0]->sizeX,
TextureImage[0]->sizeY,
0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
// Create Linear Filtered Texture
glBindTexture(GL_TEXTURE_2D,
texture[1]);
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, TextureImage[0]->sizeX,
TextureImage[0]->sizeY,
0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
// Create MipMapped Texture
glBindTexture(GL_TEXTURE_2D,
texture[2]);
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, TextureImage[0]->sizeX,
TextureImage[0]->sizeY,
GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
}
if (TextureImage[0]) // If
Texture Exists
{
if (TextureImage[0]->data) // If Texture Image Exists
{
free(TextureImage[0]->data);
// Free The Texture Image Memory
}
free(TextureImage[0]);
// Free The Image Structure
}
return Status; // Return
The Status
}
void resize(int width, int
height) // Resize And Initialize The GL Window
{
if (height==0)
// Prevent A Divide By Zero By
{
height=1;
// Making Height Equal One
}
glViewport(0,0,width,height);
// Reset The Current Viewport
glMatrixMode(GL_PROJECTION);
// Select The Projection Matrix
glLoadIdentity();
//Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
//Select The Modelview Matrix
glLoadIdentity();
//Reset The Modelview Matrix
}
void init() // All Setup For OpenGL Goes Here
{
if (!LoadGLTextures()) //Jump
To Texture Loading Routine
{
return; //If Texture Didn't
Load Return FALSE
}
glEnable(GL_TEXTURE_2D);
//Enable Texture Mapping
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
// Set The Blending Function For Translucency
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
glDepthFunc(GL_LESS);
//The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST);
//Enables Depth Testing
glShadeModel(GL_SMOOTH);
//Enables Smooth Color Shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT,
GL_NICEST); // Really Nice Perspective Calculations
SetupWorld();
return; //Initialization
Went OK
}
void myTimeOut(int id)
{
// called if timer event
// ...advance the state of animation incrementally...
//rot+=1;
glutPostRedisplay();
// request redisplay
glutTimerFunc(100,
myTimeOut, 0); // request next timer event
}
void myKeyboard(unsigned char key,int x, int y)
{
}
void mySpecialKeyboard(int key,int x, int y)
{
if(key==GLUT_KEY_UP)
{
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;
}
else if(key==GLUT_KEY_DOWN)
{
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;
}
else if(key==GLUT_KEY_RIGHT)
{
heading
-= 1.0f;
yrot
= heading;
}
else if(key==GLUT_KEY_LEFT)
{
heading
+= 1.0f;
yrot
= heading;
}
else if(key==GLUT_KEY_PAGE_UP)
{
z-=0.02f;
lookupdown-=
1.0f;
}
else if(key==GLUT_KEY_PAGE_DOWN)
{
z+=0.02f;
lookupdown+=
1.0f;
}
}
void mydisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT); // Clear The Screen And The
Depth Buffer
glLoadIdentity();
//Reset The View
GLfloat
x_m, y_m, z_m, u_m, v_m;
GLfloat
xtrans = -xpos;
GLfloat
ztrans = -zpos;
GLfloat
ytrans = -walkbias-0.25f;
GLfloat
sceneroty = 360.0f - yrot;
int numtriangles;
glRotatef(lookupdown,1.0f,0,0);
glRotatef(sceneroty,0,1.0f,0);
glTranslatef(xtrans,
ytrans, ztrans);
glBindTexture(GL_TEXTURE_2D,
texture[filter]);
numtriangles
= sector1.numtriangles;
// Process Each Triangle
for (int 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();
}
glFlush();
glutSwapBuffers();
}
int main(int argc, char**
argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(
GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("simple");
// callbacks
glutDisplayFunc(mydisplay);
glutKeyboardFunc(myKeyboard);
glutSpecialFunc(mySpecialKeyboard);
glutTimerFunc(100,
myTimeOut, 0);
glutReshapeFunc(resize);
init();
glutMainLoop();
return 0;
}
Penjelasan
:
Apabilan program 13
kita jalankan akan membuat file model 3D dengan format kita sendiri. File
format kita adalah file World.txt yang formatnya akan berupa aturan sebagai
berikut:
-
Kita dapat memasukkan baris kosong semau
kita agar file lebih mudah dibaca
-
Kita dapat memasukkan baris komentar dengan
menambahkan “//” pada awal
baris
-
Hanya terkait dengan satu file texture
-
Primitif yang digunakan hanya GL_TRIANGLES
-
Informasi awalnya akan berupa frasa
NUMPOLLIES xx, dengan xx adalah
jumlah
primitif
-
Setelah itu kita harus memberi spesifikasi
triangle-nya dengan menuliskan daftar
vertex
perbaris dengan format baris sbb.
X Y Z S Tdengan X,Y, Z
adalah posisi vertex sedangkan S, T adalah pixel texture yang bersesuaian.Link ke File Source Tutorial 13
Tutorial
14 :
3D
rendering
Dalam latihan ke 14 ini kita akan membuat
ilustrasi tentang bagaimana kita membuat object 3 dimensi seperti pesawat.
Dimana object adalah sebuah pesawat yang bergerak, sama dengan langkah
sebelumnya (Pada Tutorial ke 1) buat sebuah Project dengan nama Tutor14 dan di
tambah File : Tutor14.cpp, di tambah dengan file bmp.h, bmp.cpp dan file :
material.h yang kita butuhkan kemudian anda ketikan Source Code dibawah ini
3dsloader.h
/**********************************************************
*
* FUNCTION Load3DS (obj_type_ptr, char *)
*
* This function loads a mesh from a 3ds file.
* Please note that we are loading only the
vertices, polygons and mapping lists.
* If you need to load meshes with advanced
features as for example:
* multi objects, materials, lights and so on,
you must insert other chunk parsers.
*
*********************************************************/
extern char
Load3DS (obj_type_ptr ogg, char *filename);
3dsloader.cpp
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <io.h>
#include "tutorial4.h"
#include "3dsloader.h"
/**********************************************************
*
* FUNCTION Load3DS (obj_type_ptr, char *)
*
* This function loads a mesh from a 3ds file.
* Please note that we are loading only the
vertices, polygons and mapping lists.
* If you need to load meshes with advanced
features as for example:
* multi objects, materials, lights and so on,
you must insert other chunk parsers.
*
*********************************************************/
char Load3DS (obj_type_ptr
p_object, char *p_filename)
{
int i; //Index
variable
FILE *l_file; //File pointer
unsigned short
l_chunk_id; //Chunk identifier
unsigned int
l_chunk_lenght; //Chunk lenght
unsigned char
l_char; //Char variable
unsigned short
l_qty; //Number of elements in each chunk
unsigned short
l_face_flags; //Flag that stores some face
information
if ((l_file=fopen (p_filename, "rb"))== NULL) return
0; //Open the file
while (ftell (l_file) < filelength
(fileno (l_file))) //Loop to scan the whole file
{
//getche(); //Insert this command for debug
(to wait for keypress for each chuck reading)
fread (&l_chunk_id, 2, 1, l_file); //Read
the chunk header
printf("ChunkID: %x\n",l_chunk_id);
fread (&l_chunk_lenght, 4, 1, l_file); //Read
the lenght of the chunk
printf("ChunkLenght: %x\n",l_chunk_lenght);
switch (l_chunk_id)
{
//-----------------
MAIN3DS -----------------
// Description:
Main chunk, contains all the other chunks
// Chunk ID:
4d4d
// Chunk Lenght: 0 + sub chunks
//-------------------------------------------
case
0x4d4d:
break;
//-----------------
EDIT3DS -----------------
// Description:
3D Editor chunk, objects layout info
// Chunk ID: 3d3d
(hex)
// Chunk
Lenght: 0 + sub chunks
//-------------------------------------------
case
0x3d3d:
break;
//---------------
EDIT_OBJECT ---------------
// Description:
Object block, info for each object
// Chunk ID:
4000 (hex)
// Chunk
Lenght: len(object name) + sub chunks
//-------------------------------------------
case
0x4000:
i=0;
do
{
fread (&l_char, 1, 1, l_file);
p_object->name[i]=l_char;
i++;
}while(l_char
!= '\0' && i<20);
break;
//---------------
OBJ_TRIMESH ---------------
// Description:
Triangular mesh, contains chunks for 3d mesh info
// Chunk ID:
4100 (hex)
// Chunk
Lenght: 0 + sub chunks
//-------------------------------------------
case
0x4100:
break;
//---------------
TRI_VERTEXL ---------------
// Description:
Vertices list
// Chunk ID:
4110 (hex)
// Chunk
Lenght: 1 x unsigned short (number of vertices)
// + 3 x float (vertex coordinates) x
(number of vertices)
// + sub chunks
//-------------------------------------------
case
0x4110:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
p_object->vertices_qty = l_qty;
printf("Number
of vertices: %d\n",l_qty);
for
(i=0; i<l_qty; i++)
{
fread (&p_object->vertex[i].x,
sizeof(float),
1, l_file);
printf("Vertices
list x: %f\n",p_object->vertex[i].x);
fread (&p_object->vertex[i].y,
sizeof(float),
1, l_file);
printf("Vertices
list y: %f\n",p_object->vertex[i].y);
fread (&p_object->vertex[i].z,
sizeof(float),
1, l_file);
printf("Vertices
list z: %f\n",p_object->vertex[i].z);
}
break;
//---------------
TRI_FACEL1 ----------------
// Description:
Polygons (faces) list
// Chunk ID:
4120 (hex)
// Chunk
Lenght: 1 x unsigned short (number of polygons)
// + 3 x unsigned short (polygon
points) x (number of polygons)
// + sub chunks
//-------------------------------------------
case
0x4120:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
p_object->polygons_qty = l_qty;
printf("Number
of polygons: %d\n",l_qty);
for
(i=0; i<l_qty; i++)
{
fread
(&p_object->polygon[i].a, sizeof (unsigned short), 1,
l_file);
printf("Polygon
point a: %d\n",p_object->polygon[i].a);
fread (&p_object->polygon[i].b, sizeof (unsigned short), 1, l_file);
printf("Polygon
point b: %d\n",p_object->polygon[i].b);
fread
(&p_object->polygon[i].c, sizeof (unsigned short), 1,
l_file);
printf("Polygon
point c: %d\n",p_object->polygon[i].c);
fread (&l_face_flags, sizeof (unsigned short), 1, l_file);
printf("Face
flags: %x\n",l_face_flags);
}
break;
//-------------
TRI_MAPPINGCOORS ------------
// Description:
Vertices list
// Chunk ID:
4140 (hex)
// Chunk
Lenght: 1 x unsigned short (number of mapping points)
// + 2 x float (mapping coordinates)
x (number of mapping points)
// + sub chunks
//-------------------------------------------
case
0x4140:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
for
(i=0; i<l_qty; i++)
{
fread
(&p_object->mapcoord[i].u, sizeof (float), 1, l_file);
printf("Mapping
list u: %f\n",p_object->mapcoord[i].u);
fread
(&p_object->mapcoord[i].v, sizeof (float), 1, l_file);
printf("Mapping
list v: %f\n",p_object->mapcoord[i].v);
}
break;
//-----------
Skip unknow chunks ------------
//We need to
skip all the chunks that currently we don't use
//We use the
chunk lenght information to set the file pointer
//to the same
level next chunk
//-------------------------------------------
default:
fseek(l_file, l_chunk_lenght-6, SEEK_CUR);
}
}
fclose (l_file); // Closes the file stream
return (1); //
Returns ok
}
Texture.h
extern int
num_texture;
extern int
LoadBitmap(char *filename);
Texture.cpp
#include <stdio.h>
#include <windows.h>
#include <GL/glut.h>
#include "texture.h"
/**********************************************************
*
* VARIABLES DECLARATION
*
*********************************************************/
int num_texture=-1; //Counter to keep track of the last loaded texture
/**********************************************************
*
* FUNCTION LoadBitmap(char *)
*
* This function loads a bitmap file and return
the OpenGL reference ID to use that texture
*
*********************************************************/
int LoadBitmap(char *filename)
{
int i, j=0; //Index
variables
FILE *l_file; //File pointer
unsigned char
*l_texture; //The pointer to the memory zone in which
we will load the texture
// windows.h gives us these types to work with
the Bitmap files
BITMAPFILEHEADER fileheader;
BITMAPINFOHEADER infoheader;
RGBTRIPLE rgb;
num_texture++; // The counter of the current
texture is increased
if( (l_file = fopen(filename, "rb"))==NULL) return
(-1); // Open the file for reading
fread(&fileheader, sizeof(fileheader),
1, l_file); // Read the fileheader
fseek(l_file, sizeof(fileheader),
SEEK_SET); // Jump the fileheader
fread(&infoheader, sizeof(infoheader),
1, l_file); // and read the infoheader
// Now we need to allocate the memory for our
image (width * height * color deep)
l_texture = (byte *) malloc(infoheader.biWidth * infoheader.biHeight *
4);
// And fill it with zeros
memset(l_texture, 0, infoheader.biWidth * infoheader.biHeight * 4);
// At this point we can read every pixel of
the image
for (i=0; i <
infoheader.biWidth*infoheader.biHeight; i++)
{
// We
load an RGB value from the file
fread(&rgb, sizeof(rgb), 1, l_file);
// And
store it
l_texture[j+0] = rgb.rgbtRed; // Red component
l_texture[j+1] = rgb.rgbtGreen; // Green component
l_texture[j+2] = rgb.rgbtBlue; // Blue component
l_texture[j+3] = 255; // Alpha value
j += 4; //
Go to the next position
}
fclose(l_file); // Closes the file stream
glBindTexture(GL_TEXTURE_2D, num_texture); //
Bind the ID texture specified by the 2nd parameter
// The next commands sets the texture
parameters
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // If the u,v coordinates overflow the range 0,1 the image
is repeated
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // The magnification function ("linear" produces
better results)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST); //The minifying function
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // We don't combine the color with the original surface color,
use only the texture map.
// Finally we define the 2d texture
glTexImage2D(GL_TEXTURE_2D, 0, 4, infoheader.biWidth,
infoheader.biHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, l_texture);
// And create 2d mipmaps for the minifying
function
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, infoheader.biWidth,
infoheader.biHeight, GL_RGBA, GL_UNSIGNED_BYTE, l_texture);
free(l_texture); // Free the memory we used to
load the texture
return (num_texture); // Returns the current texture OpenGL ID
}
Main.h
#define MAX_VERTICES 8000 // Max number of vertices (for each object)
#define MAX_POLYGONS 8000 // Max number of polygons (for each object)
// Our vertex type
typedef struct
{
float x,y,z;
} vertex_type;
// The polygon
(triangle), 3 numbers that aim 3 vertices
typedef struct
{
int a,b,c;
} polygon_type;
// The mapcoord type,
2 texture coordinates for each vertex
typedef struct
{
float u,v;
} mapcoord_type;
// The object type
typedef struct
{
char name[20];
int vertices_qty;
int polygons_qty;
vertex_type vertex[MAX_VERTICES];
polygon_type polygon[MAX_POLYGONS];
mapcoord_type mapcoord[MAX_VERTICES];
int id_texture;
} obj_type, *obj_type_ptr;
Main.cpp
#include <windows.h>
#include <GL/glut.h>
#include "tutorial4.h"
#include "texture.h"
#include "3dsloader.h"
// The width and
height of your window, change them as you like
int screen_width=640;
int screen_height=480;
// Absolute rotation
values (0-359 degrees) and rotation increments for each frame
double rotation_x=0,
rotation_x_increment=0.1;
double rotation_y=0,
rotation_y_increment=0.05;
double rotation_z=0,
rotation_z_increment=0.03;
// Flag for rendering
as lines or filled polygons
int filling=1; //0=OFF 1=ON
//Now the object is
generic, the cube has annoyed us a little bit, or not?
obj_type object;
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0); // This
clear the background color to black
glShadeModel(GL_SMOOTH); // Type of shading
for the polygons
// Viewport transformation
glViewport(0,0,screen_width,screen_height);
// Projection transformation
glMatrixMode(GL_PROJECTION); // Specifies
which matrix stack is the target for matrix operations
glLoadIdentity(); // We initialize the
projection matrix as identity
gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,10.0f,10000.0f);
// We define the "viewing volume"
glEnable(GL_DEPTH_TEST); // We enable the
depth test (also called z buffer)
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); //
Polygon rasterization mode (polygon filled)
glEnable(GL_TEXTURE_2D); // This Enable the
Texture mapping
Load3DS (&object,"spaceship.3ds");
object.id_texture=LoadBitmap("spaceshiptexture.bmp");
// The Function LoadBitmap() return the current
texture ID
// If the last function returns -1 it means
the file was not found so we exit from the program
if (object.id_texture==-1)
{
MessageBox(NULL,"Image file:
spaceshiptexture.bmp not found","Zetadeck",MB_OK
| MB_ICONERROR);
exit (0);
}
}
void resize (int width, int
height)
{
screen_width=width; // We obtain the new
screen width values and store it
screen_height=height; // Height value
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // We clear both the color and the depth buffer so to draw
the next frame
glViewport(0,0,screen_width,screen_height); //
Viewport transformation
glMatrixMode(GL_PROJECTION); // Projection
transformation
glLoadIdentity(); // We initialize the
projection matrix as identity
gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,10.0f,10000.0f);
glutPostRedisplay (); // This command redraw
the scene (it calls the same routine of glutDisplayFunc)
}
void keyboard (unsigned char key, int x, int y)
{
switch (key)
{
case ' ':
rotation_x_increment=0;
rotation_y_increment=0;
rotation_z_increment=0;
break;
case 'r':
case 'R':
if
(filling==0)
{
glPolygonMode (GL_FRONT_AND_BACK,
GL_FILL); // Polygon rasterization mode (polygon
filled)
filling=1;
}
else
{
glPolygonMode (GL_FRONT_AND_BACK,
GL_LINE); // Polygon rasterization mode (polygon
outlined)
filling=0;
}
break;
}
}
void keyboard_s (int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_UP:
rotation_x_increment = rotation_x_increment
+0.005;
break;
case GLUT_KEY_DOWN:
rotation_x_increment =
rotation_x_increment -0.005;
break;
case GLUT_KEY_LEFT:
rotation_y_increment =
rotation_y_increment +0.005;
break;
case GLUT_KEY_RIGHT:
rotation_y_increment =
rotation_y_increment -0.005;
break;
case GLUT_KEY_PAGE_UP:
rotation_z_increment =
rotation_z_increment +0.005;
break;
case GLUT_KEY_PAGE_DOWN:
rotation_z_increment =
rotation_z_increment -0.005;
break;
}
}
void display(void)
{
int l_index;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); // Modeling
transformation
glLoadIdentity(); // Initialize the model
matrix as identity
glTranslatef(0.0,0.0,-300); // We move the
object forward (the model matrix is multiplied by the translation matrix)
rotation_x = rotation_x + rotation_x_increment;
rotation_y = rotation_y + rotation_y_increment;
rotation_z = rotation_z + rotation_z_increment;
if (rotation_x > 359) rotation_x = 0;
if (rotation_y > 359) rotation_y = 0;
if (rotation_z > 359) rotation_z = 0;
glRotatef(rotation_x,1.0,0.0,0.0); //
Rotations of the object (the model matrix is multiplied by the rotation
matrices)
glRotatef(rotation_y,0.0,1.0,0.0);
glRotatef(rotation_z,0.0,0.0,1.0);
glBindTexture(GL_TEXTURE_2D, object.id_texture); // We set the active texture
glBegin(GL_TRIANGLES); // glBegin and glEnd
delimit the vertices that define a primitive (in our case triangles)
for (l_index=0;l_index<object.polygons_qty;l_index++)
{
//-----------------
FIRST VERTEX -----------------
// Texture
coordinates of the first vertex
glTexCoord2f( object.mapcoord[
object.polygon[l_index].a ].u,
object.mapcoord[ object.polygon[l_index].a
].v);
// Coordinates
of the first vertex
glVertex3f( object.vertex[
object.polygon[l_index].a ].x,
object.vertex[
object.polygon[l_index].a ].y,
object.vertex[
object.polygon[l_index].a ].z); //Vertex definition
//-----------------
SECOND VERTEX -----------------
// Texture
coordinates of the second vertex
glTexCoord2f( object.mapcoord[
object.polygon[l_index].b ].u,
object.mapcoord[
object.polygon[l_index].b ].v);
// Coordinates
of the second vertex
glVertex3f( object.vertex[
object.polygon[l_index].b ].x,
object.vertex[
object.polygon[l_index].b ].y,
object.vertex[
object.polygon[l_index].b ].z);
//-----------------
THIRD VERTEX -----------------
// Texture
coordinates of the third vertex
glTexCoord2f( object.mapcoord[
object.polygon[l_index].c ].u,
object.mapcoord[
object.polygon[l_index].c ].v);
// Coordinates
of the Third vertex
glVertex3f( object.vertex[
object.polygon[l_index].c ].x,
object.vertex[
object.polygon[l_index].c ].y,
object.vertex[
object.polygon[l_index].c ].z);
}
glEnd();
glFlush(); // This force the execution of
OpenGL commands
glutSwapBuffers(); // In double buffered mode
we invert the positions of the visible buffer and the writing buffer
}
int main(int argc, char
**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(screen_width,screen_height);
glutInitWindowPosition(0,0);
glutCreateWindow("SpaceShip dari File
3DS Simple");
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc (resize);
glutKeyboardFunc (keyboard);
glutSpecialFunc (keyboard_s);
init();
glutMainLoop();
return(0);
}
Tutorial4.h
/**********************************************************
*
* TYPES DECLARATION
*
*********************************************************/
#define MAX_VERTICES 8000 // Max number of vertices (for each object)
#define MAX_POLYGONS 8000 // Max number of polygons (for each object)
// Our vertex type
typedef struct
{
float x,y,z;
} vertex_type;
// The polygon
(triangle), 3 numbers that aim 3 vertices
typedef struct
{
int a,b,c;
} polygon_type;
// The mapcoord type,
2 texture coordinates for each vertex
typedef struct
{
float u,v;
}mapcoord_type;
// The object type
typedef struct
{
char name[20];
int vertices_qty;
int polygons_qty;
vertex_type vertex[MAX_VERTICES];
polygon_type polygon[MAX_POLYGONS];
mapcoord_type mapcoord[MAX_VERTICES];
int id_texture;
} obj_type, *obj_type_ptr;
Saat file Tutor14.cpp di jalankan akan
terjadi Error, untuk menghindari Error tersebut, tambahkan file glaux.lib pada
bagian :
Klik kanan pada Project Tutor14 anda,
kemudian pilih Properties di bagian bawah popup menu,kemudian tampil dialog
menu. Kemudian pilih Linker, pilih Input, pada bagian Properties, additional
dependencies, klik combobox, kemudian pilih <edit>, akan tampil dialog
menu, ketikan glaux.lib, pada kotak isian, kemudian klik OK, dan OK untuk
dialog terakhir.
Kemudian membutuhkan file : spaceship.3ds
dan spaceshiptexture.bmp
Apabila source code
tersebut di jalankan, akan ditampilkan gambar berikut seperti sebuah pesawat
yang sedang berputar dan bergerak ke atas ke kiri dan ke kanan.Link ke File Source Tutorial 14
Tutorial
16 :
Sistem partikel
Dalam latihan ke 16 ini kita akan membuat
ilustrasi tentang bagaimana kita membuat partikel seperti kembang api. Dimana
object seolah olah memudah menjadi besar dari kecil, sama dengan langkah
sebelumnya (Pada Tutorial ke 1) buat sebuah Project dengan nama Tutor16 dan di
tambah File : Tutor16.cpp, di tambah dengan file bmp.h, bmp.cpp dan file :
material.h yang kita butuhkan kemudian anda ketikan Source Code dibawah ini
Bmp.h
#include <GL/glaux.h>
AUX_RGBImageRec *LoadBMP(char *Filename);
Bmp.cpp
#include <windows.h>
#include <stdio.h>
// Header File For Standard Input/Output
#include <gl\gl.h>
// Header File For The OpenGL32 Library
#include <gl\glu.h>
// Header File For The GLu32 Library
#include <gl\glaux.h>
// Header File For The Glaux Library
#include "bmp.h"
AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A
Bitmap Image
{
FILE
*File=NULL; // File Handle
if (!Filename)
// Make Sure A Filename Was Given
{
return NULL;
// If Not Return NULL
}
File=fopen(Filename,"r"); // Check
To See If The File Exists
if (File)
// Does The File Exist?
{
fclose(File);
// Close The Handle
return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer
}
return NULL;
// If Load Failed Return NULL
}
Particle.h
#ifndef PARTICLE_H_
typedef struct
{
float lifetime; // total lifetime of the particle
float decay; // decay speed of the particle
float r,g,b; // color values of the particle
float xpos,ypos,zpos; // position of the particle
float xspeed,yspeed,zspeed; // speed of the particle
bool active; // is particle active or not?
} PARTICLE;
void CreateParticle(int i);
void InitParticle();
void EvolveParticle();
#endif
Particle.cpp
#include <windows.h>
#include <stdlib.h>
#include <math.h>
#include "particle.h"
const short
maxparticle=2000; // set maximum number of particles
PARTICLE particle[maxparticle];
void CreateParticle(int i)
{
particle[i].lifetime= (float)(500000*rand()/RAND_MAX)/500000.0;
particle[i].decay=0.001;
particle[i].r = 0.7;
particle[i].g = 0.7;
particle[i].b = 1.0;
particle[i].xpos= 0.0;
particle[i].ypos= 0.0;
particle[i].zpos= 0.0;
particle[i].xspeed = 10*(0.0005-(float)(100*rand()/RAND_MAX)/100000.0);
particle[i].yspeed = 0.01-(float)(100*rand()/RAND_MAX)/100000.0;
particle[i].zspeed = 0.0005-(float)(100*rand()/RAND_MAX)/100000.0;
particle[i].active = true;
}
//---------------------------------------------------------------------------
void InitParticle()
{
for (int
i=0;i<=maxparticle;i++){ // initialize the
particle parameters
CreateParticle(i);
particle[i].active = false; // set all
particles inactive
}
}
//---------------------------------------------------------------------------
void EvolveParticle()
{
for (int
i=0;i<=maxparticle;i++){ // evolve the particle
parameters
particle[i].lifetime-=particle[i].decay;
particle[i].xpos+=particle[i].xspeed;
particle[i].ypos+=particle[i].yspeed;
particle[i].zpos+=particle[i].zspeed;
particle[i].yspeed-=0.00010;
}
}
Tutor16.cpp
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <GL/glut.h>
#include "bmp.h"
#include "particle.h"
float z_pos=-5.0f;
float rot=0.0f;
GLfloat LightAmbient[]= { 0.5f,
0.5f, 0.5f, 1.0f };
GLfloat LightDiffuse[]= { 1.0f,
1.0f, 1.0f, 1.0f };
GLfloat LightPosition[]= { 0.0f,
0.0f, 2.0f, 1.0f };
/* array to hold
texture handles */
GLuint filter; // Which Filter To Use
GLuint texture[1]; // Storage For 3 Textures
/* Particle System */
extern int
const maxparticle=2000; // set maximum number of particles
extern PARTICLE
particle[maxparticle];
int LoadGLTextures() //Load Bitmaps And Convert To Textures
{
int Status=FALSE; //Status
Indicator
AUX_RGBImageRec
*TextureImage[1]; // Create Storage Space For The
Texture
memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL
// Load The Bitmap, Check For Errors, If Bitmap's Not Found
Quit
if (TextureImage[0]=LoadBMP("particle.bmp"))
{
Status=TRUE;
// Set The Status To TRUE
glGenTextures(1,
&texture[0]); //Create Three Textures
// Create Nearest Filtered Texture
glBindTexture(GL_TEXTURE_2D,
texture[0]);
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, TextureImage[0]->sizeX,
TextureImage[0]->sizeY,
0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
}
if (TextureImage[0]) // If
Texture Exists
{
if (TextureImage[0]->data) // If Texture Image Exists
{
free(TextureImage[0]->data);
// Free The Texture Image Memory
}
free(TextureImage[0]);
//Free The Image Structure
}
glEnable(GL_TEXTURE_2D);
//Enable Texture Mapping
return Status;
// Return The Status
}
void resize(int width, int
height)
{
glViewport(0,
0, width, height);
//glMatrixMode(GL_PROJECTION);
//glLoadIdentity();
//gluPerspective(45.0, (float)width/(float)height, 0.0,
300.0);
glMatrixMode(GL_PROJECTION);
// the following operations affect the projection
matrix
glLoadIdentity();
// restore matrix to original state
glOrtho(
-0.60,0.60,-0.20,0.60,-0.60,0.60); // defines the
viewing volume
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void myTimeOut(int id)
{
// called if timer event
// ...advance the state of animation incrementally...
rot+=1;
glutPostRedisplay();
// request redisplay
glutTimerFunc(100,
myTimeOut, 0); // request next timer event
}
void myKeyboard(unsigned char key,int x, int y)
{
if((key=='<')||(key==',')) z_pos-=0.1f;
else if((key=='>')||(key=='.'))
z_pos+=0.1f;
else if((key=='F')||(key='f'))
{
filter+=1;
if (filter>2)
{
filter=0;
}
printf("filter: %i",filter);
}
}
void mydisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLoadIdentity();
glRotatef(50.0,1.0,0.0,0.0);
// show scene from top front
glBindTexture(GL_TEXTURE_2D,texture[0]);
// choose particle texture
for (int
i=0;i<=maxparticle;i++){
if(particle[i].ypos<0.0) particle[i].lifetime=0.0;
if((particle[i].active==true)
&& (particle[i].lifetime>0.0)){
glColor3f(particle[i].r,particle[i].g,particle[i].b);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0.0,1.0);
glVertex3f(particle[i].xpos+0.005,particle[i].ypos+0.005,
particle[i].zpos+0.0); // top right
glTexCoord2f(0.0,0.0);
glVertex3f(particle[i].xpos-0.005,particle[i].ypos+0.005,
particle[i].zpos+0.0); // top left
glTexCoord2f(1.0,1.0);
glVertex3f(particle[i].xpos+0.005,particle[i].ypos-0.005, particle[i].zpos+0.0);
// bottom right
glTexCoord2f(1.0,0.0);
glVertex3f(particle[i].xpos-0.005,particle[i].ypos-0.005,
particle[i].zpos+0.0); // bottom left
glEnd();
}
else CreateParticle(i);
}
EvolveParticle();
glFlush();
glutSwapBuffers();
}
void init()
{
glDisable(GL_DEPTH_TEST);
// deactivate hidden surface removal
glDisable(GL_CULL_FACE);
// show backside of polygons
glClearColor(0.0f,
0.0f, 0.0f, 1.0f); // Black Background
glColor4f(1.0f,
1.0f, 1.0f, 0.5); // Full Brightness. 50% Alpha
if (!LoadGLTextures()) //
Jump To Texture Loading Routine
{
return; // If Texture
Didn't Load Return FALSE
}
InitParticle();
glMatrixMode(GL_MODELVIEW);
return;
}
int main(int argc, char**
argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(
GLUT_DOUBLE);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("simple");
// callbacks
glutDisplayFunc(mydisplay);
glutKeyboardFunc(myKeyboard);
glutTimerFunc(100,
myTimeOut, 0);
glutReshapeFunc(resize);
init();
glutMainLoop();
return 0;
}
Saat file Tutor16.cpp di jalankan akan
terjadi Error, untuk menghindari Error tersebut, tambahkan file glaux.lib pada
bagian :
Klik kanan pada Project Tutor16 anda,
kemudian pilih Properties di bagian bawah popup menu,kemudian tampil dialog
menu. Kemudian pilih Linker, pilih Input, pada bagian Properties, additional
dependencies, klik combobox, kemudian pilih <edit>, akan tampil dialog
menu, ketikan glaux.lib, pada kotak isian, kemudian klik OK, dan OK untuk
dialog terakhir.
Apabila source code tersebut
di jalankan, akan ditampilkan partikel mengembang dari kecil menjadi besar,
dimana butiran butilan kecil disimpan dalam file particle yang kemudian di
setting pada mydisplay(), yang dapat kita lihat seperti gambar dibawah ini.Link ke File Source Tutorial 16
Tutorial
17 :
Lighting
Link ke File Source Tutorial 17
Apabila source code tersebut di jalankan, akan ditampilkan gambar berikut, dimana object material dalam bentuk vas donut akan di load dan seolah olah dibagian sisi depan object tersebut mendapat cahaya, sementara sisi yang lain yang terkena cahaya. Dan seperti terlihat dibawah ini
Tutorial
18 :
Lighting Position
Link ke File Source Tutorial 18
Apabila source code tersebut di jalankan,
akan ditampilkan gambar berikut, dimana object material dalam bentuk vas bunga
akan di load dan seolah olah disatu sisi lebih terang di banding sisi yang lain
yang terkena cahaya. Dan seperti terlihat dibawah ini.
Tutorial
19 :
Vertex Animation
Dalam latihan ke 19 ini kita akan membuat ilustrasi
tentang bagaimana kita membuat gambar yang di gerakan seolah olah seperti
tertiup angin istilah ini disebut dengan Vertex Animation. dan disetiap bagian
diberi gambar texture, sama dengan langkah sebelumnya (Pada Tutorial ke 1) buat
sebuah Project dengan nama Tutor19 dan di tambah File : Tutor19.cpp, yang kita
butuhkan kemudian anda ketikan Source Code dibawah ini
#include <windows.h>
#include <math.h> // Math Library Header File
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <GL/glut.h>
#include <GL/glaux.h>
/* array to hold
texture handles */
GLuint filter; // Which Filter To Use
float z_pos=-12.0f;
float points[45][45][3]; // The Array For The Points On The Grid Of Our
"Wave"
int wiggle_count = 0; // Counter Used To Control How Fast Flag Waves
GLfloat xrot; // X Rotation ( NEW )
GLfloat yrot; // Y Rotation ( NEW )
GLfloat zrot; // Z Rotation ( NEW )
GLfloat hold; // Temporarily
Holds A Floating Point Value
GLuint texture[1]; // Storage For One Texture ( NEW )
AUX_RGBImageRec *LoadBMP(char *Filename) //
Loads A Bitmap Image
{
FILE *File=NULL;
// File Handle
if (!Filename) // Make Sure A Filename Was Given
{
return NULL; // If Not Return NULL
}
File=fopen(Filename,"r"); // Check To See If
The File Exists
if (File) // Does The File Exist?
{
fclose(File); // Close The Handle
return auxDIBImageLoadA(Filename); //
Load The Bitmap And Return A Pointer
}
return NULL; // If Load Failed Return NULL
}
int LoadGLTextures() // Load Bitmaps And Convert To Textures
{
int Status=FALSE; //
Status Indicator
AUX_RGBImageRec *TextureImage[1]; //
Create Storage Space For The Texture
memset(TextureImage,0,sizeof(void *)*1);
// Set The Pointer To NULL
// Load The Bitmap, Check For Errors, If
Bitmap's Not Found Quit
if (TextureImage[0]=LoadBMP("Data/glass.bmp"))
{
Status=TRUE; // Set The Status To TRUE
glGenTextures(1, &texture[0]); //
Create The Texture
// Typical Texture Generation Using Data From
The Bitmap
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX,
TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
if (TextureImage[0]) // If Texture Exists
{
if (TextureImage[0]->data) // If Texture Image Exists
{
free(TextureImage[0]->data); //
Free The Texture Image Memory
}
free(TextureImage[0]); // Free The Image Structure
}
return Status; // Return The Status
}
void resize(GLsizei width,
GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making
Height Equal One
}
glViewport(0,0,width,height); //
Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The
Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
int init(GLvoid) // All Setup For OpenGL Goes Here
{
if (!LoadGLTextures()) // Jump To Texture Loading Routine ( NEW )
{
return FALSE; // If Texture Didn't Load Return FALSE
}
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( NEW )
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //
Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice
Perspective Calculations
glPolygonMode( GL_BACK, GL_FILL ); //
Back Face Is Solid
glPolygonMode( GL_FRONT, GL_LINE ); //
Front Face Is Made Of Lines
for(int
x=0; x<45; x++)
{
for(int
y=0; y<45; y++)
{
points[x][y][0]=float((x/5.0f)-4.5f);
points[x][y][1]=float((y/5.0f)-4.5f);
points[x][y][2]=float(sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f));
}
}
return TRUE; // Initialization Went OK
}
void mydisplay(GLvoid) // Here's Where We Do All The Drawing
{
int x, y;
float float_x, float_y, float_xb,
float_yb;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,z_pos);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
for( x = 0; x < 44; x++ )
{
for( y =
0; y < 44; y++ )
{
float_x = float(x)/44.0f;
float_y = float(y)/44.0f;
float_xb = float(x+1)/44.0f;
float_yb = float(y+1)/44.0f;
glTexCoord2f( float_x, float_y);
glVertex3f( points[x][y][0],
points[x][y][1], points[x][y][2] );
glTexCoord2f( float_x, float_yb );
glVertex3f( points[x][y+1][0],
points[x][y+1][1], points[x][y+1][2] );
glTexCoord2f( float_xb, float_yb );
glVertex3f( points[x+1][y+1][0],
points[x+1][y+1][1], points[x+1][y+1][2] );
glTexCoord2f( float_xb, float_y );
glVertex3f( points[x+1][y][0],
points[x+1][y][1], points[x+1][y][2] );
}
}
glEnd();
if( wiggle_count == 2 )
{
for( y = 0; y < 45; y++ )
{
hold=points[0][y][2];
for( x =
0; x < 44; x++)
{
points[x][y][2] = points[x+1][y][2];
}
points[44][y][2]=hold;
}
wiggle_count = 0;
}
wiggle_count++;
xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;
glFlush();
glutSwapBuffers();
}
void myTimeOut(int id)
{
// called if timer event
// ...advance the state of animation
incrementally...
//rot+=1;
glutPostRedisplay(); // request redisplay
glutTimerFunc(10, myTimeOut, 0); //
request next timer event
}
void myKeyboard(unsigned char key,int x, int y)
{
if((key=='<')||(key==',')) z_pos-=0.1f;
else if((key=='>')||(key=='.'))
z_pos+=0.1f;
}
void mySpecialKeyboard(int key,int x, int y)
{
}
int main(int argc, char**
argv)
{
printf("Simple Vertex Animation Demo
\n\n");
printf("Press '<' key to move object
farther (alongside -Z axis) \n");
printf("Press '>' key to move object
nearer (alongside +Z axis) \n");
glutInit(&argc,argv);
glutInitDisplayMode( GLUT_RGB |GLUT_DOUBLE| GLUT_DEPTH );
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("Animasi Bendera
Simple");
// callbacks
glutDisplayFunc(mydisplay);
glutKeyboardFunc(myKeyboard);
glutSpecialFunc(mySpecialKeyboard);
glutTimerFunc(100, myTimeOut, 0);
glutReshapeFunc(resize);
init();
glutMainLoop();
return 0;
}
PENJELASAN
:
Apabila source code
tersebut di jalankan, akan ditampilkan gambar berikut, dimana object digerakan
seperti tertiup angi yang di setting pada mydisplay. Dan seperti terlihat
dibawah ini.Link ke File Source Tutorial 19
Untuk file lengkap tutorial dalam bentu PDF, berikut ini adalah linknya : http://inafile.com/i4zj3dqaaiot
Terima kasih, semoga dapat membantu dalam mepelajari OPENGL dengan GLUT
trimasih gan,,, penjelasnnya mudah dipahami
BalasHapuskeren sudah saya coba semua berhasil...
BalasHapussaya tambahkan sedikit tentang programing openGL 2D, 3D dan animasinya di blog ane untuk referency :
==================================================
Myblog
==================================================
Gold Casino - Gold Casino 카지노 카지노 우리카지노 우리카지노 349Slingo Mango Habanero Hot Sauce, 4 fl oz - Thai
BalasHapus