PDA

View Full Version : Having a problem with lighting - 3D objects C++



vvv9703
06-07-2016, 10:55 AM
I'm having a problem with lighting 3D objects. I'm not sure if the formula for normala's vector is correct or I'm probably missing something...



// GlmfcnView.cpp : implementation of the CGlmfcnView class
//

#include "stdafx.h"
#include "Glmfcn.h"

#include "GlmfcnDoc.h"
#include "GlmfcnView.h"
#include <gl/gl.h>
#include <gl/glu.h>
#include "glaux.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CGlmfcnView

IMPLEMENT_DYNCREATE(CGlmfcnView, CView)

BEGIN_MESSAGE_MAP(CGlmfcnView, CView)
//{{AFX_MSG_MAP(CGlmfcnView)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
ON_COMMAND(ID_CENTER, &CGlmfcnView::OnCenter)
ON_COMMAND(ID_ROTATE, &CGlmfcnView::OnRotate)
ON_COMMAND(ID_EXCEL, &CGlmfcnView::OnExcelClick)
END_MESSAGE_MAP()
float spin=0.0;
double tx1=-800, tx2=-1600;
double rot0 = 0, rot1 = 0, rot2 = 0;



/////////////////////////////////////////////////////////////////////////////
// CGlmfcnView construction/destruction

CGlmfcnView::CGlmfcnView()
{
// TODO: add construction code here

}

CGlmfcnView::~CGlmfcnView()
{
}

BOOL CGlmfcnView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs

cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
return CView::PreCreateWindow(cs);
}

BOOL CGlmfcnView::InitializeOpenGL()
{
CGlmfcnDoc* pDoc = GetDocument();
pDoc->m_pDC = new CClientDC(this);
m_hDC = pDoc->m_pDC->GetSafeHdc();

if ( NULL == pDoc->m_pDC ) // failure to get DC
{
::AfxMessageBox("Couldn't get a valid DC.");
return FALSE;
}

if ( !SetupPixelFormat() )
{
::AfxMessageBox("SetupPixelFormat failed.\n");
return FALSE;
}
m_hRC=wglGetCurrentContext();
if (m_hRC==NULL)
if ( 0 == (m_hRC = ::wglCreateContext( m_hDC ) ) )
{
::AfxMessageBox("wglCreateContext failed.");
return FALSE;
}


return makeCurrent();
}


BOOL CGlmfcnView::SetupPixelFormat()
{
// default pixel format for a single-buffered,
// OpenGL-supporting, hardware-accelerated,
// RGBA-mode format. Pass in a pointer to a different
// pixel format if you want something else
CGlmfcnDoc* pDoc = GetDocument();
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),// size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_DOUBLEBUFFER | // doubble buffer
PFD_SUPPORT_OPENGL, // support OpenGL
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
16, // 16-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};

int pixelformat;
PIXELFORMATDESCRIPTOR* pPFDtoUse;

// let the user override the default pixel format
// pPFDtoUse = (0 == pPFD)? &pfd : pPFD;
pPFDtoUse = &pfd ;

if ( 0 == (pixelformat =
::ChoosePixelFormat( m_hDC, pPFDtoUse )) )
{
::AfxMessageBox("ChoosePixelFormat failed.");
return FALSE;
}

if ( FALSE == ::SetPixelFormat( m_hDC,
pixelformat, pPFDtoUse ) )
{
::AfxMessageBox("SetPixelFormat failed.");
return FALSE;
}

return TRUE;
}

void CGlmfcnView::myReshape()
{
CGlmfcnDoc* pDoc = GetDocument();
// compute the aspect ratio
// this will keep all dimension scales equal
pDoc->m_AspectRatio = (GLdouble)pDoc->m_WindowWidth/(GLdouble)pDoc->m_WindowHeight;

// Now, set up the viewing area-select the full client area
::glViewport(0, 0, pDoc->m_WindowWidth, pDoc->m_WindowHeight);

if ( GL_NO_ERROR != ::glGetError() )
{
::AfxMessageBox("Error while trying to set viewport.");
}

// select the projection matrix as the recipient of
// matrix operations (there's three to choose from)
::glMatrixMode(GL_PROJECTION);
// initialize the projection matrix to a pristine state
::glLoadIdentity();
//::glTranslatef( 0.0f, -0.0f, 0.0f );
//::glRotatef( 90.0f, 1.0f, 0.0f, 0.0f );


// select the viewing volume. You do it after you
// get the aspect ratio and set the viewport
// ::gluPerspective( 45.0f, pDoc->m_AspectRatio, 0.1f, 20.0f );
float r=1.0/pDoc->m_AspectRatio;

/* if (pDoc->m_WindowWidth <= pDoc->m_WindowHeight)
glOrtho (-1800.0, 1800.0, -1800.0, 1800.0*r, -10.0, 2000.0);
else
glOrtho (-1800.0, 1800.0/r, -1800.0, 1800.0, -10.0, 2000.0);
*/
if (pDoc->m_WindowWidth <= pDoc->m_WindowHeight)
glOrtho (-1100, 1100.0, -200, 2000*r, -500.0, 500.0);
else
glOrtho (-1100, 1100.0/r, -100.0, 2000, -500.0, 500.0);

glMatrixMode(GL_MODELVIEW);

// NOTE: Other commands you could have here are
// glFrustum, which gives you much more control over
// the perspective view, or glOrtho which is used for
// parallel projections. No matter what you use, check
// the error status when you set the viewing frustum!

if ( GL_NO_ERROR != ::glGetError() )
{
::AfxMessageBox("Error while trying to set viewing frustum.");
return ;
}


// now select the modelview matrix and clear it
// this is the mode we do most of our calculations in
// so we leave it as the default mode.
::glMatrixMode(GL_MODELVIEW);
::glLoadIdentity();

// now perform a default viewing transformations
// ::glTranslatef( 0.0f, 0.0f, -5.0f );
//::glRotatef( 45.0f, 1.0f, 1.0f, 1.0f );

}

