LINUX.ORG.RU

Помогите наложить текстуру в opengl

 , ,


0

3

https://github.com/xverizex/asel

Всё действие происходит в main.c

Программа загружает из data 3d модель и картинку. Картинку хочу использовать как текстуру. В blender делал модельку и создал uv рисунок. Нарисовал. Проверил как выглядит. Экспортировал в формат obj вместе с текстурными координатами.

Программа отображает модельку, но текстура наложена неправильно. Я когда раньше проверял загруженную картинку, то как то попробывал использовать glDrawPixels, она выводит рисунок какой он есть, это значит что я правильно перенёс рисунок. Только помню пришлось поменять направление на справа налево.

Что может быть не так? Как сделать, чтобы было правильно?

Ответ на: комментарий от aureliano15

Так у меня добрый дядька на аве, зачем мне такие вещи делать. Я вот еще подсказываю, а такое встраивать ну ты чего. Да и такие люди думаю иксы не юзают, и их рабочее место выглядит как то так: Рабочее место шифропанка

linuhs_user
()
Последнее исправление: linuhs_user (всего исправлений: 1)
Ответ на: комментарий от u0atgKIRznY5

У тебя вообще нет понимания что происходит, в функции render_3d, между glBegin(GL_TRIANGLES) и glEnd().
Посмотри примеры, документацию, пойми как это работает.
Более того, этот способ объявлен устаревшим.
Когда ты отдуплишь, что делаешь неправильно, может увидишь, что файлик с моделькой, и его заполнение в obj.c из test_shuttle.obj ты делаешь тоже неправильно.
Возможно тебе нужно внимательней прочитать документацию по формату файла Wavefront(.obj)

И да, это ещё не всё.
И это…, мы в тебя верим!

uCore
()
Ответ на: комментарий от uCore

Я знаю что это устаревшее, и надо пользоваться отдельными либами. Это я узнал в книги про рецепты шейдеров, что-то такое в названии. Но мне на первое время это пойдёт, устаревшее.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от linuhs_user

Так у меня добрый дядька на аве

Ну, мало ли что на аве. На аве может быть одно, а под авой — совсем другое. :-)

такие люди думаю иксы не юзают, и их рабочее место выглядит как то так

Не обязательно. Я знавал очень сильных программёров, которые неработающий драйвер для linux переписывали для другой системы, и он там начинал работать. При этом сидели под виндой и даже с антивирусом не заморачивались. Когда на компе выскакивал какой-то чёртик и сообщал им, что я, дескать, вирус, но добрый и пушистый, поэтому бороться со мной не надо, — они принимали на веру и оставляли всё как есть. :-) А ведь даже добрый и пушистый вирус может неумышленно нагадить, если в его коде есть ошибки.

Да и вообще голая консоль (если только железо не вынуждает её использовать) — больше понты. Конечно, чтоб настроить её по-человечески, надо иметь некоторые навыки. Но это больше админские, нежели программистские навыки.

aureliano15 ★★
()
Ответ на: комментарий от u0atgKIRznY5

мне на первое время это пойдёт, устаревшее

А зачем? Т. е. бывают устаревшие проекты, которые сложно переписать с нуля и приходится использовать легаси. Бывают проекты под какое-то устаревшее железо (ну, если заказчику это просто необходимо), где тоже могут использовать старьё, хотя такая ситуация кажется мне несколько надуманной (обычно легче купить новое железо, чем переплачивать за код, который из-за использования устаревших неподдерживаемых инструментов поддерживать труднее и дороже).

Но зачем учиться на устаревшем, а потом переучиваться?

aureliano15 ★★
()
Ответ на: комментарий от uCore

Просто это более важное, кмк.

