我写了一个obj加载器,据我所知,所有加载工作都很好,但是当我尝试绘制纹理时,它不起作用。
我看着魔鬼,加载后没有任何错误,一切都有数据,但是当我绘制它时不会显示图像只是黑色。
你们有什么可以推荐的吗? 我已经看了几件事,但找不到解决办法。
我如何做事 我有一个纹理创建的mtl
Loader.h
#pragma once
#include "typedef.h"
#include <string>
#include <vector>
#include <fstream>
#include "MTL.h"
#include "../freeglut.h"
#include <iostream> // this is just for testing, you can remove this with all the cout's
class Loader
{
public:
/**
* \brief string location of the obj file
*
* In Order for you to Load the 3D object you need to specify its location
* in a string.
*
*
*/
Loader( std::string input);
~Loader(void);
void draw(); // this function takes the obj file and draws it
//this can be ignored, it does not make any changes to the problem
void move(float x, float y, float z);
void getPos();
void setPos(float x, float y, float z); // set position
void find_box(float &maxX,float &minX,float &maxY, float &minY, float &maxZ,float &minZ);
private:
std::ifstream m_inFile;
// the list of vectors that i will be using
std::vector<points> m_points;
std::vector<normal> m_normals;
std::vector<coordinate> m_coords;
std::vector<MTL> m_mtl;
std::vector<face> m_faces;
void process(std::string input);
void processMTL(std::string input);
void inputPoints(points temp);
void inputNormals(normal temp);
void inputCoordinates(coordinate temp);
void createFaces(face temp);
};
Loader.cpp
void Loader::process(std::string input)
{
std::string identifier; //used to identify where the input should go
points temppoint;
normal tempnormal;
coordinate tempcoord;
face tempface;
std::string read; // used to read the curent line
int readNum; // this is the number that has just been read in
char skip; // a char to skip thr /
int i;
int count= 1;
//other things to take into account
//****************************************
std::string l_name;
bool firstRun = true;
std::string parse;
//**************************************
m_inFile.open(input);
//creation of the reading loop
m_inFile >> identifier;
do {
// check to see what the opening is
if (identifier =="#")
{
getline(m_inFile,read); // use this to read the whole line
}
else if(identifier == "v")
{
m_inFile >> temppoint.x >> temppoint.y >> temppoint.z;
inputPoints(temppoint);
}
else if(identifier == "vn")
{
m_inFile >> tempnormal.vn[0] >> tempnormal.vn[1] >> tempnormal.vn[2];
inputNormals(tempnormal);
}
else if (identifier == "vt")
{
m_inFile >> tempcoord.vt[0] >> tempcoord.vt[1] >> tempcoord.vt[2];
inputCoordinates(tempcoord);
}
else if(identifier == "f")
{
for( i =0; i < 3; i++)
{
count++;
m_inFile >> readNum;
if(readNum == 0)
break;
readNum--;
tempface.p[i].x = m_points[readNum].x;
tempface.p[i].y = m_points[readNum].y;
tempface.p[i].z = m_points[readNum].z;
m_inFile >> skip >> readNum;
readNum--;
tempface.coord[i].vt[0] = m_coords[readNum].vt[0];
tempface.coord[i].vt[1] = m_coords[readNum].vt[1];
tempface.coord[i].vt[2] = m_coords[readNum].vt[2];
m_inFile >> skip >> readNum;
readNum--;
tempface.norm[i].vn[0] = m_normals[readNum].vn[0];
tempface.norm[i].vn[1] = m_normals[readNum].vn[1];
tempface.norm[i].vn[2] = m_normals[readNum].vn[2];
}
tempface.name = l_name; // this gives the mtl name to the face so it can be compared and applied later
createFaces(tempface);
}
else if(identifier =="mtllib")
{
m_inFile >> identifier;
identifier = "test/" + identifier;
processMTL(identifier);
}
else if(identifier == "usemtl")
{
// chnages the mtl that is being applied
m_inFile >> read;
l_name = read; // so the face can have
}
else
{
getline(m_inFile,read);
std::cout << "Not Processed From Loader" << identifier << " " << read <<std::endl;
}
m_inFile >> identifier;
} while (!m_inFile.eof());
//m_inFile.close();
//m_inFile.~basic_ifstream();
}
void Loader::draw()
{
int i;
int j;
int k;
std::string currentTex;
glEnable(GL_TEXTURE_2D);
//glDisable(GL_TEXTURE_2D);
//glBegin(GL_TRIANGLES);
for (i=0; i < m_faces.size();i++)
{
//bind a certain image
for (k=0; k<m_mtl.size();k++)
{
if (m_mtl[k].compare(m_faces[i].name) == true)
{
//these next two lines do the same thing
//m_mtl[k].draw();
glBindTexture(GL_TEXTURE_2D,m_mtl[k].getGLID());
//break; // break out of the loop
}
}
glBegin(GL_TRIANGLES);
for(j = 0 ; j < 3; j++)
{
glNormal3f(m_faces[i].norm[j].vn[0],m_faces[i].norm[j].vn[1],m_faces[i].norm[j].vn[2]);
glTexCoord2f(m_faces[i].coord[j].vt[0],m_faces[i].coord[j].vt[1]);
glVertex3f(m_faces[i].p[j].x,m_faces[i].p[j].y,m_faces[i].p[j].z);
}
glEnd();
}
}
void Loader::processMTL(std::string input)
{
std::string identifier;
std::string read; //for reading whole lines
MTL mtlTemp;
std::ifstream l_inMtl;
//for reading in numbers to give to the mtl
float ka0, ka1, ka2;
float kd0, kd1, kd2;
float ks0, ks1, ks2;
//so that an empty mtl is not pushed back into the vector
bool firstRun = true;
l_inMtl.open(input);
l_inMtl >> identifier;
do{
if(identifier == "#")
{
getline(l_inMtl,read);
}
else if(identifier == "newmtl")
{
//checks to see if it has run before if it has not run before don't push back the last read
if (firstRun == false)
m_mtl.push_back(mtlTemp);
else
firstRun = false;
l_inMtl >> identifier;
mtlTemp.setName(identifier);
}
else if(identifier == "Ka")
{
l_inMtl >>ka0 >> ka1 >> ka2;
mtlTemp.setKa(ka0,ka1,ka2);
}
else if(identifier == "Kd")
{
l_inMtl >> kd0 >>kd1 >> kd2;
mtlTemp.setKd(kd0,kd1,kd2);
}
else if(identifier =="Ks")
{
l_inMtl >> ks0 >> ks1 >> ks2;
mtlTemp.setKs(ks0, ks1, ks2);
}
else if(identifier == "map_Ka")
{
getline(l_inMtl,identifier);
//l_inMtl >> identifier;
mtlTemp.setLoc(identifier);
}
else
{
getline(l_inMtl,read);
std::cout << "Not Processed MTL" << identifier << " " << read << std::endl;
}
l_inMtl >> identifier;
}while(!l_inMtl.eof());
l_inMtl.close();
m_mtl.push_back(mtlTemp); // so the last one is pushed back
}
MTL.h
#pragma once
#include "../freeglut.h"
#include <string>
#include <fstream>
#include "typedef.h"
#include "../lib/IL/il.h"
#include <iostream>
//#include <IL/il.h>
class MTL
{
public:
MTL(); //name of the file
~MTL(void);
void bind(std::string bindType);// somehow set the bind type eg tile stretch ect
void setVar(float ka0, float ka1, float ka2,float kd0, float kd1, float kd2, float ks0, float ks1, float ks2); // takes in all the inputs and sets them to the class
void setLoc(std::string inLocation); // set the location
void setName(std::string inName);
void setKa(float ka0, float ka1, float ka2);
void setKd(float kd0, float kd1, float kd2);
void setKs(float ks0, float ks1, float ks2);
void setNs(float inNs);
bool compare(std::string inName); // compare the string with another
void draw(); // change the binds
GLuint getGLID() { return texture;};
private:
std::string name;
std::string location; // the location of the image
float ka[3];
float kd[3];
float ks[3];
// must have freeglut in order to use this
BYTE *pixmap; // contains the data (not yet set)
GLuint texture;
//two functions that you need to load and display
void LoadThing();
void createTex(int width, int height, int chan);
};
MTL.cpp
#include "MTL.h"
MTL::MTL() /
{
}
MTL::~MTL()
{
}
void MTL::setName(std::string inName)
{
name = inName;
}
void MTL::setLoc(std::string inLocation)
{
location = inLocation;
LoadThing();
}
bool MTL::compare(std::string inName) // compare the string with another
{
//return true if they are the same
if (name == inName)
return true;
else
return false;
}
void MTL::draw() // change the binds
{
glBindTexture(GL_TEXTURE_2D, texture);
}
void MTL::setKa(float ka0, float ka1, float ka2)
{
ka[0] = ka0;
ka[1] = ka1;
ka[2] = ka2;
}
void MTL::setKd(float kd0, float kd1, float kd2)
{
kd[0] = kd0;
kd[1] = kd1;
kd[2] = kd2;
}
void MTL::setKs(float ks0, float ks1, float ks2)
{
ks[0] = ks0;
ks[1] = ks1;
ks[2] = ks2;
}
void MTL::LoadThing()
{
ILuint devImg;
ilGenImages(1,&devImg);
ilBindImage(devImg);
int error = ilLoadImage("marble_floor2.png");
int e = ilGetError();
pixmap = ilGetData();
int width = ilGetInteger(IL_IMAGE_WIDTH);
int height = ilGetInteger(IL_IMAGE_HEIGHT);
int chan = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
createTex(width,height,chan);
}
void MTL::createTex(int width, int height, int chan)
{
glEnable(GL_TEXTURE_2D);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, chan, width, height, 0, (chan == 4)?GL_RGBA: GL_RGB, GL_UNSIGNED_BYTE, pixmap);
//no clue
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
编辑:首先感谢那些拒绝投票给我的人,花了我一段时间才意识到这一点,但我有很多功能,你们不需要看到它们,所以它已经减少了。
我认为可能存在问题的地方 画() 来自Loader的process() 和 画() LoadThings() 来自MTL的createTex()
编辑: 好吧我们找到了解决方案,原因是opengl在显示纹理时使用了glColor,所以正在做的是... opengl
溶液: 在glBegin(poly?triangle)上方添加这一行 glColor3f(1.0F,1.0F,1.0F)
答案 0 :(得分:0)
好吧我们找到了解决方案,原因是opengl在显示纹理时使用了glColor,所以正在做的是... opengl
解决方案:在glBegin(poly?triangle)上方添加此行glColor3f(1.0f,1.0f,1.0f)