330 lines
8.2 KiB
C++
330 lines
8.2 KiB
C++
#include "RenderDevice.h"
|
|
|
|
#include "Utilities/Log.h"
|
|
|
|
#include "GL/gl.h"
|
|
#include "GL/glu.h"
|
|
|
|
namespace BlueCore
|
|
{
|
|
|
|
//------------------------------------------------------------------------------
|
|
void RenderDevice::WindowResizeSlot(int width, int height)
|
|
{
|
|
glViewport( 0, 0, width, height);
|
|
_ViewportWidth = width;
|
|
_ViewportHeight = height;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
RenderDevice::RenderDevice(RenderWindow* renderWindow) :
|
|
_RenderWindow(renderWindow)
|
|
{
|
|
if (_RenderWindow.valid())
|
|
{
|
|
_RenderWindow->WindowResizeSignal.connect(this,
|
|
&RenderDevice::WindowResizeSlot);
|
|
|
|
_RenderWindow->WindowCloseSignal.connect(this,
|
|
&RenderDevice::WindowCloseSlot);
|
|
|
|
_ViewportWidth = _RenderWindow->getWidth();
|
|
_ViewportHeight = _RenderWindow->getHeight();
|
|
glViewport( 0, 0, _ViewportWidth, _ViewportHeight);
|
|
}
|
|
|
|
clog << ">>> RenderDevice constructed..."<< endlog;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
RenderDevice::~RenderDevice()
|
|
{
|
|
clog << ">>> RenderDevice destructed..."<< endlog;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void RenderDevice::WindowCloseSlot()
|
|
{
|
|
DeviceShutdownSignal();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
int RenderDevice::getViewportWidth()
|
|
{
|
|
return _ViewportWidth;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
int RenderDevice::getViewportHeight()
|
|
{
|
|
return _ViewportHeight;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void RenderDevice::begin2D()
|
|
{
|
|
// prepare state
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
glNormal3f( 0.0, 0.0, 1.0);
|
|
|
|
// set projection matrix
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
//int newheight = (_width / 16.0) * 9.0;
|
|
gluOrtho2D( 0, _ViewportWidth-1, 0, _ViewportHeight-1);
|
|
|
|
// prepare model matrix
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void RenderDevice::end2D()
|
|
{
|
|
// restore projection matrix
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPopMatrix();
|
|
|
|
// restore model matrix
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPopMatrix();
|
|
|
|
// restore old state
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_LIGHTING);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void RenderDevice::clear()
|
|
{
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void RenderDevice::setAmbientLight(float r, float g, float b)
|
|
{
|
|
GLfloat lightAmbient[] =
|
|
{ r, g, b, 1.0f };
|
|
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightAmbient);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
/*
|
|
void RenderDevice::renderShadowVolume(Mesh *mesh,
|
|
const Vector3Float &direction, const Vector3Float &extrude)
|
|
{
|
|
// Calculate visibility
|
|
unsigned int i, frontface_count = 0;
|
|
for (i=0; i < mesh->shadowfaces.count(); i++)
|
|
{
|
|
if (mesh->shadowfaces[i].plane.distance(extrude) < 0)
|
|
{
|
|
shadow_faces[i].backFace = false;
|
|
frontface_count++;
|
|
}
|
|
else
|
|
{
|
|
shadow_faces[i].backFace = true;
|
|
}
|
|
}
|
|
|
|
unsigned int max_edges = (frontface_count) * 3;
|
|
if (_extrudeVertexBuffer.count() < (max_edges * 4))
|
|
{
|
|
clog << ">>> increase shadow buffers to "<< max_edges << " Edges"<< endline;
|
|
_extrudeVertexBuffer.create( (max_edges + 100) * 4);
|
|
}
|
|
|
|
if (_extrudeIndexBuffer.count() < (max_edges * 6))
|
|
_extrudeIndexBuffer.create( (max_edges + 100) * 6);
|
|
|
|
// fill the buffer
|
|
unsigned int j, k;
|
|
extrude_quad_count = 0;
|
|
Vertex *face_vertices[3];
|
|
for (i=0; i<shadow_faces.count(); i++)
|
|
{
|
|
if (shadow_faces[i].backFace == false)
|
|
{
|
|
for (j=0; j<3; j++)
|
|
{
|
|
k = shadow_faces[i].neighbours[j];
|
|
if ( (k == 0) || (shadow_faces[k-1].backFace == true))
|
|
{
|
|
unsigned int src_index_offset = i * 3;
|
|
face_vertices[0]
|
|
= &mesh->vertex_buffer[ mesh->index_buffer[ src_index_offset ] ];
|
|
face_vertices[1]
|
|
= &mesh->vertex_buffer[ mesh->index_buffer[ src_index_offset + 1] ];
|
|
face_vertices[2]
|
|
= &mesh->vertex_buffer[ mesh->index_buffer[ src_index_offset + 2] ];
|
|
|
|
#ifdef DEBUG_SILHOUETTE
|
|
glBegin( GL_LINES );
|
|
glVertex3f( face_vertices[j]->point.x, face_vertices[j]->point.y, face_vertices[j]->point.z );
|
|
glVertex3f( face_vertices[(j+1)%3]->point.x, face_vertices[(j+1)%3]->point.y, face_vertices[(j+1)%3]->point.z );
|
|
glEnd();
|
|
#endif
|
|
|
|
unsigned int vertex_offset = extrude_quad_count*4;
|
|
_extrudeVertexBuffer[vertex_offset] = face_vertices[j]->point;
|
|
_extrudeVertexBuffer[vertex_offset+1] = face_vertices[(j+1)%3]->point;
|
|
_extrudeVertexBuffer[vertex_offset+2] = face_vertices[(j+1)%3]->point + extrude_vector;
|
|
_extrudeVertexBuffer[vertex_offset+3] = face_vertices[j]->point
|
|
+ extrude_vector;
|
|
|
|
unsigned int index_offset = extrude_quad_count*6;
|
|
_extrudeIndexBuffer[index_offset] = vertex_offset;
|
|
_extrudeIndexBuffer[index_offset+1] = vertex_offset + 3;
|
|
_extrudeIndexBuffer[index_offset+2] = vertex_offset + 1;
|
|
_extrudeIndexBuffer[index_offset+3] = vertex_offset + 1;
|
|
_extrudeIndexBuffer[index_offset+4] = vertex_offset + 3;
|
|
_extrudeIndexBuffer[index_offset+5] = vertex_offset + 2;
|
|
|
|
extrude_quad_count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (_capIndexBuffer.count() < mesh->index_buffer.count() )
|
|
_capIndexBuffer.create(mesh->index_buffer.count() );
|
|
|
|
bf = 0;
|
|
ff = 0;
|
|
|
|
for (i=0; i<shadow_faces.count(); i++)
|
|
{
|
|
unsigned int dst_offset, src_offset = i*3;
|
|
|
|
if (shadow_faces[i].backFace == false)
|
|
{
|
|
dst_offset = ff*3;
|
|
ff++;
|
|
}
|
|
else
|
|
{
|
|
dst_offset = _capIndexBuffer.count() - (bf + 1)*3;
|
|
bf++;
|
|
}
|
|
|
|
_capIndexBuffer[dst_offset] = mesh->index_buffer[src_offset];
|
|
_capIndexBuffer[dst_offset+1] = mesh->index_buffer[src_offset+1];
|
|
_capIndexBuffer[dst_offset+2] = mesh->index_buffer[src_offset+2];
|
|
}
|
|
|
|
_lastOrientation = _AbsoluteRotation;
|
|
}
|
|
|
|
if (_extrudeVertexBuffer.count() > 0)
|
|
{
|
|
// draw the volume
|
|
glPushAttrib( GL_ALL_ATTRIB_BITS);
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glEnable( GL_DEPTH_TEST);
|
|
glDepthMask(GL_FALSE);
|
|
|
|
#if defined(DEBUG_SILHOUETTE) || defined(DEBUG_CAPS) || defined(DEBUG_VOLUME)
|
|
glColorMask( 1, 1, 1, 1 );
|
|
glDepthFunc(GL_LEQUAL);
|
|
#else
|
|
glColorMask(0, 0, 0, 0);
|
|
glDepthFunc(GL_LESS);
|
|
#endif
|
|
|
|
glEnable(GL_STENCIL_TEST);
|
|
glStencilFunc(GL_ALWAYS, 0, ~0);
|
|
glStencilMask( ~0);
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
glMatrixMode ( GL_MODELVIEW);
|
|
glPushMatrix();
|
|
Matrix4x4 m(_AbsoluteRotation, _AbsoluteTranslation);
|
|
glMultMatrixd ( ( GLdouble * ) &m.m );
|
|
|
|
glActiveTextureARB ( GL_TEXTURE2_ARB);
|
|
glDisable ( GL_TEXTURE_2D);
|
|
glActiveTextureARB ( GL_TEXTURE1_ARB);
|
|
glDisable ( GL_TEXTURE_2D);
|
|
glActiveTextureARB ( GL_TEXTURE0_ARB);
|
|
glDisable ( GL_TEXTURE_2D);
|
|
|
|
ShaderManager::getSingleton()->useShaderProgram( 0);
|
|
|
|
#ifndef DEBUG_SILHOUETTE
|
|
|
|
glEnableClientState( GL_VERTEX_ARRAY);
|
|
glDisableClientState( GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState( GL_NORMAL_ARRAY);
|
|
glDisableClientState( GL_ARRAY_BUFFER_ARB);
|
|
glDisableClientState( GL_ELEMENT_ARRAY_BUFFER_ARB);
|
|
|
|
for (int p=0; p<2; p++)
|
|
{
|
|
if (p==0)
|
|
{
|
|
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
|
glCullFace(GL_FRONT);
|
|
//glColorMask(0, 1, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
|
|
glCullFace(GL_BACK);
|
|
//glColorMask(1, 0, 0, 0);
|
|
}
|
|
|
|
if (GLEW_ARB_vertex_buffer_object )
|
|
{
|
|
glBindBufferARB ( GL_ARRAY_BUFFER_ARB, 0);
|
|
glBindBufferARB ( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
|
}
|
|
// #if !defined(DEBUG_CAPS) || defined(DEBUG_VOLUME)
|
|
glVertexPointer ( 3, GL_FLOAT, 0, _extrudeVertexBuffer.data() );
|
|
glDrawElements (
|
|
GL_TRIANGLES,
|
|
extrude_quad_count * 6,
|
|
GL_UNSIGNED_SHORT,
|
|
_extrudeIndexBuffer.data());
|
|
// #endif
|
|
|
|
// #if !defined(DEBUG_VOLUME) || defined(DEBUG_CAPS)
|
|
// draw caps
|
|
mesh->vertex_buffer.bind();
|
|
//glVertexPointer ( 3, GL_FLOAT, sizeof(Vertex), mesh->vertex_buffer.data() );
|
|
glDrawElements (
|
|
GL_TRIANGLES,
|
|
ff*3,
|
|
GL_UNSIGNED_SHORT,
|
|
_capIndexBuffer.data());
|
|
//&_capIndexBuffer[_capIndexBuffer.count() - bf*3]);
|
|
|
|
glPushMatrix();
|
|
glTranslatef(extrude_vector.x, extrude_vector.y, extrude_vector.z);
|
|
glDrawElements (
|
|
GL_TRIANGLES,
|
|
bf*3,
|
|
GL_UNSIGNED_SHORT,
|
|
&_capIndexBuffer[_capIndexBuffer.count() - bf*3]);
|
|
//_capIndexBuffer.data() );
|
|
glPopMatrix();
|
|
// #endif
|
|
}
|
|
|
|
#endif
|
|
|
|
glPopAttrib();
|
|
|
|
glPopMatrix();
|
|
}
|
|
*/
|
|
} // namespace BlueCore
|