Я часами пытался нарисовать свои модели .obj в OpenGL.Я подумал, что, возможно, что-то не так с моим скриптом Python (который конвертирует модели obj в файлы C ++).Или что-то не так с файлом .obj.Я не знаю, как заставить это работать должным образом.OpenGL рисует объект, но он полностью отличается от объекта, который я создал в SketchUp.
Короче говоря: мой скрипт правильно конвертирует .obj (если я не знаю других правил).Сначала я собираю строки с вершинами в одном списке строк, то же самое с vn и vt.Я собираю также данные о лицах.Позже я сопоставлю соответствующие v, vn и vt с лицами.Наконец, он генерирует .h и .cpp файлы с данными.Что может быть не так?
Вот файл .obj: https://pastebin.com/g0HwpRqB
# Alias OBJ Model File
# Exported from SketchUp, (c) 2000-2012 Trimble Navigation Limited
# File units = meters
mtllib sciany1.mtl
g Mesh1 Model
usemtl Brick_Tumbled
v 2.06118 0 0.0146645
vt -2.25413 -0.0320745
vn 0 -1 -0
v -3.02882 0 0.0146645
vt 3.31236 -0.0320745
v -3.02882 0 -9.68534
vt 3.31236 21.184
v 2.06118 0 -9.68534
vt -2.25413 21.184
f 1/1/1 2/2/1 3/3/1 4/4/1
usemtl FrontColor
vt -119.245 0
vn 0 0 1
vt 81.1487 0
v 2.06118 2.76 0.0146645
vt 81.1487 108.661
v -3.02882 2.76 0.0146645
vt -119.245 108.661
f 2/5/2 1/6/2 5/7/2 6/8/2
usemtl Brick_Tumbled
vt -0.0160372 0
vn 1 0 -0
vt 10.592 0
v 2.06118 2.76 -9.68534
vt 10.592 6.03675
vt -0.0160372 6.03675
f 1/9/3 4/10/3 7/11/3 5/12/3
usemtl FrontColor
vt -81.1487 0
vn 0 0 -1
vt 119.245 0
v -3.02882 2.76 -9.68534
vt 119.245 108.661
vt -81.1487 108.661
f 4/13/4 3/14/4 8/15/4 7/16/4
usemtl Brick_Tumbled
vt -10.592 0
vn -1 0 -0
vt 0.0160372 0
vt 0.0160372 6.03675
vt -10.592 6.03675
f 3/17/5 2/18/5 6/19/5 8/20/5
vt -3.31236 -0.0320745
vn 0 1 -0
vt 2.25413 -0.0320745
vt 2.25413 21.184
vt -3.31236 21.184
f 6/21/6 5/22/6 7/23/6 8/24/6
Вот сгенерированный файл .cpp: https://pastebin.com/YPXnuuzP
#include "sciany1.h"
namespace Models {
Sciany1 sciany1;
Sciany1::Sciany1() {
vertices=Sciany1Internal::vertices;
normals=Sciany1Internal::normals;
vertexNormals=Sciany1Internal::vertexNormals;
texCoords=Sciany1Internal::texCoords;
colors=Sciany1Internal::colors;
vertexCount=Sciany1Internal::vertexCount;
}
Sciany1::~Sciany1() {
}
void Sciany1::drawSolid() {
glEnable(GL_NORMALIZE);
glEnableClientState(GL_VERTEX_ARRAY);
//glEnableClientState(GL_COLOR_ARRAY);
//glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(4,GL_FLOAT,0,vertices);
//glColorPointer(4,GL_FLOAT,0,colors);
glNormalPointer(GL_FLOAT,sizeof(float)*4,vertexNormals);
glTexCoordPointer(2,GL_FLOAT,0,texCoords);
glDrawArrays(GL_TRIANGLES,0,vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
//glDisableClientState(GL_COLOR_ARRAY);
//glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
namespace Sciany1Internal {
unsigned int vertexCount=18;
float vertices[]={
2.06,0,0.01,
-3.02,0,0.01,
-3.02,0,-9.68,
-3.02,0,0.01,
2.06,0,0.01,
2.06,2.76,0.01,
2.06,0,0.01,
2.06,0,-9.68,
2.06,2.76,-9.68,
2.06,0,-9.68,
-3.02,0,-9.68,
-3.02,2.76,-9.68,
-3.02,0,-9.68,
-3.02,0,0.01,
-3.02,2.76,0.01,
-3.02,2.76,0.01,
2.06,2.76,0.01,
2.06,2.76,-9.68,
};
float colors[]={
};
float normals[]={
0,-1,-0,
0,-1,-0,
0,-1,-0,
0,0,1,
0,0,1,
0,0,1,
1,0,-0,
1,0,-0,
1,0,-0,
0,0,-1,
0,0,-1,
0,0,-1,
-1,0,-0,
-1,0,-0,
-1,0,-0,
0,1,-0,
0,1,-0,
0,1,-0,
};
float vertexNormals[]={
};
float texCoords[]={
-2.25,-0.03,
3.31,-0.03,
3.31,21.18,
-119.24,0,
81.14,0,
81.14,108.66,
-0.01,0,
10.59,0,
10.59,6.03,
-81.14,0,
119.24,0,
119.24,108.66,
-10.59,0,
0.01,0,
0.01,6.03,
-3.31,-0.03,
2.25,-0.03,
2.25,21.18,
};
}
}
Вотсгенерированный .h файл: https://pastebin.com/jaf73yf2
#ifndef SCIANY1_H
#define SCIANY1_H
//Sciany1 model made out of triangles
//Contains arrays:
//vertices - vertex positions in homogenous coordinates
//normals - vertex normals in homogenous coordinates
//texCoords - texturing coordinates
//colors - vertex colors (rgba)
//Culling GL_CW
//TBN friendly
#include "model.h"
namespace Models {
namespace Sciany1Internal {
extern float vertices[];
extern float normals[];
extern float vertexNormals[];
extern float texCoords[];
extern float colors[];
extern unsigned int vertexCount;
}
class Sciany1: public Model {
public:
Sciany1();
virtual ~Sciany1();
virtual void drawSolid();
};
extern Sciany1 sciany1;
}
#endif
Вот мой скрипт на Python: https://pastebin.com/LivefwgY
def round_number(string_number):
if "\n" in string_number:
string_number = string_number.replace("\n", "")
if "." in string_number:
parts = string_number.split(".")
if len(parts[1]) > 2:
return parts[0] + "." + parts[1][:2]
return string_number
def line_to_good_line(line):
processed_numbers=[]
numbers=line.split(" ")
for number in numbers:
if number and number != "\n":
processed_numbers.append(round_number(number))
output = str.join(",", processed_numbers) + ",\n"
return output
def add_numbers_in_the_end(lines, additional_number):
new_lines=[]
for line in lines:
new_lines.append(line[:-1]+","+additional_number+",\n")
return new_lines
def prepare_output_from_faces(data, faces):
ready_list = []
for face in faces:
for number in face:
ready_list.append(data[int(number)-1])
return str.join("", ready_list)
def convert_to_cpp(filename):
model_name = filename[0].upper() + filename[1:-4]
upper_model_name = model_name.upper()
lower_model_name = model_name.lower()
vertices_lines = []
normals_lines = []
tex_coords_lines = []
vertices_faces = []
normals_faces = []
tex_coords_faces = []
vertices="" # final string output
normals="" # final string output
tex_coords="" # final string output
with open(filename, "r") as file:
lines = file.readlines()
for line in lines:
if line[0:2] == "v ":
line = line_to_good_line(line[2:])
vertices_lines.append(line)
elif line[0:3] == "vn ":
line = line_to_good_line(line[3:])
normals_lines.append(line);
elif line[0:3] == "vt ":
line = line_to_good_line(line[3:])
tex_coords_lines.append(line)
elif line[0:2] == "f ":
face = line[2:].replace("\n", "").split(" ")
face[0] = face[0].split("/")
face[1] = face[1].split("/")
face[2] = face[2].split("/")
vertex_face = [face[0][0], face[1][0], face[2][0]]
tex_coord_face = [face[0][1], face[1][1], face[2][1]]
normals_face = [face[0][2], face[1][2], face[2][2]]
vertices_faces.append(vertex_face)
tex_coords_faces.append(tex_coord_face)
normals_faces.append(normals_face)
vertices = prepare_output_from_faces(vertices_lines, vertices_faces)
normals = prepare_output_from_faces(normals_lines, normals_faces)
tex_coords = prepare_output_from_faces(tex_coords_lines, tex_coords_faces)
vertices_number = vertices.count("\n")
with open(lower_model_name + ".h", "w") as header_file:
data = """
/*
Niniejszy program jest wolnym oprogramowaniem; możesz go
rozprowadzać dalej i / lub modyfikować na warunkach Powszechnej
Licencji Publicznej GNU, wydanej przez Fundację Wolnego
Oprogramowania - według wersji 2 tej Licencji lub(według twojego
wyboru) którejś z późniejszych wersji.
Niniejszy program rozpowszechniany jest z nadzieją, iż będzie on
użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej
gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH
ZASTOSOWAŃ.W celu uzyskania bliższych informacji sięgnij do
Powszechnej Licencji Publicznej GNU.
Z pewnością wraz z niniejszym programem otrzymałeś też egzemplarz
Powszechnej Licencji Publicznej GNU(GNU General Public License);
jeśli nie - napisz do Free Software Foundation, Inc., 59 Temple
Place, Fifth face, Boston, MA 02110 - 1301 USA
*/
#ifndef {}_H
#define {}_H
//{} model made out of triangles
//Contains arrays:
//vertices - vertex positions in homogenous coordinates
//normals - vertex normals in homogenous coordinates
//texCoords - texturing coordinates
//colors - vertex colors (rgba)
//Culling GL_CW
//TBN friendly
#include "model.h"
namespace Models {{
namespace {}Internal {{
extern float vertices[];
extern float normals[];
extern float vertexNormals[];
extern float texCoords[];
extern float colors[];
extern unsigned int vertexCount;
}}
class {}: public Model {{
public:
{}();
virtual ~{}();
virtual void drawSolid();
}};
extern {} {};
}}
#endif
""".format(upper_model_name, upper_model_name,
model_name, model_name, model_name, model_name,
model_name, model_name, lower_model_name)
header_file.write(data)
with open(model_name + ".cpp", "w") as cpp_file:
data = """
/*
Niniejszy program jest wolnym oprogramowaniem; możesz go
rozprowadzać dalej i / lub modyfikować na warunkach Powszechnej
Licencji Publicznej GNU, wydanej przez Fundację Wolnego
Oprogramowania - według wersji 2 tej Licencji lub(według twojego
wyboru) którejś z późniejszych wersji.
Niniejszy program rozpowszechniany jest z nadzieją, iż będzie on
użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej
gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH
ZASTOSOWAŃ.W celu uzyskania bliższych informacji sięgnij do
Powszechnej Licencji Publicznej GNU.
Z pewnością wraz z niniejszym programem otrzymałeś też egzemplarz
Powszechnej Licencji Publicznej GNU(GNU General Public License);
jeśli nie - napisz do Free Software Foundation, Inc., 59 Temple
Place, Fifth face, Boston, MA 02110 - 1301 USA
*/
#include "{}.h"
namespace Models {{
{} {};
{}::{}() {{
vertices={}Internal::vertices;
normals={}Internal::normals;
vertexNormals={}Internal::vertexNormals;
texCoords={}Internal::texCoords;
colors={}Internal::colors;
vertexCount={}Internal::vertexCount;
}}
{}::~{}() {{
}}
void {}::drawSolid() {{
glEnable(GL_NORMALIZE);
glEnableClientState(GL_VERTEX_ARRAY);
//glEnableClientState(GL_COLOR_ARRAY);
//glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(4,GL_FLOAT,0,vertices);
//glColorPointer(4,GL_FLOAT,0,colors);
glNormalPointer(GL_FLOAT,sizeof(float)*4,vertexNormals);
glTexCoordPointer(2,GL_FLOAT,0,texCoords);
glDrawArrays(GL_TRIANGLES,0,vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
//glDisableClientState(GL_COLOR_ARRAY);
//glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}}
namespace {}Internal {{
unsigned int vertexCount={};
float vertices[]={{
{}
}};
float colors[]={{
}};
float normals[]={{
{}
}};
float vertexNormals[]={{
}};
float texCoords[]={{
{}
}};
}}
}}
""".format(lower_model_name, model_name, lower_model_name, model_name,
model_name, model_name, model_name, model_name, model_name, model_name,
model_name, model_name, model_name, model_name, model_name, vertices_number,
vertices, normals, tex_coords)
cpp_file.write(data)
filename = input("Input the name of the obj file: ")
convert_to_cpp(filename)