Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros temas > Trucos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Los mejores trucos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 24-10-2024
navbuoy navbuoy is offline
Miembro
 
Registrado: mar 2024
Posts: 280
Poder: 2
navbuoy Va por buen camino
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.
Responder Con Cita
  #2  
Antiguo 24-10-2024
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.874
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
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.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
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


La franja horaria es GMT +2. Ahora son las 14:00:21.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi