I got a problem with my opengl wrapper class... Basically, I've been designing an portable API for all my needs. Audio, Graphics, GUI, Resolutions, LANning. etc. But my OpenGL wrapper class is in real need of help.
It does everything wonderfully, except the following:
when the win32 window is fullscreen and borderless the initial buffer flickers accross the ever changing current rendered screen,
and i need help with my font loader, I cant get the draw text procedure work.
Help me out, I will give credit where due, thanks.
Here's code from my windows class that I think will matter:
<br />
void register_stapi_classes();<br />
HWND create_window(const c8* class_name, const c8* title, const DWORD extra, const DWORD style, const vector_2d<s32>& tl, const vector_2d<s32>& br,HWND parent =0);<br />
<br />
<br />
window::window(const_string _caption, bool _border, bool _resizable, const_vector _tl, const_vector _br) throw(win_error)<br />
: mborder(_border), mresizable( (mborder)?_resizable:false), mclosed(false), mcaption(_caption), parent(0), current_cursor(new cursor), icon_file("")<br />
{ <br />
register_stapi_classes();
<br />
DWORD style = WS_POPUP;
<br />
if(mborder)<br />
style |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
if(mborder && mresizable)<br />
style |= WS_MAXIMIZEBOX |WS_THICKFRAME;
<br />
ready = false;<br />
<br />
wnd = create_window(sapi_main, mcaption.c_str(), 0, style | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, _tl, _br);
<br />
<br />
<br />
mdimensions = new wdimension(wnd);<br />
mcommoncontrol = new wcommoncontrol(wnd);<br />
<br />
ShowWindow ( (HWND)wnd, false); <br />
mcommoncontrol->visible(false);<br />
<br />
UpdateWindow( (HWND)wnd);
mdimensions->set_dimensions(_tl,_br); <br />
<br />
SetActiveWindow( (HWND)wnd);<br />
SetForegroundWindow( (HWND)wnd);<br />
<br />
win_hash.insert( (HWND)wnd, this);
run();<br />
<br />
mcommoncontrol->visible(true);
}<br />
<br />
window::~window()<br />
{<br />
win_hash.erase( (HWND)wnd);<br />
if(IsWindow((HWND)wnd))<br />
DestroyWindow((HWND)wnd);<br />
<br />
delete mdimensions;<br />
delete mcommoncontrol;<br />
delete current_cursor;<br />
}<br />
<br />
bool window::run()<br />
{<br />
<br />
if(!mclosed)<br />
{<br />
MSG messages;<br />
HWND _wnd = (HWND) wnd;<br />
<br />
for(;PeekMessage(&messages, _wnd, 0, 0, PM_REMOVE);)<br />
{<br />
TranslateMessage(&messages);<br />
DispatchMessage(&messages);<br />
}<br />
<br />
event event;<br />
event.id = eget_form;<br />
event.info[efi_handle] = (u32)this;<br />
event.info[efi_type] = efe_run;<br />
post_event(eget_form, &event);<br />
}<br />
<br />
return !mclosed;<br />
}<br />
<br />
void window::set_border(const bool _border) throw(win_error)<br />
{<br />
if(_border == mborder)<br />
return;<br />
<br />
mborder = _border;<br />
if(!mborder)<br />
mresizable = false;<br />
<br />
DWORD style = WS_POPUP;
<br />
if(mborder)<br />
{<br />
style = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
if(mresizable)<br />
style |= WS_MAXIMIZEBOX | WS_THICKFRAME;<br />
}<br />
<br />
style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;<br />
<br />
ShowWindow ( (HWND)wnd, false);<br />
UpdateWindow( (HWND)wnd);
<br />
<br />
if (!SetWindowLong( (HWND)wnd, GWL_STYLE, style))<br />
throw win_error("Unable to change window style");<br />
<br />
mdimensions->set_dimensions(mdimensions->get_topleft(), mdimensions->get_bottomright());<br />
<br />
ShowWindow ( (HWND)wnd, true);
UpdateWindow( (HWND)wnd);
<br />
SetActiveWindow( (HWND)wnd);<br />
SetForegroundWindow( (HWND)wnd);<br />
}<br />
And here's from my opengl code:
<br />
<br />
#include <iostream><br />
<br />
#include "sapi.h"<br />
<br />
#include <gl/gl.h><br />
#include <gl/glu.h><br />
<br />
#include "sapi_opengltexture.h"<br />
#include "sapi_openglmaterial_renderers.h"<br />
#include "sapi_opengldriver.h"<br />
#include "sstudio/hashmap.h"<br />
<br />
#ifdef _WINDOWS_<br />
# include <windows.h><br />
# include <gl/glext.h><br />
#endif<br />
<br />
namespace sanet<br />
{<br />
namespace sapi<br />
{<br />
<br />
PFNGLACTIVETEXTUREARBPROC pglActiveTextureARB;<br />
PFNGLCLIENTACTIVETEXTUREARBPROC pglClientActiveTextureARB;<br />
PFNGLMULTITEXCOORD2DPROC pglMultiTexCoord2f;<br />
<br />
void glActiveTextureARB(GLenum e)<br />
{<br />
if(pglActiveTextureARB)<br />
pglActiveTextureARB(e);<br />
}<br />
<br />
void glClientActiveTextureARB(GLenum e)<br />
{<br />
if(pglClientActiveTextureARB)<br />
pglClientActiveTextureARB(e);<br />
}<br />
<br />
static void set_hint_levels(s32 level);<br />
static void anti_alias(bool yes);<br />
static void set3Dmode(void);<br />
<br />
#ifdef _WINDOWS_<br />
<br />
struct wingl<br />
{<br />
HWND window;<br />
HDC device;<br />
HGLRC renderer;<br />
iwindow* sapi_window;<br />
<br />
GLYPHMETRICSFLOAT agmf[256];<br />
};<br />
<br />
static wingl* temp_wingl;<br />
static hashmap<wingl,opengldriver*> glmap;<br />
<br />
<br />
static void init_extensions();<br />
<br />
typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int);<br />
PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT;<br />
<br />
wingl* get_wingl(vp p)<br />
{<br />
return reinterpret_cast<wingl*>(p);<br />
}<br />
<br />
opengldriver::opengldriver(const iwindow* _win, bool stencil_buffer) throw(gl_error)<br />
: lights_on(0), ers(ers_3d), stencil(stencil_buffer), tmatrix(this, emt_world), pmatrix(this, emt_projection), vmatrix(this, emt_view),<br />
multitex(false), anistropic(false), anistropic_level(16.0f)<br />
{<br />
if(!_win)<br />
throw gl_error("Invalid Window Handle");<br />
<br />
PIXELFORMATDESCRIPTOR pfd;<br />
<br />
ZeroMemory (&pfd, sizeof (pfd));<br />
pfd.nSize = sizeof (pfd);<br />
pfd.nVersion = 1;<br />
pfd.dwFlags = PFD_DRAW_TO_WINDOW | <br />
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;<br />
pfd.iPixelType = PFD_TYPE_RGBA;<br />
pfd.cColorBits = 16;<br />
pfd.cDepthBits = 16;<br />
pfd.cStencilBits = (stencil?1:0);<br />
pfd.iLayerType = PFD_MAIN_PLANE;<br />
<br />
temp_wingl = new wingl;<br />
temp_wingl->sapi_window = (iwindow*)_win;<br />
temp_wingl->sapi_window->grab();<br />
temp_wingl->window = (HWND)_win->get_window();<br />
temp_wingl->device = GetDC((HWND)_win->get_window());<br />
<br />
bool tried_no_stencil = false;<br />
retry:;
<br />
GLuint PixelFormat = ChoosePixelFormat(temp_wingl->device, &pfd);<br />
SetPixelFormat(temp_wingl->device, PixelFormat, &pfd);<br />
<br />
if(!PixelFormat && tried_no_stencil)<br />
throw gl_error("Unable to set pixel format!");<br />
else if(!PixelFormat)<br />
{<br />
tried_no_stencil = true;<br />
pfd.cStencilBits = 0;<br />
stencil = false;<br />
goto retry;<br />
}<br />
<br />
temp_wingl->renderer = wglCreateContext(temp_wingl->device);<br />
<br />
if(!temp_wingl->renderer)<br />
throw gl_error("Unable to create an OpenGL rendering context!");<br />
<br />
internal = temp_wingl;<br />
<br />
make_current();<br />
<br />
load_support();<br />
init_extensions();<br />
if(!pglActiveTextureARB || !pglClientActiveTextureARB)<br />
multitex = false;<br />
<br />
add_material_renderer(new opengl_mr__solid(this));<br />
<br />
<br />
<br />
if(wglSwapIntervalEXT)<br />
wglSwapIntervalEXT(1);<br />
<br />
glClearDepth(1.0f);<br />
glEnable(GL_DEPTH_TEST);<br />
glDepthFunc(GL_LEQUAL);<br />
<br />
set_viewport(vector_2d<u32>(0,0), _win->get_dimensions()->get_bottomright());<br />
set_render_state(ers_3d);<br />
<br />
glShadeModel(GL_SMOOTH);<br />
<br />
static GLfloat data[4] = {0.0f, 0.0f, 0.0f, 1.0f};<br />
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, data);<br />
<br />
reset = true;<br />
<br />
set_material(current_material);<br />
<br />
add_material_renderer(new opengl_mr__reflection2layer(this));<br />
add_material_renderer(new opengl_mr__transparent_add(this));<br />
add_material_renderer(new opengl_mr__transparent_alpha_ref(this));<br />
add_material_renderer(new opengl_mr__transparent_vertex_alpha(this));<br />
<br />
pmatrix = get_perspective_fov_projection(60.0f, (f96)viewport[1].x / viewport[1].y, 1.0f, 5000.0f, epd_righthanded);<br />
<br />
f96 fog[] = {1.0f, 1000.0f};<br />
set_fog(eft_linear, color(127,127,127,255), fog);<br />
<br />
anti_alias(true);<br />
set_antialias(false);<br />
<br />
glEnable(GL_COLOR_MATERIAL);<br />
glEnable(GL_TEXTURE_2D);<br />
<br />
text_list = glGenLists(256);<br />
<br />
SelectObject (temp_wingl->device, GetStockObject (SYSTEM_FONT));<br />
<br />
wglUseFontOutlines(temp_wingl->device, 0, 255, text_list, 0.0f, 0.015f, WGL_FONT_POLYGONS, temp_wingl->agmf);<br />
}<br />
<br />
void opengldriver::load_support()<br />
{<br />
const GLubyte* t = glGetString(GL_EXTENSIONS); <br />
s32 len = (s32)strlen((const char*)t);<br />
c8 *str = new c8[len+1];<br />
c8* p = str;<br />
<br />
for (s32 i=0; i<len; ++i)<br />
{<br />
str[i] = (char)t[i];<br />
<br />
if (str[i] == ' ')<br />
{<br />
str[i] = 0;<br />
if (strstr(p, "GL_ARB_multitexture"))<br />
multitex = true;<br />
<br />
else<br />
if (strstr(p, "GL_EXT_texture_filter_anisotropic"))<br />
anistropic = true;<br />
<br />
p = p + strlen(p) + 1;<br />
}<br />
}<br />
<br />
s32 i = 0;<br />
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &i);<br />
<br />
if( i < 2)<br />
{<br />
multitex = false;<br />
}<br />
}<br />
<br />
opengldriver::~opengldriver()<br />
{<br />
glDeleteLists(text_list, 256);<br />
for(s32 i = 0; i < renderers.size(); ++i)<br />
{<br />
renderers.position(i)->drop();<br />
renderers.erase(renderers.key(i));<br />
}<br />
<br />
temp_wingl = get_wingl(internal);<br />
<br />
wglMakeCurrent(0, 0);<br />
wglDeleteContext(temp_wingl->renderer);<br />
<br />
ReleaseDC(temp_wingl->window, temp_wingl->device);<br />
<br />
temp_wingl->sapi_window->drop();<br />
delete temp_wingl;<br />
}<br />
<br />
bool opengldriver::drop()<br />
{<br />
if(base::drop())<br />
{<br />
delete this;<br />
return true;<br />
}<br />
return false;<br />
}<br />
<br />
const evideo_driver opengldriver::get_videodriver() const<br />
{<br />
return evd_opengl;<br />
}<br />
<br />
bool opengldriver::get_support(const evideodriver_support& support) const<br />
{<br />
switch(support)<br />
{<br />
case evds_multitexture:<br />
return multitex;<br />
<br />
case evds_anistropy:<br />
return anistropic;<br />
<br />
case evds_3d:<br />
return true;<br />
<br />
default:<br />
return false;<br />
}<br />
}<br />
<br />
void opengldriver::make_current()<br />
{<br />
temp_wingl = get_wingl(internal);<br />
if(wglGetCurrentDC()!= temp_wingl->device)<br />
wglMakeCurrent(temp_wingl->device, temp_wingl->renderer);<br />
}<br />
<br />
void opengldriver::loadid()<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
glLoadIdentity();<br />
}<br />
<br />
void opengldriver::clear_buffer(ebuffer _buffer)<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
<br />
switch(_buffer)<br />
{<br />
case eb_color:<br />
glClear(GL_COLOR_BUFFER_BIT);<br />
return;<br />
<br />
case eb_depth:<br />
glClear(GL_DEPTH_BUFFER_BIT);<br />
return;<br />
<br />
case eb_stencil:<br />
glClear(GL_STENCIL_BUFFER_BIT);<br />
return;<br />
}<br />
}<br />
<br />
void opengldriver::clear_buffer(u32 ebuffer_flags)<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
<br />
if(ebuffer_flags & eb_color)<br />
glClear(GL_COLOR_BUFFER_BIT);<br />
<br />
if(ebuffer_flags & eb_depth)<br />
{<br />
GLboolean mask;<br />
glGetBooleanv(GL_DEPTH_WRITEMASK, &mask);<br />
<br />
if(!mask)<br />
glDepthMask(GL_TRUE);
<br />
glDisable(GL_BLEND);<br />
<br />
glFlush();<br />
glClear(GL_DEPTH_BUFFER_BIT);<br />
<br />
if(!mask)<br />
glDepthMask(GL_FALSE);<br />
}<br />
<br />
if(ebuffer_flags & eb_stencil)<br />
glClear(GL_STENCIL_BUFFER_BIT);<br />
}<br />
<br />
void opengldriver::color_buffer_backdrop(const color _color)<br />
{<br />
backdrop = _color;<br />
<br />
f32 inv = 1.0f / 255.0f;<br />
<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
glClearColor(backdrop.get_red()*inv, backdrop.get_green()*inv, backdrop.get_blue()*inv, backdrop.get_alpha()*inv);<br />
}<br />
<br />
void opengldriver::swap_buffer()<br />
{<br />
<br />
temp_wingl = get_wingl(internal);<br />
<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
<br />
SwapBuffers(temp_wingl->device);<br />
}<br />
<br />
void opengldriver::set_antialias(bool _antialias)<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
<br />
antialias = _antialias;<br />
if(antialias)<br />
set_hint_levels(GL_NICEST);<br />
else<br />
set_hint_levels(GL_FASTEST);<br />
}<br />
<br />
bool opengldriver::get_antialias() const<br />
{<br />
return antialias;<br />
}<br />
<br />
<br />
void opengldriver::draw_text(const string16& fmt, ...)<br />
{<br />
temp_wingl = get_wingl(internal);<br />
<br />
f32 length = 0;
c8* text = new c8[fmt.length()];
va_list ap;
<br />
va_start(ap, fmt.c_str());
vsprintf(text, fmt.c_str(), ap);
va_end(ap);
<br />
for (unsigned int loop=0;loop<(strlen(text));loop++)
{<br />
length += temp_wingl->agmf[text[loop]].gmfCellIncX;
}<br />
<br />
<br />
glPushAttrib(GL_LIST_BIT);
glListBase(text_list);
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
glPopAttrib();
<br />
delete text;<br />
}<br />
<br />
<br />
void opengldriver::set_render_state(erender_state _state)<br />
{<br />
ers = _state;<br />
<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
switch(_state)<br />
{<br />
case ers_3d:<br />
reset = true;<br />
set_material(current_material);<br />
append_matrix(emt_projection, pmatrix);<br />
return;<br />
}<br />
}<br />
<br />
void opengldriver::set_viewport(const_vector& _tl, const_vector& _br)<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
glViewport(_tl.x, _tl.y, _br.x, _br.y);<br />
viewport[0](_tl.x,_tl.y);<br />
viewport[1](_br.x,_br.y);<br />
}<br />
<br />
void opengldriver::append_matrix(const ematrice_type& matrix, const matrix4x4& _tm)<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
f32* mat;<br />
switch(matrix)<br />
{<br />
case emt_view:<br />
<br />
glMatrixMode(GL_MODELVIEW);<br />
if(&vmatrix != &_tm)<br />
vmatrix *= _tm;<br />
<br />
glLoadMatrixf(*((driver_specific*)&(vmatrix*tmatrix)));
break;<br />
<br />
case emt_world:<br />
glMatrixMode(GL_MODELVIEW);<br />
if(&tmatrix != &_tm)<br />
tmatrix *= _tm;<br />
<br />
glLoadMatrixf(*((driver_specific*)&(vmatrix*tmatrix)));
break;<br />
<br />
case emt_projection:<br />
glMatrixMode(GL_PROJECTION);<br />
if(&pmatrix != &_tm)<br />
pmatrix *= _tm;<br />
<br />
{<br />
driver_specific tmp(this, (ematrice_type)125);<br />
tmp = pmatrix;
mat = (f32*)(tmp);<br />
mat[12] *= -1.0f;<br />
<br />
glLoadMatrixf(mat);<br />
glMatrixMode(GL_MODELVIEW);<br />
}<br />
break;<br />
}<br />
}<br />
<br />
void opengldriver::clear_matrix(const ematrice_type& matrix)<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
switch(matrix)<br />
{<br />
case emt_view:<br />
vmatrix.load_identity();<br />
break;<br />
<br />
case emt_world:<br />
tmatrix.load_identity();<br />
break;<br />
<br />
case emt_projection:<br />
pmatrix.load_identity();<br />
break;<br />
}<br />
}<br />
<br />
const matrix4x4& opengldriver::get_matrix(const ematrice_type& matrix) const<br />
{<br />
switch(matrix)<br />
{<br />
case emt_view:<br />
return vmatrix;<br />
<br />
case emt_world:<br />
return tmatrix;<br />
<br />
case emt_projection:<br />
return pmatrix;<br />
}<br />
}<br />
<br />
matrix4x4& opengldriver::get_matrix(const ematrice_type& matrix)<br />
{<br />
switch(matrix)<br />
{<br />
case emt_view:<br />
return vmatrix;<br />
<br />
case emt_world:<br />
return tmatrix;<br />
<br />
case emt_projection:<br />
return pmatrix;<br />
}<br />
}<br />
<br />
const s32 opengldriver::get_max_lights() const<br />
{<br />
return GL_MAX_LIGHTS;<br />
}<br />
<br />
void opengldriver::clear_lights()<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
for (s32 i=0; i < lights_on; ++i)<br />
if(!free_lights.size())<br />
glDisable(GL_LIGHT0 + i);<br />
else<br />
glDisable(used_lights.position(i));<br />
<br />
lights_on = 0;<br />
}<br />
<br />
void opengldriver::set_ambient_light(const color _color)<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
<br />
GLfloat data[4] = {_color.get_red(), _color.get_green(), _color.get_blue(), _color.get_alpha()};<br />
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, data);<br />
}<br />
<br />
void opengldriver::remove_light(const slight& light)<br />
{<br />
if(!used_lights.is_key((slight*)&light))<br />
throw gl_error("This light has not been enabled yet.");<br />
s32 _light = used_lights[(slight*)&light];<br />
free_lights.push_back(_light);<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
glDisable(_light);<br />
--lights_on;<br />
}<br />
<br />
void opengldriver::add_light(const slight& light)<br />
{<br />
if (lights_on+1 >= GL_MAX_LIGHTS)<br />
throw gl_error("Lights have reached this version of OpenGL's implementation limit.");<br />
<br />
s32 _light = 0;<br />
<br />
if(free_lights.size())<br />
{<br />
_light = free_lights.back();<br />
free_lights.pop_back();<br />
}<br />
else<br />
_light = GL_LIGHT0 + lights_on;<br />
used_lights.insert((slight*)&light, _light);<br />
<br />
GLfloat data[4];<br />
<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
switch(light.type)<br />
{<br />
case elt_radiant:<br />
data[0] = light.position.x;<br />
data[1] = light.position.y;<br />
data[2] = light.position.z;<br />
data[3] = 1.0f;<br />
glLightfv(_light, GL_POSITION, data);<br />
break;<br />
<br />
case elt_spot:<br />
data[0] = -light.position.x;<br />
data[1] = -light.position.y;<br />
data[2] = -light.position.z;<br />
<br />
data[3] = 0.0f;<br />
glLightfv(_light, GL_POSITION, data);<br />
<br />
data[3] = 1.0f;<br />
glLightfv(_light, GL_SPOT_DIRECTION, data);<br />
glLightf(_light, GL_SPOT_CUTOFF, 180.0f);<br />
glLightf(_light, GL_SPOT_EXPONENT, 0.0f);<br />
break;<br />
<br />
default:<br />
throw gl_error("The current version of SAPI does not support that light type");<br />
}<br />
<br />
data[0] = light.diffuse_color.get_red();<br />
data[1] = light.diffuse_color.get_green();<br />
data[2] = light.diffuse_color.get_blue();<br />
data[3] = light.diffuse_color.get_alpha();<br />
glLightfv(_light, GL_DIFFUSE, data);<br />
<br />
#ifdef NOSPEC<br />
data[0] = light.specular_color.get_red();<br />
data[1] = light.specular_color.get_green();<br />
data[2] = light.specular_color.get_blue();<br />
data[3] = light.specular_color.get_alpha();<br />
#else<br />
data[0] = 0;
data[1] = 0;
data[2] = 0;
data[3] = 0;
#endif<br />
glLightfv(_light, GL_SPECULAR, data);<br />
<br />
data[0] = light.ambient_color.get_red();<br />
data[1] = light.ambient_color.get_green();<br />
data[2] = light.ambient_color.get_blue();<br />
data[3] = light.ambient_color.get_alpha();<br />
glLightfv(_light, GL_AMBIENT, data);<br />
<br />
glLightf(_light, GL_CONSTANT_ATTENUATION, 0.0f);<br />
glLightf(_light, GL_LINEAR_ATTENUATION, 1.0f / light.radius);<br />
glLightf(_light, GL_QUADRATIC_ATTENUATION, 0.0f);<br />
<br />
glEnable(_light);<br />
<br />
++lights_on;<br />
}<br />
<br />
template<class A><br />
void tset_fog(efog_type _type, const color& _c, A* params)<br />
{<br />
if(_type == eft_linear)<br />
glFogi(GL_FOG_MODE, GL_LINEAR);<br />
else<br />
glFogi(GL_FOG_MODE, (_type == eft_dense) ? GL_EXP : GL_EXP2);<br />
<br />
if(_type == eft_linear)<br />
{<br />
glFogf(GL_FOG_START, params[0]);<br />
glFogf(GL_FOG_END, params[1]);<br />
}<br />
else<br />
glFogf(GL_FOG_DENSITY, params[0]);<br />
<br />
static f32 inv = 1.0f / 255.0f;<br />
GLfloat data[4] = {_c.get_red() * inv, _c.get_green()*inv, _c.get_blue()*inv, _c.get_alpha()*inv};<br />
glFogfv(GL_FOG_COLOR, data);<br />
}<br />
<br />
void opengldriver::set_fog(efog_type _type, const color& _c, f32* params)<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
tset_fog(_type, _c, params);<br />
}<br />
<br />
void opengldriver::set_fog(efog_type _type, const color& _c, f64* params)<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
tset_fog(_type, _c, params);<br />
}<br />
<br />
void opengldriver::set_fog(efog_type _type, const color& _c, f96* params)<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
tset_fog(_type, _c, params);<br />
}<br />
<br />
void opengldriver::set_property(const evideodriver_set& property, const f64& _x)<br />
{<br />
switch(property)<br />
{<br />
case evds_anistropic_filter:<br />
anistropic_level = _x;<br />
return;<br />
}<br />
}<br />
<br />
f64 opengldriver::get_property(const evideodriver_get& property) const<br />
{<br />
switch(property)<br />
{<br />
case evdg_max_anistropic:<br />
{<br />
f32 anis = 0;<br />
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anis);<br />
return anis;<br />
}<br />
}<br />
}<br />
<br />
void opengldriver::set_material(const smaterial& mat)<br />
{<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
<br />
smaterial material = mat;<br />
<br />
if(material.textures.size())<br />
{<br />
<br />
use_texture(0, material.textures[0]);<br />
if(multitex && material.textures.size() > 1)<br />
{<br />
use_texture(1, material.textures[1]);<br />
}<br />
<br />
if(renderers.is_key(current_material.material_type) && renderers.is_key(material.material_type))<br />
renderers[material.material_type]->OnSetMaterial(current_material, material, renderers[current_material.material_type]);<br />
else if(renderers.is_key(material.material_type))<br />
renderers[material.material_type]->OnSetMaterial(current_material, material, 0x0);<br />
else<br />
renderers[emt_solid]->OnSetMaterial(current_material, material, 0x0);<br />
<br />
if(!material.textures[0])<br />
use_texture(0, 0);<br />
if(multitex && material.textures.size() > 1 && !material.textures[1])<br />
use_texture(1, 0);<br />
}<br />
else<br />
{<br />
use_texture(0, 0);<br />
if(multitex)<br />
{<br />
use_texture(1, 0);<br />
}<br />
}<br />
<br />
{<br />
GLfloat color[4];<br />
float inv = 1.0f / 255.0f;<br />
<br />
if(material.ambient_color != current_material.ambient_color || reset)<br />
{<br />
color[0] = material.ambient_color.get_red() * inv;<br />
color[1] = material.ambient_color.get_green() * inv;<br />
color[2] = material.ambient_color.get_blue() * inv;<br />
color[3] = material.ambient_color.get_alpha() * inv;<br />
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);<br />
}<br />
<br />
if(material.diffuse_color != current_material.diffuse_color || reset)<br />
{<br />
color[0] = material.diffuse_color.get_red() * inv;<br />
color[1] = material.diffuse_color.get_green() * inv;<br />
color[2] = material.diffuse_color.get_blue() * inv;<br />
color[3] = material.diffuse_color.get_alpha() * inv;<br />
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);<br />
}<br />
<br />
if(material.specular_color != current_material.specular_color || reset)<br />
{<br />
color[0] = material.specular_color.get_red() * inv;<br />
color[1] = material.specular_color.get_green() * inv;<br />
color[2] = material.specular_color.get_blue() * inv;<br />
color[3] = material.specular_color.get_alpha() * inv;<br />
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);<br />
}<br />
<br />
if(material.emissive_color != current_material.emissive_color || reset)<br />
{<br />
color[0] = material.emissive_color.get_red() * inv;<br />
color[1] = material.emissive_color.get_green() * inv;<br />
color[2] = material.emissive_color.get_blue() * inv;<br />
color[3] = material.emissive_color.get_alpha() * inv;<br />
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);<br />
}<br />
<br />
if(material.shininess != current_material.shininess || reset)<br />
{<br />
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material.shininess);<br />
if(material.shininess)<br />
{<br />
material.normalize = true;<br />
glEnable(GL_NORMALIZE);<br />
}<br />
}<br />
}<br />
<br />
{<br />
if(material.lighting != current_material.lighting || reset)<br />
if(material.lighting)<br />
glEnable(GL_LIGHTING);<br />
else<br />
glDisable(GL_LIGHTING);<br />
}<br />
<br />
{<br />
if(material.cull != current_material.cull || reset)<br />
if(material.cull)<br />
glEnable(GL_CULL_FACE);<br />
else<br />
glDisable(GL_CULL_FACE);<br />
}<br />
<br />
{<br />
if(material.wireframe != current_material.wireframe || reset)<br />
if(material.wireframe)<br />
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);<br />
else<br />
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);<br />
}<br />
<br />
{<br />
if(material.fogged != current_material.fogged || reset)<br />
if(material.fogged)<br />
glEnable(GL_FOG);<br />
else<br />
glDisable(GL_FOG);<br />
}<br />
<br />
{<br />
if(material.normalize != current_material.normalize || reset)<br />
if(material.normalize)<br />
glEnable(GL_NORMALIZE);<br />
else<br />
glDisable(GL_NORMALIZE);<br />
}<br />
<br />
{<br />
if(material.depth_buffer != current_material.depth_buffer || reset)<br />
if(material.depth_buffer)<br />
glEnable(GL_DEPTH_TEST);<br />
else<br />
glDisable(GL_DEPTH_TEST);<br />
}<br />
<br />
{<br />
if(material.depth_write != current_material.depth_write || reset)<br />
if(material.depth_write)<br />
glDepthMask(GL_TRUE);<br />
else<br />
glDepthMask(GL_FALSE);<br />
}<br />
<br />
<br />
if (material.emt_flag != current_material.emt_flag || reset)<br />
{<br />
if (multitex && material.textures.size() > 1)<br />
{<br />
glActiveTextureARB(GL_TEXTURE1_ARB);<br />
<br />
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, <br />
material.emt_flag & emt_bilinear ? GL_LINEAR : GL_NEAREST);<br />
<br />
if (anistropic)<br />
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, <br />
material.emt_flag & emt_anistropic ? anistropic_level : 1.0f );<br />
<br />
glActiveTextureARB(GL_TEXTURE0_ARB);<br />
}<br />
<br />
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, <br />
material.emt_flag & emt_bilinear ? GL_LINEAR : GL_NEAREST);<br />
<br />
if (anistropic)<br />
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, <br />
material.emt_flag & emt_anistropic ? anistropic_level : 1.0f );<br />
}<br />
<br />
<br />
<br />
current_material = material;<br />
}<br />
<br />
const smaterial& opengldriver::get_material() const<br />
{<br />
return current_material;<br />
}<br />
<br />
void opengldriver::draw_triangle_list(const svertice* tri_vertices, const u16& count, const u16* order)<br />
{<br />
bool allocd = false;<br />
u16* dorder = (u16*)order;<br />
<br />
if(!dorder)<br />
{<br />
dorder = new u16[count*3];<br />
allocd = true;<br />
for(u16 i = 0; i < count*3; ++i)<br />
{<br />
dorder[i] = i;<br />
}<br />
}<br />
<br />
s32 max = 0;<br />
for(u16 i = 0; i < count*3; ++i)<br />
{<br />
if(max < dorder[i])<br />
max = dorder[i];<br />
}<br />
<br />
array<u32> colors;<br />
colors.reserve(max+1);<br />
colors.fill();<br />
<br />
for(u16 i = 0; i < count*3; ++i)<br />
{<br />
colors[dorder[i]] = rgba32_to_abgr32(tri_vertices[dorder[i]].vector_color.__color);<br />
}<br />
<br />
array<vector2d> tex_coords1;<br />
tex_coords1.reserve(max+1);<br />
tex_coords1.fill();<br />
<br />
array<vector2d> tex_coords2;<br />
if(multitex)<br />
{<br />
tex_coords2.reserve(max+1);<br />
tex_coords2.fill();<br />
}<br />
<br />
for(u16 i = 0; i < count*3; ++i)<br />
{<br />
tex_coords1[dorder[i]] = tri_vertices[dorder[i]].texture_coordinates[0];<br />
if(multitex)<br />
if(tri_vertices[dorder[i]].texture_flag & evt_layer2)<br />
tex_coords2[dorder[i]] = tri_vertices[dorder[i]].texture_coordinates[1];<br />
else<br />
tex_coords2[dorder[i]] = tex_coords2[dorder[i-1]];<br />
}<br />
<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
<br />
glEnableClientState(GL_COLOR_ARRAY);<br />
glEnableClientState(GL_VERTEX_ARRAY);<br />
glEnableClientState(GL_TEXTURE_COORD_ARRAY );<br />
glEnableClientState(GL_NORMAL_ARRAY );<br />
<br />
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(s32), &colors[0]);<br />
glVertexPointer(3, GL_FLOAT, sizeof(svertice), &tri_vertices->vector_position);<br />
glNormalPointer(GL_FLOAT, sizeof(svertice), &tri_vertices->vector_normal);<br />
<br />
if(multitex)<br />
{<br />
glClientActiveTextureARB(GL_TEXTURE0);<br />
glEnableClientState ( GL_TEXTURE_COORD_ARRAY );<br />
glTexCoordPointer(2, GL_DOUBLE, sizeof(vector2d), &tex_coords1[0]);<br />
<br />
glClientActiveTextureARB(GL_TEXTURE1);<br />
glEnableClientState ( GL_TEXTURE_COORD_ARRAY );<br />
glTexCoordPointer(2, GL_DOUBLE, sizeof(vector2d), &tex_coords2[0]);<br />
}<br />
else<br />
glTexCoordPointer(2, GL_DOUBLE, sizeof(vector2d), &tex_coords1[0]);<br />
<br />
glDrawElements(GL_TRIANGLES, count * 3, GL_UNSIGNED_SHORT, dorder);<br />
glFlush();<br />
<br />
glDisableClientState(GL_COLOR_ARRAY);<br />
glDisableClientState(GL_VERTEX_ARRAY);<br />
glDisableClientState(GL_NORMAL_ARRAY );<br />
<br />
if(multitex)<br />
{<br />
glClientActiveTextureARB(GL_TEXTURE0);<br />
glDisableClientState ( GL_TEXTURE_COORD_ARRAY );<br />
<br />
glClientActiveTextureARB(GL_TEXTURE1);<br />
glDisableClientState ( GL_TEXTURE_COORD_ARRAY );<br />
}<br />
else<br />
glDisableClientState(GL_TEXTURE_COORD_ARRAY );<br />
<br />
if(allocd)<br />
delete dorder;<br />
}<br />
<br />
void opengldriver::draw_line_list(const svertice* line_vertices, const u16& count, const u16* order)<br />
{<br />
bool allocd = false;<br />
u16* dorder = (u16*)order;<br />
<br />
if(!dorder)<br />
{<br />
dorder = new u16[count*2];<br />
allocd = true;<br />
for(u16 i = 0; i < count*2; ++i)<br />
{<br />
dorder[i] = i;<br />
}<br />
}<br />
<br />
s32 max = 0;<br />
for(u16 i = 0; i < count*2; ++i)<br />
{<br />
if(max < dorder[i])<br />
max = dorder[i];<br />
}<br />
<br />
array<s32> colors;<br />
colors.reserve(max);<br />
colors.fill();<br />
<br />
for(u16 i = 0; i < count*2; ++i)<br />
{<br />
colors[dorder[i]] = rgba32_to_abgr32(line_vertices[dorder[i]].vector_color.__color);<br />
}<br />
<br />
array<vector2d> tex_coords1;<br />
tex_coords1.reserve(max);<br />
tex_coords1.fill();<br />
<br />
array<vector2d> tex_coords2;<br />
if(multitex)<br />
{<br />
tex_coords2.reserve(max);<br />
tex_coords2.fill();<br />
}<br />
<br />
for(u16 i = 0; i < count*2; ++i)<br />
{<br />
tex_coords1[dorder[i]] = line_vertices[dorder[i]].texture_coordinates[0];<br />
if(multitex)<br />
if(line_vertices[dorder[i]].texture_flag & evt_layer2)<br />
tex_coords2[dorder[i]] = line_vertices[dorder[i]].texture_coordinates[1];<br />
else if(i != 0)<br />
tex_coords2[dorder[i]] = tex_coords2[dorder[i-1]];<br />
else<br />
tex_coords2[dorder[i]] = vector2d(0.0,0.0);<br />
}<br />
<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
<br />
glEnableClientState(GL_COLOR_ARRAY);<br />
glEnableClientState(GL_VERTEX_ARRAY);<br />
glEnableClientState(GL_TEXTURE_COORD_ARRAY );<br />
glEnableClientState(GL_NORMAL_ARRAY );<br />
<br />
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(s32), &colors[0]);<br />
glVertexPointer(3, GL_FLOAT, sizeof(svertice), &line_vertices->vector_position);<br />
glNormalPointer(GL_FLOAT, sizeof(svertice), &line_vertices->vector_normal);<br />
<br />
if(multitex)<br />
{<br />
glClientActiveTextureARB(GL_TEXTURE0);<br />
glEnableClientState ( GL_TEXTURE_COORD_ARRAY );<br />
glTexCoordPointer(2, GL_DOUBLE, sizeof(vector2d), &tex_coords1[0]);<br />
<br />
glClientActiveTextureARB(GL_TEXTURE1);<br />
glEnableClientState ( GL_TEXTURE_COORD_ARRAY );<br />
glTexCoordPointer(2, GL_DOUBLE, sizeof(vector2d), &tex_coords2[0]);<br />
}<br />
else<br />
glTexCoordPointer(2, GL_DOUBLE, sizeof(vector2d), &tex_coords1[0]);<br />
<br />
glDrawElements(GL_LINES, count * 2, GL_UNSIGNED_SHORT, dorder);<br />
glFlush();<br />
<br />
glDisableClientState(GL_COLOR_ARRAY);<br />
glDisableClientState(GL_VERTEX_ARRAY);<br />
glDisableClientState(GL_NORMAL_ARRAY );<br />
<br />
if(multitex)<br />
{<br />
glClientActiveTextureARB(GL_TEXTURE0);<br />
glDisableClientState ( GL_TEXTURE_COORD_ARRAY );<br />
<br />
glClientActiveTextureARB(GL_TEXTURE1);<br />
glDisableClientState ( GL_TEXTURE_COORD_ARRAY );<br />
}<br />
else<br />
glDisableClientState(GL_TEXTURE_COORD_ARRAY );<br />
<br />
if(allocd)<br />
delete dorder;<br />
}<br />
<br />
<br />
itexture* opengldriver::create_texture(const_string imagefile, bool mipmap)<br />
{<br />
iimage* image = create_image(imagefile);<br />
itexture* ret = new opengltexture(image, mipmap);<br />
image->drop();<br />
return ret;<br />
}<br />
<br />
itexture* opengldriver::create_texture(const iimage* image, bool l)<br />
{<br />
return new opengltexture((iimage*)image, l);<br />
}<br />
<br />
void opengldriver::use_texture(const u32 layer, const itexture* texture)<br />
{<br />
if(layer > 1 && multitex)<br />
throw gl_error("Only layer 0 and 1 are functional for multitextures");<br />
<br />
#ifndef NO_CURRENT<br />
make_current();<br />
#endif<br />
<br />
if (multitex)<br />
glActiveTextureARB(layer == 0 ? GL_TEXTURE0_ARB : GL_TEXTURE1_ARB);<br />
else<br />
if (layer != 0)<br />
throw gl_error("Only layer 0 is functional for non-multitextures");<br />
<br />
if(texture && texture->get_driver() != evd_opengl)<br />
throw gl_error("Texture Cannot Be Used by this Driver");<br />
<br />
if (!texture)<br />
{<br />
glDisable(GL_TEXTURE_2D);<br />
}<br />
else<br />
{<br />
glEnable(GL_TEXTURE_2D);<br />
((opengltexture*)texture)->bind();<br />
}<br />
}<br />
<br />
void opengldriver::add_material_renderer(imaterial_renderer* renderer)<br />
{<br />
if(renderers.is_key(renderer->get_code())) <br />
throw gl_error("A Material Renderer is Set to Correspond to that Code.");<br />
<br />
renderers.insert(renderer->get_code(), renderer);<br />
}<br />
<br />
bool got_ext = false;<br />
<br />
static void init_extensions()<br />
{<br />
if(!got_ext)<br />
{<br />
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress( "wglSwapIntervalEXT" );<br />
pglActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress( "glActiveTextureARB");<br />
pglClientActiveTextureARB= (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB");<br />
}<br />
got_ext = true;<br />
}<br />
<br />
#endif<br />
<br />
static void set_hint_levels(s32 level)<br />
{ <br />
glHint(GL_FOG_HINT, level);<br />
glHint(GL_LINE_SMOOTH_HINT, level);<br />
glHint(GL_PERSPECTIVE_CORRECTION_HINT, level);<br />
glHint(GL_POINT_SMOOTH_HINT, level);<br />
glHint(GL_POLYGON_SMOOTH_HINT, level);<br />
if (wglSwapIntervalEXT)<br />
wglSwapIntervalEXT(level == GL_NICEST ? 1 : 0);<br />
}<br />
<br />
static void set3Dmode(void)<br />
{<br />
glFrontFace(GL_CCW);<br />
}<br />
<br />
static void anti_alias(bool yes)<br />
{<br />
if(yes)<br />
{<br />
glEnable(GL_POINT_SMOOTH);<br />
glEnable(GL_LINE_SMOOTH);<br />
glEnable(GL_POLYGON_SMOOTH);<br />
}<br />
else<br />
{<br />
glDisable(GL_POINT_SMOOTH);<br />
glDisable(GL_LINE_SMOOTH);<br />
glDisable(GL_POLYGON_SMOOTH);<br />
}<br />
}<br />
<br />
};<br />
};<br />
<br />
Thanks for any help
SaGE SaneT
|