BOOL CGlmfcnView::makeCurrent()
{
CGlmfcnDoc* pDoc = GetDocument();
// HGLRC hglrc = wglGetCurrentContext();
// if (hglrc!=pDoc->m_hRC )
if ( FALSE == ::wglMakeCurrent(m_hDC, m_hRC ) )
{
::AfxMessageBox("wglMakeCurrent failed.");
return FALSE;
}

// specify black as clear color
::glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
// specify the back of the buffer as clear depth
::glClearDepth( 1.0f );
// enable depth testing
::glEnable( GL_DEPTH_TEST );

return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CGlmfcnView drawing




void normalize(float v[3]) {
GLfloat d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
if (d == 0.0) {
// error("zero length vector");
return;
}
v[0] /= d; v[1] /= d; v[2] /= d;
}



void CGlmfcnView::OnDraw(CDC* pDC)
{
long v1, v2, v3, nfaces;
double x, y, z;


CGlmfcnDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here pDoc->faces.size 0x00a19f00 std::vector<F3D,std::allocator<F3D> >::size(void) unsigned int (void)

// glClearColor(0.1, 0.1, 0.1, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix



// осветяване
GLfloat mat_specular[] = { 0.0, 1.0, 1.0, 1.0 }; // задава се отразената светлина
GLfloat mat_dif[] = { 0.0, 0.0, 1.0, 1.0 }; // задава се дифузионната светлина
GLfloat mat_shininess[] = { 50.0 }; // задава се лъскавина
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; // задава се позиция на източника на светлина

glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_dif);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);





//glRotatef(90.0,0.0,1.0,0.0);
//glRotatef(-90.0,1.0,0.0,0.0);

// axes x,y,z
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0.0,0.0,0.0); glVertex3f(400,0.0,0.0);
glEnd();
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0.0,0.0,0.0); glVertex3f(0.0,400,0.0);
glEnd();
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0.0,0.0,0.0); glVertex3f(0.0,0.0,400);
glEnd();


// glPolygonMode ( GL_FRONT_AND_BACK, GL_POINT);
glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL);

double xcoord=0;
double ycoord=0;
double zcoord=0;

glRotatef(spin,0,1,0);
glRotatef(-90,1,0,0);

for (int m = 0; m<pDoc->number_of_models; m++){
glPushMatrix();
switch (m) {
case 0: {glColor3f(0.0, 1.0, 1.0); //CYAN

//

break;}

case 1: {glColor3f(1.0, 0.0, 1.0); //MAGENTA


break;}

case 2: {glColor3f(1.0, 1.0, 0.0); //YELLOW


break;}

}

nfaces = pDoc->faces[m].size();
glBegin(GL_TRIANGLES);
for (long i = 0; i< nfaces; i++){
v1 = pDoc->faces[m][i].v1-1;
v2 = pDoc->faces[m][i].v2-1;
v3 = pDoc->faces[m][i].v3-1;

x = pDoc->vertex[m][v1].x - pDoc->mcx[m];
y = pDoc->vertex[m][v1].y - pDoc->mcy[m];
z = pDoc->vertex[m][v1].z;
glNormal3f( x,y,z); glVertex3f( x,y,z);


x = pDoc->vertex[m][v2].x - pDoc->mcx[m];
y = pDoc->vertex[m][v2].y - pDoc->mcy[m];
z = pDoc->vertex[m][v2].z;
glNormal3f( x,y,z); glVertex3f( x,y,z);


x = pDoc->vertex[m][v3].x - pDoc->mcx[m];
y = pDoc->vertex[m][v3].y - pDoc->mcy[m];
z = pDoc->vertex[m][v3].z;
glNormal3f( x,y,z); glVertex3f( x,y,z);



}
glEnd();
glPopMatrix();
}

BOOL ok=SwapBuffers(m_hDC);
}

/////////////////////////////////////////////////////////////////////////////
// CGlmfcnView diagnostics