Хотя… я вижу openGL в первый раз, могу и ошибаться. (:

uCore
()
Ответ на: комментарий от aureliano15

Но зачем учиться на устаревшем, а потом переучиваться?

Чтобы на нетбуке работало. Бывает я на нетбуке пишу. А там шейдеры не заработают.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от peregrine

у разных версий одного и того же браузера результат может выглядеть по-разному.

А, в этом плане. Да, разработчики браузеров любят класть на совместимость. Но всё-таки есть какие-то стандарты, и если придерживаться только их и не использовать разные расширения, то, думаю, всё должно быть ok. Хотя, конечно, всё равно желательно тестировать в разных браузерах.

aureliano15 ★★
()
Ответ на: комментарий от linuhs_user

У меня пока что проблема с пониманием шейдеров. Мне бы хотя бы опыта на обычном opengl наработать. А потом взяться за что по сложнее.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от linuhs_user

Получилось. Только видны артефакты, и прозрачность, помню была функция gl, которая не рисует перекрывающиеся объекты, надо искать её. Что мне с артефактами делать, рисунок 1024x1024?

https://www.youtube.com/watch?v=or2ZAbevsZQ&feature=youtu.be

u0atgKIRznY5
() автор топика
Ответ на: комментарий от linuhs_user

Забыл в ffmpeg -qscale:v 0 сделать, без этого изображение не чёткое.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от linuhs_user

Если ты про glEnable ( GL_DEPTH_TEST ), то он указан в коде, в момент инициализации. Я помню было что-то вроде cull_face, но точно не помню ( это чтоб не рисовались перекрывающиеся объекты ).

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

CullFace на отображение не влияет, если правильно сделанно. Просто отсекает для OpenGL части которые не нужно рисовать.

linuhs_user
()
Последнее исправление: linuhs_user (всего исправлений: 2)
Ответ на: комментарий от u0atgKIRznY5

Вообще мне больно смотреть.
vim -> geany
build.sh/make -> meson
png.h -> sdl2_image
gl1 -> gl2
glu -> https://github.com/arkanis/single-header-file-c-libs/blob/master/math_3d.h

Вот лучше изучи современное, старого уже хватит, понял как треугольник нарисовать и нормально.

linuhs_user
()
Ответ на: комментарий от linuhs_user

png.h -> sdl2_image

Ну я же из data все данные получаю, а sdl2_image только отдельные файлы рисунков. Конечно можно посмотреть как структура sdl_image выглядит и адаптировать её для извлечения данных из data, но это может быть сложным для меня.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от linuhs_user

Я прочитал в книге что depth_test использует z координату, а моём случае рисунок был выше по y координате, и он виден был.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от linuhs_user

Видно прозрачно другие детали из-за того, что треугольников не хватает. Но как такое может быть? Я же в коде все f получаю и сохраняю.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

Да, причем там в формате недостающий треугольник мог смещаться в любую сторону по XYZ...

linuhs_user
()
Ответ на: комментарий от u0atgKIRznY5

На гифке что я выкладывал, артефакты видел?
Ты в gluPerspective ( 60, w / h, -30, 0 ); точно всё правильно делаешь? Документацию перечитай.

uCore
()
Ответ на: комментарий от u0atgKIRznY5

Смотри
Есть только артефакт на одной из граней.
Скорее всего это проблема с текстурой, или её наложением. Мне разбираться лень.

uCore
()
Ответ на: комментарий от uCore

Вот ты блин. На готовом то легко говорить. Сам пользуешься моим кодом, а как поменял немного кода, так его скрываешь. Ладно, надеюсь тебе также сделают.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от uCore

Здесь всё правильно?

	if ( !strncmp ( line, "f ",  2 ) ) {
			int vxx, vyy, vzz;
			int vtxx, vtyy, vtzz;
			int vnxx, vnyy, vnzz;
			sscanf ( line, "f %d/%d/%d %d/%d/%d %d/%d/%d",
					&vxx, &vtxx, &vnxx, &vyy, &vtyy, &vnyy, &vzz, &vtzz, &vnzz );

			obj->v[obj->i_v].x = vv [ vxx - 1 ];
			obj->v[obj->i_v].y = vv [ vyy - 1 ];
			obj->v[obj->i_v].z = vv [ vzz - 1 ];

			obj->vn[obj->i_vn].x = vvn [ vnxx - 1 ];
			obj->vn[obj->i_vn].y = vvn [ vnyy - 1 ];
			obj->vn[obj->i_vn].z = vvn [ vnzz - 1 ];
			
			obj->vt[obj->i_vt].x.u = vvt [ vtxx - 1 ].u;
			obj->vt[obj->i_vt].x.v = vvt [ vtxx - 1 ].v;
			obj->vt[obj->i_vt].y.u = vvt [ vtyy - 1 ].u;
			obj->vt[obj->i_vt].y.v = vvt [ vtyy - 1 ].v;
			obj->vt[obj->i_vt].z.u = vvt [ vtzz - 1 ].u;
			obj->vt[obj->i_vt].z.v = vvt [ vtzz - 1 ].v;

			obj->i_v++;
			obj->i_vn++;
			obj->i_vt++;
		}
	}
	fclose ( fd );
	
	obj->length_v = obj->i_v;
	obj->length_vt = obj->i_vt;
	obj->length_vn = obj->i_vn;

	fd = fopen ( data_file, "ab" );
	if ( !fd ) return -1;

	fwrite ( &obj->length_v,  sizeof ( unsigned int ), 1, fd );
	fwrite ( &obj->length_vt, sizeof ( unsigned int ), 1, fd );
	fwrite ( &obj->length_vn, sizeof ( unsigned int ), 1, fd );

	for ( int i = 0; i < obj->length_v; i++ ) {
//		fwrite ( &obj->v[i], sizeof ( struct coordinates ), 1, fd );
#if 1
		fwrite ( &obj->v[i].x.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].x.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].x.z, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].y.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].y.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].y.z, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].z.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].z.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].z.z, sizeof ( float ), 1, fd );
