Rendern Sie .obj-Dateien mit OpenGl
Posted: 15 Jan 2025, 15:36
Ich möchte .obj-Dateien mit C++ laden und ihre Formen und Materialien mit OpenGl in die Szene zeichnen. Zum Laden verwende ich den tinyobjectloader von syoyo. Das Laden funktioniert sehr gut und ich kann das Objekt mit einer statischen Farbe oder einer statischen diffusen Textur zeichnen.
So kann ich alle Wahrheiten und Texturkoordinaten mithilfe von Puffern in den Shader geben.
Mein Das Problem besteht nun darin, die richtige Farbe im Pixel-Shader einzustellen.
Die von der Loader-Klasse gegebenen Formen haben ein Netz und ein Meterial, die wie folgt definiert sind:
Ich möchte alle Farben und verschiedenen Texturen als Uniformen festlegen.
Zum Beispiel würde die diffuse Farbe wie folgt eingestellt werden:
Und die Texturen so:
Ich konnte auch ein Objekt laden, bei dem alle Formen eine diffuse Textur hatten. Also hier kein Problem. Mein Problem ist, wie man mit nicht gesetzten Texturen umgeht. Beispielsweise verfügen viele Objekte nicht über einen Spiegeltextursatz. Kann ich irgendwie eine Standardtextur erstellen?
Mein Pixel-Shader sieht im Moment so aus:
Es wird also nur die Textur angezeigt und dies funktioniert nur, wenn jede Form eine diffuse Textur hat. Aber wie kombiniere ich alle Farben und Texturen so miteinander, dass das Objekt genauso aussieht wie in meiner 3D-Software? Was passiert, wenn eine der Farben null ist oder wenn ein Sampler2D null ist?
So kann ich alle Wahrheiten und Texturkoordinaten mithilfe von Puffern in den Shader geben.
Mein Das Problem besteht nun darin, die richtige Farbe im Pixel-Shader einzustellen.
Die von der Loader-Klasse gegebenen Formen haben ein Netz und ein Meterial, die wie folgt definiert sind:
Code: Select all
typedef struct {
std::string name;
float ambient[3];
float diffuse[3];
float specular[3];
float transmittance[3];
float emission[3];
float shininess;
float ior; // index of refraction
float dissolve; // 1 == opaque; 0 == fully transparent
// illumination model (see http://www.fileformat.info/format/material/)
int illum;
std::string ambient_texname;
std::string diffuse_texname;
std::string specular_texname;
std::string normal_texname;
std::map unknown_parameter;
} material_t;
typedef struct
{
std::vector positions;
std::vector normals;
std::vector texcoords;
std::vector indices;
} mesh_t;
Zum Beispiel würde die diffuse Farbe wie folgt eingestellt werden:
Code: Select all
GLuint diffColLocation = glGetUniformLocation(programmId, "diffuseColor");
glUniform3f(diffColLocation, this->material.diffuse[0], this->material.diffuse[1], this->material.diffuse[2]);
Code: Select all
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this->ambientTextureID);
glUniform1i(this->diffuseTextureUniformIndex, 0);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, this->diffuseTextureID);
glUniform1i(this->diffuseTextureUniformIndex, 0);
etc.
Mein Pixel-Shader sieht im Moment so aus:
Code: Select all
#version 150 core
#extension GL_ARB_explicit_attrib_location: enable
// output to the (default) FBO in color buffer 0
layout (location = 0) out vec4 outColor;
in vec2 fragTextCoords;
uniform sampler2D ambientTex;
uniform sampler2D diffuseTex;
uniform sampler2D specularTex;
uniform vec3 ambientColor;
uniform vec3 diffuseColor;
uniform vec3 specularColor;
// main entry point for the fragment shader
void main() {
//vec3 tempColor ambientColor + diffuseTex * specularTex; //Is that correct?
//outcolor = tempColor * texture(diffuseTex, fragTextCoords); //Then this?
outcolor = texture(diffuseTex, fragTextCoords);
}