C-Kurs/DreiD/Musterlösung: Unterschied zwischen den Versionen
AndyF (Diskussion | Beiträge) |
(kein Unterschied)
|
Version vom 17. September 2010, 09:47 Uhr
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "screen.h"
/* Rotationsgeschwindigkeiten (frei wählbar) */
#define ROT_V_ALPHA 0.1f
#define ROT_V_BETA 0.03f
#define LIGHT_V_ALPHA 0.0f
#define LIGHT_V_BETA 0.0f
/* Drahtgitter-Modus: 1=an, 0=aus */
#define WIREFRAMES_MODE 1
/* 3x3-Matrix-Repräsentation als 2-dimensionales Array */
typedef float Matrix[3][3];
/* Aktuelle Transformation */
Matrix transform;
/* Aktuelle Zeichenfarbe mit Werten zwischen 0 und 1 */
float color_r;
float color_g;
float color_b;
/* Aktueller Lichtvektor */
float lgt_x;
float lgt_y;
float lgt_z;
/* --- Prototypen --- */
/* Gibt eine 3x3-Matrix aus und beendet das Programm */
void print_matrix(Matrix matrix);
/* Gibt einen Vektor, bestehend aus 3 floats, aus und beendet das Programm */
void print_vector(float x, float y, float z);
/*
Bildet aus zwei Winkeln die resultierende Transformationsmatrix
*/
void refresh_transformation_matrix(float alpha, float beta)
{
/* Rotationsmatrizen */
Matrix rot_x = {
{ 1.0f , 0.0f , 0.0f },
{ 0.0f , cos(beta) , -sin(beta) },
{ 0.0f , sin(beta) , cos(beta) }
};
//... (rot_y)
/* Matrix-Multiplikation */
//...
}
/*
Rotiert den gegebenen Vektor, bestehend aus 3 Floats, entsprechend der aktuellen transform-Matrix
*/
void apply_transform(float * x,float * y,float * z)
{
float h_x = *x;
float h_y = *y;
float h_z = *z;
/* Transformation anwenden */
*x = h_x;
*y = h_y;
*z = h_z;
}
/*
Zeichnet ein dreidimensionales Dreieck auf die zweidimensionale Fläche entsprechend der aktuellen transform-Matrix
*/
void render_primitive(float x1,float y1,float z1, float x2,float y2,float z2, float x3,float y3,float z3)
{
/* Koordinaten transformieren */
apply_transform(&x1,&y1,&z1);
apply_transform(&x2,&y2,&z2);
apply_transform(&x3,&y3,&z3);
/* Culling */
//...
/* Dreiecke zeichnen */
set_color(color_r, color_g, color_b);
if(WIREFRAMES_MODE)
{
draw_line(x1,y1, x2,y2);
draw_line(x2,y2, x3,y3);
draw_line(x3,y3, x1,y1);
}else
draw_triangle(x1,y1, x2,y2, x3,y3);
}
/* ----------------Ab hier alles Vorlage---------------- */
/* Aktuelle Rotationen */
float trf_alpha = 0;
float trf_beta = 0;
float lgt_alpha = 0;
float lgt_beta = 0;
/* Anzahl der bisher gezeichneten Frames */
int c_time = 0;
/*
Gibt eine 3x3-Matrix aus und beendet das Programm
*/
void print_matrix(Matrix matrix)
{
printf("%f %f %f\n",matrix[0][0],matrix[0][1],matrix[0][2]);
printf("%f %f %f\n",matrix[1][0],matrix[1][1],matrix[1][2]);
printf("%f %f %f\n",matrix[2][0],matrix[2][1],matrix[2][2]);
system("PAUSE");
exit(EXIT_SUCCESS);
}
/*
Gibt einen Vektor, bestehend aus 3 floats, aus und beendet das Programm
*/
void print_vector(float x, float y, float z)
{
printf("%f %f %f\n",x,y,z);
system("PAUSE");
exit(EXIT_SUCCESS);
}
/*
Setzt die aktuelle Farbe für nachfolgende render_* Aufrufe
*/
void refresh_color(float r,float g, float b)
{
color_r = r;
color_g = g;
color_b = b;
}
/*
Rendert dreidimensionale viereckige Fläche (bestehend aus zwei Dreiecken)
*/
void render_face(float x1,float y1,float z1, float x2,float y2,float z2, float x3,float y3,float z3, float x4,float y4,float z4)
{
render_primitive(x1,y1,z1,x2,y2,z2,x3,y3,z3);
render_primitive(x1,y1,z1,x3,y3,z3,x4,y4,z4);
}
/*
Komplette Ausgabe
*/
void output()
{
/* Transformation aktualisieren */
refresh_transformation_matrix(trf_alpha,trf_beta);
/* Licht-Vektor setzen */
lgt_x = cos(lgt_beta);
lgt_y = sin(lgt_beta);
lgt_z = sin(lgt_alpha)*lgt_x;
lgt_x = cos(lgt_alpha)*lgt_x;
/* Szene rendern */
begin_scene();
refresh_color(1,0,0);
render_face(-1,-1,1, 1,-1,1, 1,1,1, -1,1,1); //Front
render_face(1,-1,-1, -1,-1,-1, -1,1,-1, 1,1,-1); //Back
refresh_color(1,1,0);
render_face(-1,-1,1, -1,1,1, -1,1,-1, -1,-1,-1); //Left
render_face(1,1,1, 1,-1,1, 1,-1,-1, 1,1,-1); //Right
refresh_color(1,0.5,0);
render_face(1,-1,1, -1,-1,1, -1,-1,-1, 1,-1,-1); //Top
render_face(-1,1,1, 1,1,1, 1,1,-1, -1,1,-1); //Bottom
end_scene();
}
int main(void)
{
/* Fenster initialisieren */
if(create_window(400,400,0x220000) != 0){
printf("Fehler beim Fenster Erstellen. Bitte wende dich an einen Tutor.\n");
return EXIT_FAILURE;
}
/* Startwerte setzen */
zoom = 0.5;
trf_alpha = M_PI/2;
trf_beta = M_PI/3;
lgt_alpha = M_PI*2/3;
lgt_beta = -M_PI/4;
/* Figur wiederholt rendern */
while(1)
{
trf_alpha += ROT_V_ALPHA;
trf_beta += ROT_V_BETA;
lgt_alpha += LIGHT_V_ALPHA;
lgt_beta += LIGHT_V_BETA;
output();
c_time++;
usleep(50000);
}
/* Programmende */
close_window();
return EXIT_SUCCESS;
}