#endif
	}
	for ( int i = 0; i < obj->length_vn; i++ ) {
#if 1
		fwrite ( &obj->vn[i].x.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].x.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].x.z, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].y.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].y.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].y.z, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].z.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].z.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].z.z, sizeof ( float ), 1, fd );
#endif
	}
	for ( int i = 0; i < obj->length_vt; i++ ) {
#if 1
		fwrite ( &obj->vt[i].x.u, sizeof ( float ), 1, fd );
		fwrite ( &obj->vt[i].x.v, sizeof ( float ), 1, fd );
		fwrite ( &obj->vt[i].y.u, sizeof ( float ), 1, fd );
		fwrite ( &obj->vt[i].y.v, sizeof ( float ), 1, fd );
		fwrite ( &obj->vt[i].z.u, sizeof ( float ), 1, fd );
		fwrite ( &obj->vt[i].z.v, sizeof ( float ), 1, fd );
#endif
	}

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

ого. Вроде бы на нетбуке исправленная версия, щас эту подправлю.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от uCore

Вот, здесь всё правильно?

if ( !strncmp ( line, "f ",  2 ) ) {
			int vxx, vyy, vzz;
			int vtxx, vtyy, vtzz;
			int vnxx, vnyy, vnzz;
			sscanf ( line, "f %d/%d/%d %d/%d/%d %d/%d/%d",
					&vxx, &vtxx, &vnxx, &vyy, &vtyy, &vnyy, &vzz, &vtzz, &vnzz );

			obj->v[obj->i_v].x.x = vv [ vxx - 1 ].x;
			obj->v[obj->i_v].x.y = vv [ vxx - 1 ].y;
			obj->v[obj->i_v].x.z = vv [ vxx - 1 ].z;

			obj->v[obj->i_v].y.x = vv [ vyy - 1 ].x;
			obj->v[obj->i_v].y.y = vv [ vyy - 1 ].y;
			obj->v[obj->i_v].y.z = vv [ vyy - 1 ].z;

			obj->v[obj->i_v].z.x = vv [ vzz - 1 ].x;
			obj->v[obj->i_v].z.y = vv [ vzz - 1 ].y;
			obj->v[obj->i_v].z.z = vv [ vzz - 1 ].z;

			obj->vn[obj->i_vn].x.x = vvn [ vnxx - 1 ].x;
			obj->vn[obj->i_vn].y.y = vvn [ vnyy - 1 ].y;
			obj->vn[obj->i_vn].z.z = vvn [ vnzz - 1 ].z;
			
			obj->vt[obj->i_vt].x.u = vvt [ vtxx - 1 ].u;
			obj->vt[obj->i_vt].x.v = vvt [ vtxx - 1 ].v;
			obj->vt[obj->i_vt].y.u = vvt [ vtyy - 1 ].u;
			obj->vt[obj->i_vt].y.v = vvt [ vtyy - 1 ].v;
			obj->vt[obj->i_vt].z.u = vvt [ vtzz - 1 ].u;
			obj->vt[obj->i_vt].z.v = vvt [ vtzz - 1 ].v;

			obj->i_v++;
			obj->i_vn++;
			obj->i_vt++;
		}
	}
	fclose ( fd );
	
	obj->length_v = obj->i_v;
	obj->length_vt = obj->i_vt;
	obj->length_vn = obj->i_vn;

	fd = fopen ( data_file, "ab" );
	if ( !fd ) return -1;

	fwrite ( &obj->length_v,  sizeof ( unsigned int ), 1, fd );
	fwrite ( &obj->length_vt, sizeof ( unsigned int ), 1, fd );
	fwrite ( &obj->length_vn, sizeof ( unsigned int ), 1, fd );

	for ( int i = 0; i < obj->length_v; i++ ) {
//		fwrite ( &obj->v[i], sizeof ( struct coordinates ), 1, fd );
#if 1
		fwrite ( &obj->v[i].x.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].x.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].x.z, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].y.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].y.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].y.z, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].z.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].z.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->v[i].z.z, sizeof ( float ), 1, fd );
