Jeff Molofee - NeHe's OpenGL Tutorials
Здесь есть возможность читать онлайн «Jeff Molofee - NeHe's OpenGL Tutorials» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.
- Название:NeHe's OpenGL Tutorials
- Автор:
- Жанр:
- Год:неизвестен
- ISBN:нет данных
- Рейтинг книги:3 / 5. Голосов: 1
-
Избранное:Добавить в избранное
- Отзывы:
-
Ваша оценка:
- 60
- 1
- 2
- 3
- 4
- 5
NeHe's OpenGL Tutorials: краткое содержание, описание и аннотация
Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «NeHe's OpenGL Tutorials»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.
NeHe's OpenGL Tutorials — читать онлайн бесплатно полную книгу (весь текст) целиком
Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «NeHe's OpenGL Tutorials», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
Well, I suppose that's enough math for now, on to the code!
#include // Header File For Windows
#include // Header File For Math Library Routines
#include // Header File For Standard I/O Routines
#include // Header File For Standard Library
#include // Header File For The OpenGL32 Library
#include // Header File For The GLu32 Library
#include // Header File For The Glaux Library
typedef struct point_3d { // Structure For A 3-Dimensional Point ( NEW )
double x, y, z;
} POINT_3D;
typedef struct bpatch { // Structure For A 3rd Degree Bezier Patch ( NEW )
POINT_3D anchors[4][4]; // 4x4 Grid Of Anchor Points
GLuint dlBPatch; // Display List For Bezier Patch
GLuint texture; // Texture For The Patch
} BEZIER_PATCH;
HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
DEVMODE DMsaved; // Saves The Previous Screen Settings ( NEW )
bool keys[256]; // Array Used For The Keyboard Routine
bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default
GLfloat rotz = 0.0f; // Rotation About The Z Axis
BEZIER_PATCH mybezier; // The Bezier Patch We're Going To Use ( NEW )
BOOL showCPoints=TRUE; // Toggles Displaying The Control Point Grid ( NEW )
int divs = 7; // Number Of Intrapolations (Controls Poly Resolution) ( NEW )
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
The following are just a few quick functions for some simple vector math. If you're a fan of C++ you might consider using a point class (just make sure it's 3d).
// Adds 2 Points. Don't Just Use '+' ;)
POINT_3D pointAdd(POINT_3D p, POINT_3D q) {
p.x += q.x; p.y += q.y; p.z += q.z;
return p;
}
// Multiplies A Point And A Constant. Don't Just Use '*'
POINT_3D pointTimes(double c, POINT_3D p) {
p.x *= c; p.y *= c; p.z *= c;
return p;
}
// Function For Quick Point Creation
POINT_3D makePoint(double a, double b, double c) {
POINT_3D p;
p.x = a; p.y = b; p.z = c;
return p;
}
This is basically just the 3rd degree basis function written in C, it takes a variable u and an array of 4 points and computes a point on the curve. By stepping u in equal increments between 0 and 1, we'll get a nice approximation of the curve.
// Calculates 3rd Degree Polynomial Based On Array Of 4 Points
// And A Single Variable (u) Which Is Generally Between 0 And 1
POINT_3D Bernstein(float u, POINT_3D *p) {
POINT_3D a, b, c, d, r;
a = pointTimes(pow(u,3), p[0]);
b = pointTimes(3*pow(u,2)*(1-u), p[1]);
c = pointTimes(3*u*pow((1-u),2), p[2]);
d = pointTimes(pow((1-u),3), p[3]);
r = pointAdd(pointAdd(a, b), pointAdd(c, d));
return r;
}
This function does the lion's share of the work by generating all the triangle strips and storing them in a display list. We do this so that we don't have to recalculate the patch each frame, only when it changes. By the way, a cool effect you might want to try might be to use the morphing tutorial to morph the patch's control points. This would yeild a very cool smooth, organic, morphing effect for relatively little overhead (you only morph 16 points, but you have to recalculate). The "last" array is used to keep the previous line of points (since a triangle strip needs both rows). Also, texture coordinates are calculated by using the u and v values as the percentages (planar mapping).
One thing we don't do is calculate the normals for lighting. When it comes to this, you basically have two options. The first is to find the center of each triangle, then use a bit of calculus and calculate the tangent on both the x and y axes, then do the cross product to get a vector perpendicular to both, THEN normalize the vector and use that as the normal. OR (yes, there is a faster way) you can cheat and just use the normal of the triangle (calculated your favorite way) to get a pretty good approximation. I prefer the latter; the speed hit, in my opinion, isn't worth the extra little bit of realism.
// Generates A Display List Based On The Data In The Patch
// And The Number Of Divisions
GLuint genBezier(BEZIER_PATCH patch, int divs) {
int u = 0, v;
float py, px, pyold;
GLuint drawlist = glGenLists(1); // Make The Display List
POINT_3D temp[4];
POINT_3D *last = (POINT_3D*)malloc(sizeof(POINT_3D)*(divs+1));
// Array Of Points To Mark The First Line Of Polys
if (patch.dlBPatch != NULL) // Get Rid Of Any Old Display Lists
glDeleteLists(patch.dlBPatch, 1);
temp[0] = patch.anchors[0][3]; // The First Derived Curve (Along X-Axis)
temp[1] = patch.anchors[1][3];
temp[2] = patch.anchors[2][3];
temp[3] = patch.anchors[3][3];
for (v=0;v<=divs;v++) { // Create The First Line Of Points
px = ((float)v)/((float)divs); // Percent Along Y-Axis
// Use The 4 Points From The Derived Curve To Calculate The Points Along That Curve
last[v] = Bernstein(px, temp);
}
glNewList(drawlist, GL_COMPILE); // Start A New Display List
glBindTexture(GL_TEXTURE_2D, patch.texture); // Bind The Texture
for (u=1;u<=divs;u++) {
py = ((float)u)/((float)divs); // Percent Along Y-Axis
pyold = ((float)u-1.0f)/((float)divs); // Percent Along Old Y Axis
temp[0] = Bernstein(py, patch.anchors[0]); // Calculate New Bezier Points
temp[1] = Bernstein(py, patch.anchors[1]);
temp[2] = Bernstein(py, patch.anchors[2]);
temp[3] = Bernstein(py, patch.anchors[3]);
glBegin(GL_TRIANGLE_STRIP); // Begin A New Triangle Strip
for (v=0;v<=divs;v++) {
px = ((float)v)/((float)divs); // Percent Along The X-Axis
glTexCoord2f(pyold, px); // Apply The Old Texture Coords
glVertex3d(last[v].x, last[v].y, last[v].z); // Old Point
last[v] = Bernstein(px, temp); // Generate New Point
glTexCoord2f(py, px); // Apply The New Texture Coords
glVertex3d(last[v].x, last[v].y, last[v].z); // New Point
}
glEnd(); // END The Triangle Strip
}
glEndList(); // END The List
free(last); // Free The Old Vertices Array
return drawlist; // Return The Display List
}
Here we're just loading the matrix with some values I've picked that I think look cool. Feel free to screw around with these and see what it looks like. :-)
Читать дальшеИнтервал:
Закладка:
Похожие книги на «NeHe's OpenGL Tutorials»
Представляем Вашему вниманию похожие книги на «NeHe's OpenGL Tutorials» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «NeHe's OpenGL Tutorials» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.