Я хочу изучить OpenGL и решил начать с очень простого примера - визуализации формы кометы Wild 2, как это было сделано из измерений с космического корабля Stardust (подробности о данных в : http://nssdc.gsfc.nasa.gov/nmc/masterCatalog.do?ds=PSSB-00133). Пожалуйста, имейте в виду, что я абсолютно ничего не знаю о OpenGL. Некоторые Google-fu помогли мне дойти до кода, представленного ниже. Несмотря на все мои усилия, моя комета сосет:Базовый рендеринг кометы Дикие данные формы 2 с использованием OpenGL
Я хотел бы, чтобы она выглядела симпатичнее, и я понятия не имею, как поступить (кроме чтения Красную книгу, или аналогичный). Например:
- Как я могу сделать очень простой «каркасный» рендеринг формы?
- Предположим, что Солнце находится в «нижнем» направлении (то есть вдоль -Y), как я могу добавить свет и увидеть тень на другой стороне?
- Как добавить «события мыши», чтобы я мог поворачивать свой просмотр и увеличивать/уменьшать масштаб?
Как я могу сделать этот монстр более красивым? Любые ссылки на онлайновые учебники или примеры кода?
Я поместил исходный код, данные и Makefile (для OS X) в BitBucket:
рт.ст. клона https://[email protected]/arrieta/learning-opengl
Данные состоят из 8,761 триплетов (вершин, в кадре тела фиксированной) и 17 518 треугольников (каждый треугольник представляет собой триплет целых чисел, относящихся к одному из 8 761 вершинных триплетов).
#include<stdio.h>
#include<stdlib.h>
#include<OpenGL/gl.h>
#include<OpenGL/glu.h>
// I added this in case you want to "copy/paste" the program into a
// non-Mac computer
#ifdef __APPLE__
# include <GLUT/glut.h>
#else
# include <GL/glut.h>
#endif
/* I hardcoded the data and use globals. I know it sucks, but I was in
a hurry. */
#define NF 17518
#define NV 8761
unsigned int fs[3 * NF];
float vs[3 * NV];
float angle = 0.0f;
/* callback when the window changes size (copied from Internet example) */
void changeSize(int w, int h) {
if (h == 0) h = 1;
float ratio = w * 1.0/h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45.0f, ratio, 0.2f, 50000.0f); /* 45 degrees fov in Y direction; 50km z-clipping*/
glMatrixMode(GL_MODELVIEW);
}
/* this renders and updates the scene (mostly copied from Internet examples) */
void renderScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 10000.0f, /* eye is looking down along the Z-direction at 10km */
0.0f, 0.0f, 0.0f, /* center at (0, 0, 0) */
0.0f, 1.0f, 0.0f); /* y direction along natural y-axis */
/* just add a simple rotation */
glRotatef(angle, 0.0f, 0.0f, 1.0f);
/* use the facets and vertices to insert triangles in the buffer */
glBegin(GL_TRIANGLES);
unsigned int counter;
for(counter=0; counter<3 * NF; ++counter) {
glVertex3fv(vs + 3 * fs[counter]); /* here is where I'm loading
the data - why do I need to
load it every time? */
}
glEnd();
angle += 0.1f; /* update the rotation angle */
glutSwapBuffers();
}
int main(int argc, char* argv[]) {
FILE *fp;
unsigned int counter;
/* load vertices */
fp = fopen("wild2.vs", "r");
counter = 0;
while(fscanf(fp, "%f", &vs[counter++]) > 0);
fclose(fp);
/* load facets */
fp = fopen("wild2.fs", "r");
counter = 0;
while(fscanf(fp, "%d", &fs[counter++]) > 0);
fclose(fp);
/* this initialization and "configuration" is mostly copied from Internet */
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(0, 0);
glutInitWindowSize(1024, 1024);
glutCreateWindow("Wild-2 Shape");
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 30.0 };
GLfloat light_position[] = {3000.0, 3000.0, 3000.0, 0.0 };
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(renderScene);
glutMainLoop();
return 0;
}
EDIT
Это начинает выглядеть лучше, и у меня сейчас много ресурсов, чтобы изучить на некоторое время. Он все еще сосет, но на мои вопросы ответили!
Я добавил нормалей, и может переключаться между "текстурой" и каркасные:
PS. В repository показаны изменения, внесенные в соответствии с предложениями SeedmanJ.
FYI: «Решил начать с очень простого примера». «Простой пример» - это треугольник, а не сложная сетка. –
@ НикольБолас: хорошая точка - тускло отметили. – Escualo
Не используйте немедленный режим. Не используйте конвейер с фиксированной функцией. http://open.gl/introduction http://www.arcsynthesis.org/gltut/ –