Сообщение от Yoti
Боюсь, помощи с графикой долго ждать придётся. У нас разве что Ilsor что-то делал на этот счёт. Смотри его темы, может примеры кода подберёшь какие…
|
Боюсь мне другого и не остается.
Пока что я застрял на правильном отображении текстуры на загружаемом *.obj . Для элементарной отладки нарисовал в Blender'e параллелепипед и натянул на него
текстуру "спичечного коробка".
Но, как не странно
выходит вот это.
Используя ручную трассировку (на бумажке вырисовывал

), то получилось так, что по логике вещей все должно работать, поскольку каждый vertex из структуры...
struct Vertex_UVColorNormalXYZ
{
float u, v;
unsigned int color;
float normal_x, normal_y, normal_z;
float x, y, z;
};
...содержит корректные координаты [U,V] для mapping'а.
Единственное, где я действительно плаваю, это текстурные настройки (хотя я уже все перерыл и перепробовал всевозможные комбинации), а так же в выравнивании data текстуры по 16 байт, как требует void sceGuTexImage:
Note: Data must be aligned to 1 quad word (16 bytes)
|
Пока же data от текстуры просто
png_bytep *row_pointers;
// а он в свою очередь
typedef png_byte FAR * png_bytep;
//т.е.
typedef unsigned char png_byte;
Оказалось, что дело было в выравнивании.
Вот, настряпал "страшный код", для большего понимания того, что происходит, и, как оказалось, на нем все заработало...
struct COLOR
{
unsigned char r, g, b, a;
};
struct COLOR __attribute__((aligned(16))) *img_data = (struct COLOR __attribute__((aligned(16))) *)malloc(sizeof(struct COLOR __attribute__((aligned(16)))) * img_tmp.width * img_tmp.height);
unsigned long img_index = 0;
for (int y = 0; y < img_tmp.height; y++)
{
for (int x = 0; x < img_tmp.width * img_tmp.bit_depth; x += 4)
{
img_data[img_index].r = img_tmp.row_pointers[y][x];
img_data[img_index].g = img_tmp.row_pointers[y][x + 1];
img_data[img_index].b = img_tmp.row_pointers[y][x + 2];
img_data[img_index].a = img_tmp.row_pointers[y][x + 3];
img_index++;
}
}
Т.е. я просто перевел в RGBA структуру с выравниванием по 16 байт, как требует sdk. И вот какой
результат вышел.
Правда, как вы могли заметить, некоторые элементы теряются (в основном обрезанные края текстуры). Например: "шеркалка" вовсе съехала. Да и сама картинка имеет нечеткое отображение.
О боже... Все оказалось намного проще.
Image::read_png_file как-то повернул / перевернул картинку. Я сейчас просто сижу и пытаюсь подобрать алгоритм, чтобы ее восстановить так, чтобы UV координаты оказались на нужных местах
PS: так и не понятно для чего нужно выравнивание...
Наконец-то. Оказалось, что в png_bytep, в котором хранилась текстура был далеко не "квадратным" динамическим массивом, и количество столбцов каждой строки было разным, поэтому пришлось добавить немного ухищрений для того, чтобы правильно пересобрать текстуру.
public:
//...
// для хранения количества столбцов каждой строки
png_size_t *row_weight_size;
//...
// в void Image::read_png_file
row_weight_size = (png_size_t *)malloc(sizeof(png_size_t) * height);
row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
for (int y = 0; y < height; y++) {
row_weight_size[y] = png_get_rowbytes(png, info);
row_pointers[y] = (png_byte*)malloc(row_weight_size[y]);
}
//...
// функция восстановления текстуры
void Image::png_data(struct COLOR *img_data)
{
unsigned long img_data_index = 0;
for (int y = height - 1; y >= 0; y--) {
for (int x = 0; x < row_weight_size[y]; x+=4) {
img_data[img_data_index].r = row_pointers[y][x];
img_data[img_data_index].g = row_pointers[y][x + 1];
img_data[img_data_index].b = row_pointers[y][x + 2];
img_data[img_data_index].a = row_pointers[y][x + 3];
img_data_index++;
}
}
}
И непосредственно сам вызов:
Image img_tmp;
img_tmp.read_png_file("Models/matchbook.png");
struct COLOR *img_data = (struct COLOR*)malloc(sizeof(struct COLOR) * img_tmp.height * img_tmp.width);
img_tmp.png_data(img_data);
Спичечный коробок
Автобус