好友
阅读权限20
听众
最后登录1970-1-1
|
本帖最后由 沉默的菜鸟 于 2019-9-7 21:46 编辑
用OpenGL画了一个立方体,实现了鼠标手动旋转以及自动旋转等功能。
但碰到了一个棘手问题,就是当立方体自动旋转时,只有两面有颜色,另外的面为黑色,但我都设置了颜色的呀??
求大神帮助。。。
代码:
ObjLoader.h
[C++] 纯文本查看 复制代码 #pragma once
#include <GL/glut.h>
#include <vector>
#include <array>
#include <string>
using namespace std;
class ObjLoader
{
public:
ObjLoader() {};
ObjLoader( const string& filepath);
~ObjLoader();
void Paint();
private:
vector<array<GLfloat, 3>> vertexContainer;
vector<array<GLint, 3>> triangleContainer;
};
ObjLoader.cpp
[C++] 纯文本查看 复制代码
#include "ObjLoader.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <direct.h>
ObjLoader::ObjLoader(const string& filepath)
{
string line;
ifstream f;
f.open(filepath, ios::in);
if (!f.is_open())
{
cout << "文件打开失败,请检查文件路径!" << endl;
return;
}
while (!f.eof())
{
getline(f, line);
cout << line << endl;
istringstream sin(line);
if (line[0]=='v')
{
char flag;
float x, y, z;
sin >> flag >> x >> y >> z;
this->vertexContainer.push_back(array<GLfloat, 3>{x, y, z});
}
else if (line[0]=='f')
{
char flag;
int p1, p2, p3;
sin >> flag >> p1 >> p2 >> p3;
this->triangleContainer.push_back(array<GLint, 3>{p1-1, p2-1, p3-1});
//因为顶点索引在obj文件中是从1开始的,而我们存放的顶点array是从0开始的,因此要减1
}
}
}
ObjLoader::~ObjLoader()
{
char buffer[100];
_getcwd(buffer,100);
string path = string(buffer);
string filename = "/data.obj";
ofstream out;
out.open(path+filename,ios::out);
if (!out.is_open())
{
cout << "写入路径错误!" << endl;
return;
}
for(auto vertex : this->vertexContainer)
{
out << "v " << vertex[0] << " " << vertex[1] << " " << vertex[2] << endl;
}
for (auto triangle:this->triangleContainer)
{
out << "f " << triangle[0]+1 << " " << triangle[1]+1 << " " << triangle[2]+1 << endl;
}
out.close();
cout << "写入文件成功!" << endl;
}
void ObjLoader::Paint()
{
glBegin(GL_TRIANGLES); //开始绘制
for (size_t i = 0; i < this->triangleContainer.size(); i++)
{
array<GLfloat, 3>VN;//三角形的单位法向量
//三个顶点
array<GLfloat, 3>Vertex1;
array<GLfloat, 3>Vertex2;
array<GLfloat, 3>Vertex3;
if (this->triangleContainer[i].size() != 3)
{
cout << "数据错误!" << endl;
}
else
{
GLint firstVertexIndex = (triangleContainer[i])[0]; //取出顶点索引
GLint secondVertexIndex = (triangleContainer[i])[1];
GLint thirdVertexIndex = (triangleContainer[i])[2];
for (size_t j = 0; j < 3; j++)
{
Vertex1[j] = vertexContainer[firstVertexIndex][j]; //顶点一
Vertex2[j] = vertexContainer[secondVertexIndex][j]; //顶点二
Vertex3[j] = vertexContainer[thirdVertexIndex][j]; //顶点三
}
GLfloat vec1[3], vec2[3], vec3[3];//计算法向量
for (size_t z = 0; z < 3; z++)
{
vec1[z] = Vertex1[z] - Vertex2[z];//v1v2向量
vec2[z] = Vertex1[z] - Vertex3[z];//v1v3向量
}
//由v1v2向量与v1v3向量叉乘即可得平面的法向量
vec3[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
vec3[1] = vec2[0] * vec1[2] - vec2[2] * vec1[0];
vec3[2] = vec2[1] * vec1[0] - vec2[0] * vec1[1];
//单位法向量
GLfloat D = sqrtf(pow(vec3[0], 2) + pow(vec3[1], 2) + pow(vec3[2], 2));
for (size_t n = 0; n < 3; n++)
{
VN[n] = vec3[n] / D;
}
int p = 7;//扩大倍数
glColor3ub(163, 85, 104);
glNormal3f(VN[0], VN[1], VN[2]);//绘制单位法向量
glColor3ub(163, 85, 104);
glVertex3f(Vertex1[0] *p, Vertex1[1] * p, Vertex1[2] * p);
glColor3ub(73,90,128);
glVertex3f(Vertex2[0] * p, Vertex2[1] * p, Vertex2[2] * p);
glColor3ub(221,240, 237);
glVertex3f(Vertex3[0] * p, Vertex3[1] * p, Vertex3[2] * p);
}
}
glEnd();
}
main.cpp
[C++] 纯文本查看 复制代码
#include "ObjLoader.h"
#include <iostream>
using namespace std;
ObjLoader objModel;
int angles = 0; //转动角度
int xyz[3] = { 0,1,0 };
//实现移动鼠标观察模型所需变量
static float c = 3.1415926f / 180.0f;
static float r = 1.0f;
static int degree = 90;
static int oldPosY = -1;
static int oldPosX = -1;
//安置光源
void setLightRes() {
GLfloat lightPosition[] = { 0.0f, 0.0f, 1.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
glEnable(GL_LIGHTING); //启用光源
glEnable(GL_LIGHT0); //使用指定灯光
}
//初始化
void init() {
cout << "please input the path of the obj file:";
string path;
cin >> path;
cout << endl;
objModel = ObjLoader(path);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow("ObjBuilder");
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
setLightRes();
glEnable(GL_DEPTH_TEST);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
}
void timerPoc(int id)
{
angles += 20;
angles %= 360;
glutPostRedisplay();
glutTimerFunc(200, timerPoc, 1);
}
void display()
{
glColor3f(1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -20.0f);
glRotatef(angles, xyz[0], xyz[1], xyz[2]);
setLightRes();
glPushMatrix();
gluLookAt(r * cos(c * degree), 0, r * sin(c * degree), 0.0f, 0.0f, 0.0f, 0.0f,1.0f, 0.0f);
objModel.Paint();//绘制obj模型
glPopMatrix();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y)
{
if (key == 114) {
glutTimerFunc(200, timerPoc, 1);
cout << "Unhandled key press r" << endl;
}
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, (GLdouble)width / (GLdouble)height, 1.0f, 200.0f);
glMatrixMode(GL_MODELVIEW);
}
//移动鼠标360观察模型
void moseMove(int button, int state, int x, int y)
{
if (state == GLUT_DOWN) {
oldPosX = x; oldPosY = y;
}
}
void changeViewPoint(int x, int y)
{
int temp = x - oldPosX;
degree += temp;
oldPosX = x;
oldPosY = y;
}
void myIdle()
{
glutPostRedisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutMouseFunc(moseMove);
glutMotionFunc(changeViewPoint);
glutIdleFunc(myIdle);
glutMainLoop();
return 0;
}
效果:
我觉得可能是光源的问题,但不知道怎么解决。。。
|
免费评分
-
查看全部评分
|