#endif
	}
	for ( int i = 0; i < obj->length_vn; i++ ) {
#if 1
		fwrite ( &obj->vn[i].x.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].x.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].x.z, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].y.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].y.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].y.z, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].z.x, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].z.y, sizeof ( float ), 1, fd );
		fwrite ( &obj->vn[i].z.z, sizeof ( float ), 1, fd );
#endif
	}
	for ( int i = 0; i < obj->length_vt; i++ ) {
#if 1
		fwrite ( &obj->vt[i].x.u, sizeof ( float ), 1, fd );
		fwrite ( &obj->vt[i].x.v, sizeof ( float ), 1, fd );
		fwrite ( &obj->vt[i].y.u, sizeof ( float ), 1, fd );
		fwrite ( &obj->vt[i].y.v, sizeof ( float ), 1, fd );
		fwrite ( &obj->vt[i].z.u, sizeof ( float ), 1, fd );
		fwrite ( &obj->vt[i].z.v, sizeof ( float ), 1, fd );
#endif
	}

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

Это то сообщение, где ты писал что файлик неправильно загружаю в read_obj?

Нет, это моё сообщение по поводу того что ты неправильно выводишь.

uCore
()
Ответ на: комментарий от uCore

Вот как программа считывает данные, здесь врядли есть ошибка.

