![]() |
![]() |
![]() |
![]() |
![]() |
FTP | ![]() |
![]() |
CCD | ![]() |
![]() |
Buscar | ![]() |
![]() |
Trucos | ![]() |
![]() |
Trabajo | ![]() |
![]() |
Foros | ![]() |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Buscar | Temas de Hoy | Marcar Foros Como Leídos |
![]() |
|
Herramientas | Buscar en Tema | Desplegado |
|
#1
|
|||
|
|||
Inportador de modelos OBJ de Blender multi-texturas
El otro dia me puse durante la noche, que es cuando mejor programo, por aquello de que no hay muchos ruidos de la calle, coches etc
y hice este codigo en C++ Builder para importar modelos OBJ exportados desde Blender y otros programas el cual carga el modelo OBJ y tambien la informacion referente a las texturas del archivo MTL asociado, funciona muy bien ya lo veréis si lo probais de momento dejo en vuestras manos el tema de los includes necesarios (yo los tengo en la carpeta include de Rad Studio en Archivos de Programa (x86) y recordad que tambien necesita el glew.c agregado al proyecto y los lib de glew32 etc no esta del todo "saneado" el codigo ya que hay cosas ahi y funciones que estan pero no utilizo, espero que podais analizarlo bien pero asi como esta funciona por ejemplo la funcion LoadBMPTexture ya no la utiliza sino que usa la de LoadPNGTexture y la de DrawModelWithTexture tampoco la uso sino que uso la de DrawModelWithMultipleTextures Unit11.h Código:
//--------------------------------------------------------------------------- #ifndef Unit11H #define Unit11H //--------------------------------------------------------------------------- #include <System.Classes.hpp> #include <Vcl.Controls.hpp> #include <Vcl.StdCtrls.hpp> #include <Vcl.Forms.hpp> #include "acPNG.hpp" #include <Vcl.ExtCtrls.hpp> //--------------------------------------------------------------------------- class TForm11 : public TForm { __published: // IDE-managed Components TImage *Image1; TPanel *Panel1; void __fastcall FormDestroy(TObject *Sender); private: // User declarations public: // User declarations __fastcall TForm11(TComponent* Owner); void __fastcall Timer1Timer(TObject *Sender); void __fastcall InitScene(); void __fastcall DrawScene(); void __fastcall DrawScene_New(); }; //--------------------------------------------------------------------------- extern PACKAGE TForm11 *Form11; //--------------------------------------------------------------------------- #endif Código:
//--------------------------------------------------------------------------- #include <vcl.h> #include <Vcl.Imaging.pngimage.hpp> #include <GL/glew.h> #include <stdio.h> #include <conio.h> #include <stdlib.h> // Incluir GLFW #include <GL/glfw3.h> // Incluir GLM #include <glm/glm.hpp> using namespace glm; #include <GL/glut.h> #include <GL/gl.h> // OpenGL #include <GL/glu.h> // Utilidades de OpenGL #include <tiny_obj_loader.h> #include <FreeImage.h> // Para cargar imágenes BMP o JPG //Estos include puede que no sean del todo necesarios ya que los planeo usar para cuando texturice #include <iostream> #include <fstream> // Necesario para std::ifstream #include <sstream> #include <vector> // Necesario para std::vector #include <algorithm> // Necesario para std::swap #include <string> #pragma hdrstop #include "Unit11.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "acPNG" #pragma resource "*.dfm" TForm11 *Form11; void InitializeOpenGL(TPanel* Panel); bool LoadOBJModel(const std::string& filename, const std::string& texturePath); GLuint LoadBMPTexture(const char* filename); GLuint LoadTexture(const char* filename); void CloseOpenGL(void); void LoadMTL(const std::string& path); void DrawModelWithMaterials(); void DrawModelWithMultipleTextures(); void InitTextures(); GLuint LoadPNGTexture(const char* filename); // Variables globales para el manejo del contexto de OpenGL HDC hdc; HGLRC hrc; GLuint textureID, textureID1, textureID2, defaultTextureID; //esto ya no es necesario, ahora maneja las texturas con InitTextures() float rotationAngle = 0.0f; bool inicio = true; std::vector<GLuint> textureIDs; // Vector para almacenar las IDs de las texturas // Crear un objeto TPngImage para cargar la imagen PNG TPngImage *pngImage = new TPngImage(); // Variables globales para almacenar el modelo tinyobj::attrib_t attrib; std::vector<tinyobj::shape_t> shapes; std::vector<tinyobj::material_t> materials; std::string warn, err; // Estructura para almacenar el modelo cargado struct ModelData { std::vector<float> vertices; std::vector<float> normals; std::vector<float> texcoords; std::vector<unsigned int> indices; }; ModelData model; // Estructura para almacenar vértices y coordenadas de textura struct Vertex { float x, y, z; }; struct TexCoord { float u, v; }; std::vector<Vertex> vertices; std::vector<TexCoord> texCoords; //--------------------------------------------------------------------------- __fastcall TForm11::TForm11(TComponent* Owner) : TForm(Owner) { InitializeOpenGL(Panel1); InitScene(); TTimer *Timer1 = new TTimer(this); Timer1->Interval = 16; // Aproximadamente 60 fps Timer1->OnTimer = Timer1Timer; } //--------------------------------------------------------------------------- void LoadOBJModel2(const std::string& path, const std::string& path_mtl) { bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, path.c_str(), path_mtl.c_str()); if (!ret) { ShowMessage("Error al cargar modelo OBJ"); return; } if (!warn.empty()) { ShowMessage("Error al cargar modelo OBJ:" + AnsiString(warn.c_str())); return; } if (!err.empty()) { ShowMessage("Error al cargar modelo OBJ" + AnsiString(err.c_str())); return; } // Procesar vértices y coordenadas de textura for (const auto& shape : shapes) { for (const auto& index : shape.mesh.indices) { Vertex v = { attrib.vertices[3 * index.vertex_index + 0], attrib.vertices[3 * index.vertex_index + 1], attrib.vertices[3 * index.vertex_index + 2] }; vertices.push_back(v); if (!attrib.texcoords.empty()) { TexCoord tc = { attrib.texcoords[2 * index.texcoord_index + 0], attrib.texcoords[2 * index.texcoord_index + 1] }; texCoords.push_back(tc); } } } } void InitTextures() { // Reserva espacio para las texturas (tantas como materiales tenga el modelo) textureIDs.resize(materials.size()); for (size_t i = 0; i < materials.size(); i++) { if (!materials[i].diffuse_texname.empty()) { // Cargar la textura BMP usando función LoadPNGTexture textureIDs[i] = LoadPNGTexture(materials[i].diffuse_texname.c_str()); //ShowMessage(materials[i].diffuse_texname.c_str()); if (textureIDs[i] == 0) { ShowMessage("Error loading texture: " + AnsiString(materials[i].diffuse_texname.c_str())); } } } } GLuint LoadPNGTexture(const char* filename) { GLuint texID = 0; // cargar la imagen PNG pngImage->LoadFromFile(filename); // Crear un array para los datos de la textura unsigned char* data = new unsigned char[pngImage->Width * pngImage->Height * 4]; // RGBA // Copiar los datos de la imagen a la textura for (int y = 0; y < pngImage->Height; y++) { for (int x = 0; x < pngImage->Width; x++) { // Asumimos que la imagen está en formato RGBA TColor color = pngImage->Pixels[x][pngImage->Height - 1 - y]; // Ajustar el orden de y para la coordenada Y data[(y * pngImage->Width + x) * 4 + 0] = GetRValue(color);; // R data[(y * pngImage->Width + x) * 4 + 1] = GetGValue(color);; // G data[(y * pngImage->Width + x) * 4 + 2] = GetBValue(color);; // B data[(y * pngImage->Width + x) * 4 + 3] = (color >> 24) & 0xFF; // A } } // Generar y enlazar la textura glGenTextures(1, &texID); glBindTexture(GL_TEXTURE_2D, texID); // Establecer los parámetros de la textura glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Cargar la textura en OpenGL glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pngImage->Width, pngImage->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); delete[] data; return(texID); } GLuint LoadBMPTexture(const char* filename) { GLuint texID = 0; FILE* file = fopen(filename, "rb"); if (!file) { ShowMessage("Error al abrir archivo de textura BMP"); return(0); } unsigned char header[54]; fread(header, sizeof(unsigned char), 54, file); int width = *(int*)&header[18]; int height = *(int*)&header[22]; int imageSize = *(int*)&header[34]; unsigned char* data = new unsigned char[imageSize]; fread(data, sizeof(unsigned char), imageSize, file); fclose(file); // Generar y enlazar la textura glGenTextures(1, &texID); glBindTexture(GL_TEXTURE_2D, texID); // Establecer los parámetros de la textura glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Cargar la textura en OpenGL glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data); delete[] data; return(texID); } void SetupMaterial() { // Configura el color ambiental del material GLfloat mat_ambient[] = { 0.1f, 0.1f, 0.1f, 1.0f }; // Color ambiental del material glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); // Configura el color difuso del material GLfloat mat_diffuse[] = { 0.8f, 0.2f, 0.2f, 1.0f }; // Color difuso del material (rojo) glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); // Configura el color especular del material GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // Color especular del material glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); // Define el brillo del material GLfloat mat_shininess[] = { 50.0f }; // Aumentar el brillo del material glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); } void SetupLighting() { glEnable(GL_LIGHTING); // Activa el sistema de iluminación glEnable(GL_LIGHT0); // Activa la luz 0 // Define la posición de la luz GLfloat light_position[] = { 0.0f, 10.0f, 5.0f, 1.0f }; // Posición de la luz en coordenadas homogéneas glLightfv(GL_LIGHT0, GL_POSITION, light_position); // Define el color de la luz ambiental GLfloat ambient_light[] = { 0.2f, 0.2f, 0.2f, 1.0f }; // Color suave para la luz ambiental glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_light); // Define el color de la luz difusa GLfloat diffuse_light[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // Luz blanca difusa glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light); // Define el color de la luz especular GLfloat specular_light[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // Luz blanca especular glLightfv(GL_LIGHT0, GL_SPECULAR, specular_light); } void DrawModelWithMultipleTextures() { glColor3f(1.0f, 1.0f, 1.0f); // Establece el color a blanco (RGB) glEnable(GL_TEXTURE_2D); // Recorre todas las formas (shapes) del modelo for (size_t s = 0; s < shapes.size(); s++) { // Obtén el ID del material para esta forma int material_id = shapes[s].mesh.material_ids[0]; // Si el material tiene una textura, usa esa textura if (material_id >= 0 && material_id < materials.size()) { if (!materials[material_id].diffuse_texname.empty()) { glBindTexture(GL_TEXTURE_2D, textureIDs[material_id]); } else { // Si no hay textura, usa un color base o alguna otra textura por defecto glBindTexture(GL_TEXTURE_2D, defaultTextureID); } } // Dibuja los triángulos de esta forma glBegin(GL_TRIANGLES); for (size_t i = 0; i < shapes[s].mesh.indices.size(); i++) { tinyobj::index_t idx = shapes[s].mesh.indices[i]; // Coordenadas de textura if (idx.texcoord_index >= 0) { glTexCoord2f(attrib.texcoords[2 * idx.texcoord_index], attrib.texcoords[2 * idx.texcoord_index + 1]); } // Vértices glVertex3f(attrib.vertices[3 * idx.vertex_index + 0], attrib.vertices[3 * idx.vertex_index + 1], attrib.vertices[3 * idx.vertex_index + 2]); } glEnd(); } } void DrawModelWithTexture(GLuint textureID) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textureID); // Usa la textura especificada glBegin(GL_TRIANGLES); for (size_t i = 0; i < vertices.size(); i++) { if (i < texCoords.size()) { glTexCoord2f(texCoords[i].u, texCoords[i].v); } glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z); } glEnd(); glDisable(GL_TEXTURE_2D); } void __fastcall TForm11::InitScene() { // Cargar el modelo y la textura LoadOBJModel2(".\\gfx\\models\\casa.obj", ".\\gfx\\models"); // Inicializar y cargar texturas InitTextures(); glEnable(GL_DEPTH_TEST); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); } void RenderScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); // Configurar la cámara gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); DrawModelWithMultipleTextures(); SwapBuffers(hdc); } void __fastcall TForm11::DrawScene_New() { // Limpiar con fondo transparente // Establecer el color de fondo glClearColor(0.5f, 0.7f, 1.0f, 1.0f); // Cambia esto al color que desees glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Limpia los buffers glLoadIdentity(); // Configurar la matriz de proyección glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, (double)Form11->Panel1->Width / (double)Form11->Panel1->Height, 0.1f, 100.0f); // Ajusta el campo de visión glMatrixMode(GL_MODELVIEW); //gluPerspective(45.0f, 800.0f / 600.0f, 1.0f, 100.0f); glLoadIdentity(); gluLookAt(0.0, 0.0, 12.0, // Cámara 0.0, 0.0, 0.0, // Mirando al centro de la escena 0.0, 1.0, 0.0); // Vector arriba // Aplicar rotación glRotatef(270.0f, 0.0f, 0.0f, 1.0f); glRotatef(30.0f, 0.0f, 1.0f, 0.0f); rotationAngle += 0.5f; // Incrementar ángulo para rotar continuamente glRotatef(rotationAngle, 1.0f, 0.0f, 0.0f); // Dibujar el modelo con la textura DrawModelWithMultipleTextures(); glDisable(GL_TEXTURE_2D); // Desactiva el texturizado //Form11->Label1->Caption = "Angulo de Rotacion: 270 Grados"; //Form11->Label2->Caption = "TextureID: " + FloatToStr(textureID1); //ShowMessage("OK"); //DrawModel_good(); // Llamar a la función que dibuja el modelo SwapBuffers(hdc); // Intercambia los buffers para mostrar la escena glFlush(); } //--------------------------------------------------------------------------- void __fastcall TForm11::Timer1Timer(TObject *Sender) { DrawScene_New(); // Dibuja el cubo cada vez que el temporizador se activa } //--------------------------------------------------------------------------- void InitializeOpenGL(TPanel* Panel) { hdc = GetDC(Panel->Handle); // Crear un contexto de OpenGL temporal PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1 }; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cDepthBits = 24; pfd.iLayerType = PFD_MAIN_PLANE; int pixelFormat = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, pixelFormat, &pfd); HGLRC tempContext = wglCreateContext(hdc); wglMakeCurrent(hdc, tempContext); // Inicializar GLEW GLenum err = glewInit(); if (err != GLEW_OK) { ShowMessage("Error al inicializar GLEW"); return; } wglMakeCurrent(NULL, NULL); wglDeleteContext(tempContext); HGLRC mainContext = wglCreateContext(hdc); wglMakeCurrent(hdc, mainContext); // Habilitar mezcla //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // En tu función de inicialización //glEnable(GL_LIGHTING); // Habilitar iluminación //glEnable(GL_LIGHT0); // Habilitar la luz 0 //SetupLighting(); //SetupMaterial(); } void CloseOpenGL(void) { wglMakeCurrent(NULL, NULL); wglDeleteContext(hrc); ReleaseDC(NULL, hdc); } //--------------------------------------------------------------------------- void __fastcall TForm11::FormDestroy(TObject *Sender) { CloseOpenGL(); } //--------------------------------------------------------------------------- Última edición por navbuoy fecha: 24-10-2024 a las 05:29:33. |
#2
|
||||
|
||||
Gracias por el código.
![]() ![]() ![]()
__________________
Germán Estévez => Web/Blog Guía de estilo, Guía alternativa Utiliza TAG's en tus mensajes. Contactar con el Clubdelphi ![]() P.D: Más tiempo dedicado a la pregunta=Mejores respuestas. |
![]() |
Herramientas | Buscar en Tema |
Desplegado | |
|
|
![]() |
||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Añadir texturas diffuse, normal y specular a un objeto tridimensional en GLScene | noob | Gráficos | 4 | 24-01-2012 12:35:09 |
Modelos de desarrollo, modelos de negocio y mitos del S.XXI | Casimiro Notevi | La Taberna | 0 | 14-01-2011 08:56:07 |
Problemas al aplicar texturas a un Dodecahedro en GLScene | kakarotv5 | Gráficos | 2 | 02-03-2007 15:20:52 |
Base de datos multi área (multi departamento) | Al González | Conexión con bases de datos | 0 | 19-03-2004 16:27:14 |
![]() |
|