#ifdef _DEBUG
void CGlmfcnView::AssertValid() const
{
CView::AssertValid();
}

void CGlmfcnView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}

CGlmfcnDoc* CGlmfcnView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGlmfcnDoc)));
return (CGlmfcnDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CGlmfcnView message handlers

int CGlmfcnView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here
InitializeOpenGL();

return 0;
}


void CGlmfcnView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);

// TODO: Add your message handler code here
CGlmfcnDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

if ( 0 >= cx || 0 >= cy )
{
return;
}

// save the width and height of the current window
pDoc->m_WindowWidth = cx;
pDoc->m_WindowHeight = cy;

myReshape();
}


BOOL CGlmfcnView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default

return TRUE;//CView::OnEraseBkgnd(pDC);
}



void CGlmfcnView::OnCenter()
{
tx1=0;
tx2=1;
Invalidate();
// TODO: Add your command handler code here
}


void CGlmfcnView::OnRotate()
{
spin+=30;
Invalidate();
// TODO: Add your command handler code here
}


double getValueFromString(char *oneline, char *headerText)
{
if (strstr(oneline, headerText) == 0)
{
return 0;
}
else
{
int length = strlen(oneline);
int index = 0;
for (int i = 0; i < length; i++)
{
if (oneline[i] == '=')
{
index = i;
}
}
std::string part1 = "";
std::string part2 = "";
for (int i = 0; i < index; i++)
{
part1 += oneline[i];
}
for (int i = index+1; i < length; i++)
{
part2 += oneline[i];
}
double result = atof(part2.c_str());
return result;
}
}

void WriteCSVInFile(FILE *fp, char *text)
{
fputs(text, fp);
}

void WriteCSVInFile(FILE *fp, double value)
{
fprintf(fp, "%f", value);
}


/*
void CGlmfcnView::OnExcelClick()
{
CGlmfcnDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);


char fileNames[3][100];
int number_of_models = pDoc->number_of_models;


for(int i = 0; i <= number_of_models;i++)
{
strcpy(fileNames[i], pDoc->fileNames[i]);
}

int lenght = strlen(fileNames[0]) - 1;

for(int i = 0; i <= number_of_models;i++)
{
strcpy(fileNames[i]+lenght-2,"ord");
}

char csvLocation[100];
strcpy(csvLocation,fileNames[0]);
lenght = strlen(csvLocatdion) - 1;
strcpy(csvLocation+lenght-2,"csv");

double Bust_Full[3];
double Stomach_Full[3];
double Hips_Full[3];
double Abdomen_Full[3];
double Waist_Full[3];

FILE *readStream;
FILE *writeStream;
char oneline[255];

writeStream = fopen(csvLocation, "wt");

for(int i = 0; i < number_of_models;i++)
{
readStream = fopen(fileNames[i], "rt");
if (readStream==NULL) MessageBox("ORD file not found");

while (fgets(oneline, 255, readStream)!=NULL)
{

double value = getValueFromString(oneline, "Bust_Full");
if (value !=0)
{
Bust_Full[i] = value;
}
value = getValueFromString(oneline, "Stomach_Full");
if (value != 0)
{
Stomach_Full[i] = value;
}
value = getValueFromString(oneline, "Hips_Full");
if (value != 0)
{
Hips_Full[i] = value;
}
value = getValueFromString(oneline, "Abdomen_Full");
if (value != 0)
{
Abdomen_Full[i] = value;
}
value = getValueFromString(oneline, "Waist_Full");
if (value != 0)
{
Waist_Full[i] = value;
}

}
fclose(readStream);
}

WriteCSVInFile(writeStream, "Гръдна Обиколка;");
for (int i = 0; i < number_of_models; i++)
{
WriteCSVInFile(writeStream, Bust_Full[i]);
WriteCSVInFile(writeStream, ";");
}
WriteCSVInFile(writeStream, "\n");

WriteCSVInFile(writeStream, "Стомах;");
for (int i = 0; i < number_of_models; i++)
{
WriteCSVInFile(writeStream, Stomach_Full[i]);
WriteCSVInFile(writeStream, ";");
}
WriteCSVInFile(writeStream, "\n");

WriteCSVInFile(writeStream, "Ханш;");
for (int i = 0; i < number_of_models; i++)
{
WriteCSVInFile(writeStream, Hips_Full[i]);
WriteCSVInFile(writeStream, ";");
}
WriteCSVInFile(writeStream, "\n");

WriteCSVInFile(writeStream, "Корем;");
for (int i = 0; i < number_of_models; i++)
{
WriteCSVInFile(writeStream, Abdomen_Full[i]);
WriteCSVInFile(writeStream, ";");
}
WriteCSVInFile(writeStream, "\n");

WriteCSVInFile(writeStream, "Талия;");
for (int i = 0; i < number_of_models; i++)
{
WriteCSVInFile(writeStream, Waist_Full[i]);
WriteCSVInFile(writeStream, ";");
}
WriteCSVInFile(writeStream, "\n");
fclose(writeStream);

}
/*