void load_3d ( long pos, struct obj *obj )
{
	FILE *fd = fopen ( "data", "rb" );
	if ( !fd ) return;

	fseek ( fd, pos, SEEK_SET );

	fread ( &obj->length_v, sizeof ( unsigned int ), 1, fd );
	fread ( &obj->length_vt, sizeof ( unsigned int ), 1, fd );
	fread ( &obj->length_vn, sizeof ( unsigned int ), 1, fd );

	obj->v = calloc ( obj->length_v, sizeof ( struct coordinates ) );
	for ( int i = 0; i < obj->length_v; i++ ) {
#if 1
		fread ( &obj->v[i].x.x, sizeof ( float ), 1, fd );
		fread ( &obj->v[i].x.y, sizeof ( float ), 1, fd );
		fread ( &obj->v[i].x.z, sizeof ( float ), 1, fd );
		fread ( &obj->v[i].y.x, sizeof ( float ), 1, fd );
		fread ( &obj->v[i].y.y, sizeof ( float ), 1, fd );
		fread ( &obj->v[i].y.z, sizeof ( float ), 1, fd );
		fread ( &obj->v[i].z.x, sizeof ( float ), 1, fd );
		fread ( &obj->v[i].z.y, sizeof ( float ), 1, fd );
		fread ( &obj->v[i].z.z, sizeof ( float ), 1, fd );
#endif
	}
	obj->vn = calloc ( obj->length_vn, sizeof ( struct coordinates ) );
	for ( int i = 0; i < obj->length_vn; i++ ) {
#if 1
		fread ( &obj->vn[i].x.x, sizeof ( float ), 1, fd );
		fread ( &obj->vn[i].x.y, sizeof ( float ), 1, fd );
		fread ( &obj->vn[i].x.z, sizeof ( float ), 1, fd );
		fread ( &obj->vn[i].y.x, sizeof ( float ), 1, fd );
		fread ( &obj->vn[i].y.y, sizeof ( float ), 1, fd );
		fread ( &obj->vn[i].y.z, sizeof ( float ), 1, fd );
		fread ( &obj->vn[i].z.x, sizeof ( float ), 1, fd );
		fread ( &obj->vn[i].z.y, sizeof ( float ), 1, fd );
		fread ( &obj->vn[i].z.z, sizeof ( float ), 1, fd );
#endif
	}
	obj->vt = calloc ( obj->length_vt, sizeof ( struct vt_coordinates ) );
	for ( int i = 0; i < obj->length_vt; i++ ) {
#if 1
		fread ( &obj->vt[i].x.u, sizeof ( float ), 1, fd );
		fread ( &obj->vt[i].x.v, sizeof ( float ), 1, fd );
		fread ( &obj->vt[i].y.u, sizeof ( float ), 1, fd );
		fread ( &obj->vt[i].y.v, sizeof ( float ), 1, fd );
		fread ( &obj->vt[i].z.u, sizeof ( float ), 1, fd );
		fread ( &obj->vt[i].z.v, sizeof ( float ), 1, fd );
#endif
	}
}
А вот как выводиться.
void render_3d ( struct obj *obj )
{
	glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glBindTexture ( GL_TEXTURE_2D, tex );

	glPushMatrix ( );
	glTranslatef ( 0, 0, -20 );
//	move->angle += 0.1;
	glRotatef ( move->angle, 0, 1, 0 );
	move->z += 0.01;
	glTranslatef ( move->x, move->y, move->z );
//	if ( move->angle > 512 ) move->angle = 0;
//	move->x += 0.1;
	glBegin ( GL_TRIANGLES );
	for ( int i = 0; i < obj->length_v; i++ ) {
		glTexCoord2d ( obj->vt[i].x.u, obj->vt[i].x.v );
		glVertex3f ( obj->v[i].x.x, obj->v[i].x.y, obj->v[i].x.z );
		glNormal3f ( obj->vn[i].x.x, obj->vn[i].x.y, obj->vn[i].x.z );
		glTexCoord2d ( obj->vt[i].y.u, obj->vt[i].y.v );
		glNormal3f ( obj->vn[i].y.x, obj->vn[i].y.y, obj->vn[i].y.z );
		glVertex3f ( obj->v[i].y.x, obj->v[i].y.y, obj->v[i].y.z );
		glTexCoord2d ( obj->vt[i].z.u, obj->vt[i].z.v );
		glNormal3f ( obj->vn[i].z.x, obj->vn[i].z.y, obj->vn[i].z.z );
		glVertex3f ( obj->v[i].z.x, obj->v[i].z.y, obj->v[i].z.z );


	glPopMatrix ( );
	glFlush ( );
}
Здесь есть ошибка? Я сначала выводил так, но была в другом ошибка. Потом делал отдельно, в отдельном цикле glTexCoord2d, но это было ошибкой. Потом вернул обратно. Но в этом случае выводиться прозрачно и не все треугольники рисуются. Где же ошибка? В этих функция есть ошибка, которые я привёл?

u0atgKIRznY5
() автор топика
Ответ на: комментарий от uCore

И кстати, ты знаешь как нарисовать модель с текстурой без glBegin?

u0atgKIRznY5
() автор топика
Ответ на: комментарий от uCore

Поменял на это, теперь массив float хранит x y z.

if ( !strncmp ( line, "f ",  2 ) ) {
			int vxx, vyy, vzz;
			int vtxx, vtyy, vtzz;
			int vnxx, vnyy, vnzz;
			if ( sscanf ( line, "f %d/%d/%d %d/%d/%d %d/%d/%d",
					&vxx, &vtxx, &vnxx, &vyy, &vtyy, &vnyy, &vzz, &vtzz, &vnzz ) == -1 )
				perror ( "sscanf 4" );

			obj->v[obj->i_v + 0] 	 = vv [ 0 + ( vxx - 1 ) * 3 ];
			obj->v[obj->i_v + 1] 	 = vv [ 1 + ( vyy - 1 ) * 3 ];
			obj->v[obj->i_v + 2] 	 = vv [ 2 + ( vzz - 1 ) * 3 ];

			obj->vn[obj->i_vn + 0] = vvn [ 0 + ( vnxx - 1 ) * 3 ];
			obj->vn[obj->i_vn + 1] = vvn [ 1 + ( vnyy - 1 ) * 3 ];
			obj->vn[obj->i_vn + 2] = vvn [ 2 + ( vnzz - 1 ) * 3 ];
			
			obj->vt[obj->i_vt + 0] = vvt [ 0 + ( vtxx - 1 ) * 2 ];
			obj->vt[obj->i_vt + 1] = vvt [ 1 + ( vtyy - 1 ) * 2 ];
			obj->vt[obj->i_vt + 2] = vvt [ 2 + ( vtzz - 1 ) * 2 ];

			obj->i_v += 3;
			obj->i_vn += 3;
			obj->i_vt += 3;
		}

u0atgKIRznY5
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.