Files
bullet3/test/GwenOpenGLTest/OpenGLSample.cpp
a 3d499c8a7a pybullet: added EGL render device and window_backend option.
EGL review.
EGL dynamic loading, windowType to int
moved to glad2
Require GL 3.3 as GLInstancingRenderer.cpp uses glVertexAttribDivisor
glad2 update with dynamic X11 added
removed old file
build fix
fix mac/win
EGL w/o c++11, off by default
fix premake
fixup: premake fix 2
2018-08-30 13:24:25 +02:00

547 lines
10 KiB
C++

#include "Gwen/Gwen.h"
#include "Gwen/Skins/Simple.h"
#include "../OpenGLWindow/OpenGLInclude.h"
#include "UnitTest.h"
extern unsigned char OpenSansData[];
#include "Gwen/Renderers/OpenGL_DebugFont.h"
#ifdef B3_USE_GLFW
#include "OpenGLWindow/GLFWOpenGLWindow.h"
#else
#ifdef __APPLE__
#include "OpenGLWindow/MacOpenGLWindow.h"
#else
//#include "CustomGL/glew.h"
#ifdef _WIN32
#include "OpenGLWindow/Win32OpenGLWindow.h"
#else
//let's cross the fingers it is Linux/X11
#include "OpenGLWindow/X11OpenGLWindow.h"
#endif //_WIN32
#endif//__APPLE__
#endif //B3_USE_GLFW
#include "OpenGLWindow/opengl_fontstashcallbacks.h"
#ifndef NO_OPENGL3
#include "OpenGLWindow/GwenOpenGL3CoreRenderer.h"
#include "OpenGLWindow/GLPrimitiveRenderer.h"
#endif
#include <assert.h>
Gwen::Controls::Canvas* pCanvas = NULL;
Gwen::Skin::Simple skin;
void MyMouseMoveCallback( float x, float y)
{
//b3DefaultMouseCallback(button,state,x,y);
static int m_lastmousepos[2] = {0,0};
static bool isInitialized = false;
if (pCanvas)
{
if (!isInitialized)
{
isInitialized = true;
m_lastmousepos[0] = x+1;
m_lastmousepos[1] = y+1;
}
bool handled = pCanvas->InputMouseMoved(x,y,m_lastmousepos[0],m_lastmousepos[1]);
}
}
void MyMouseButtonCallback(int button, int state, float x, float y)
{
//b3DefaultMouseCallback(button,state,x,y);
if (pCanvas)
{
bool handled = pCanvas->InputMouseMoved(x,y,x, y);
if (button>=0)
{
handled = pCanvas->InputMouseButton(button,state);
if (handled)
{
if (!state)
return;
}
}
}
}
int sWidth = 800;//1050;
int sHeight = 600;//768;
GLPrimitiveRenderer* primRenderer=0;
//GwenOpenGL3CoreRenderer* gwenRenderer=0;
Gwen::Renderer::Base* gwenRenderer =0;
static void MyResizeCallback( float width, float height)
{
sWidth = width;
sHeight = height;
// printf("resize(%d,%d)\n",sWidth,sHeight);
#ifndef NO_OPENGL3
if (primRenderer)
{
primRenderer->setScreenSize(width,height);
}
#endif
if (gwenRenderer)
{
gwenRenderer->Resize(width,height);
}
if (pCanvas)
{
pCanvas->SetSize( sWidth, sHeight);
}
}
int droidRegular;//, droidItalic, droidBold, droidJapanese, dejavu;
#ifndef NO_OPENGL3
sth_stash* initFont(GLPrimitiveRenderer* primRenderer)
{
GLint err;
struct sth_stash* stash = 0;
OpenGL2RenderCallbacks* renderCallbacks = new OpenGL2RenderCallbacks(primRenderer);
stash = sth_create(512,512,renderCallbacks);//256,256);//,1024);//512,512);
err = glGetError();
assert(err==GL_NO_ERROR);
if (!stash)
{
fprintf(stderr, "Could not create stash.\n");
return 0;
}
#ifdef LOAD_FONTS_FROM_FILE
int datasize;
unsigned char* data;
float sx,sy,dx,dy,lh;
GLuint texture;
const char* fontPaths[]={
"./",
"../../bin/",
"../bin/",
"bin/"
};
int numPaths=sizeof(fontPaths)/sizeof(char*);
// Load the first truetype font from memory (just because we can).
FILE* fp = 0;
const char* fontPath ="./";
char fullFontFileName[1024];
for (int i=0;i<numPaths;i++)
{
fontPath = fontPaths[i];
//sprintf(fullFontFileName,"%s%s",fontPath,"OpenSans.ttf");//"DroidSerif-Regular.ttf");
sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Regular.ttf");//OpenSans.ttf");//"DroidSerif-Regular.ttf");
fp = fopen(fullFontFileName, "rb");
if (fp)
break;
}
err = glGetError();
assert(err==GL_NO_ERROR);
assert(fp);
if (fp)
{
fseek(fp, 0, SEEK_END);
datasize = (int)ftell(fp);
fseek(fp, 0, SEEK_SET);
data = (unsigned char*)malloc(datasize);
if (data == NULL)
{
assert(0);
return 0;
}
else
fread(data, 1, datasize, fp);
fclose(fp);
fp = 0;
}
if (!(droidRegular = sth_add_font_from_memory(stash, data)))
{
assert(0);
return 0;
}
err = glGetError();
assert(err==GL_NO_ERROR);
// Load the remaining truetype fonts directly.
sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Italic.ttf");
if (!(droidItalic = sth_add_font(stash,fullFontFileName)))
{
assert(0);
return 0;
}
sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Bold.ttf");
if (!(droidBold = sth_add_font(stash,fullFontFileName)))
{
assert(0);
return 0;
}
err = glGetError();
assert(err==GL_NO_ERROR);
sprintf(fullFontFileName,"%s%s",fontPath,"DroidSansJapanese.ttf");
if (!(droidJapanese = sth_add_font(stash,fullFontFileName)))
{
assert(0);
return 0;
}
#else
unsigned char* data = OpenSansData;
if (!(droidRegular = sth_add_font_from_memory(stash, data)))
{
printf("error!\n");
}
#endif
err = glGetError();
assert(err==GL_NO_ERROR);
return stash;
}
#endif
void keyCallback(int key, int value)
{
printf("key = %d, value = %d\n", key,value);
//pCanvas->InputKey(key,value==1);
int gwenKey = -1;
switch (key)
{
case B3G_LEFT_ARROW:
{
gwenKey = Gwen::Key::Left;
break;
}
case B3G_RIGHT_ARROW:
{
gwenKey = Gwen::Key::Right;
break;
}
case B3G_UP_ARROW:
{
gwenKey = Gwen::Key::Up;
break;
}
case B3G_DOWN_ARROW:
{
gwenKey = Gwen::Key::Down;
break;
}
case B3G_BACKSPACE:
{
gwenKey = Gwen::Key::Backspace;
break;
}
case B3G_DELETE:
{
gwenKey = Gwen::Key::Delete;
break;
}
case B3G_HOME:
{
gwenKey = Gwen::Key::Home;
break;
}
case B3G_END:
{
gwenKey = Gwen::Key::End;
break;
}
case B3G_SHIFT:
{
gwenKey = Gwen::Key::Shift;
break;
}
case B3G_CONTROL:
{
gwenKey = Gwen::Key::Control;
break;
}
default:
{
}
};
if (gwenKey>=0)
{
pCanvas->InputKey(gwenKey,value==1);
} else
{
if (key<256 && value)
{
Gwen::UnicodeChar c = ( Gwen::UnicodeChar ) key;
pCanvas->InputCharacter(c);
}
}
}
extern int avoidUpdate;
int main()
{
b3gDefaultOpenGLWindow* window = new b3gDefaultOpenGLWindow();
window->setKeyboardCallback(keyCallback);
b3gWindowConstructionInfo wci;
#ifndef NO_OPENGL3
wci.m_openglVersion = 3;
#else
wci.m_openglVersion = 2;
#endif
wci.m_width = sWidth;
wci.m_height = sHeight;
// wci.m_resizeCallback = MyResizeCallback;
window->createWindow(wci);
window->setResizeCallback(MyResizeCallback);
int majorGlVersion, minorGlVersion;
if (!(sscanf((const char*)glGetString(GL_VERSION), "%d.%d", &majorGlVersion, &minorGlVersion)==2))
{
printf("Exit: Error cannot extract OpenGL version from GL_VERSION string\n");
exit(0);
}
char title[1024];
if (wci.m_openglVersion>2)
{
sprintf(title,"Gwen with OpenGL %d.%d\n",majorGlVersion,minorGlVersion);
} else
{
sprintf(title,"Gwen with OpenGL %d\n",wci.m_openglVersion);
}
window->setWindowTitle(title);
float retinaScale = window->getRetinaScale();
#ifndef NO_OPENGL3
if (majorGlVersion>=3 && wci.m_openglVersion>=3)
{
#ifndef B3_USE_GLFW
#ifndef __APPLE__
#ifndef _WIN32
//we need glewExperimental on Linux
#endif // _WIN32
gladLoadGLInternalLoader();
#endif
#endif //B3_USE_GLFW
//we ned to call glGetError twice, because of some Ubuntu/Intel/OpenGL issue
GLuint err = glGetError();
err = glGetError();
assert(err==GL_NO_ERROR);
primRenderer = new GLPrimitiveRenderer(sWidth,sHeight);
sth_stash* font = initFont(primRenderer );
gwenRenderer = new GwenOpenGL3CoreRenderer(primRenderer,font,sWidth,sHeight,retinaScale);
} else
#endif
{
//OpenGL 2.x
gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont(retinaScale);
skin.SetRender( gwenRenderer );
glClearColor(1,0,0,1);
}
//
// Create a GWEN OpenGL Renderer
//
// Gwen::Renderer::OpenGL_DebugFont * pRenderer = new Gwen::Renderer::OpenGL_DebugFont();
//
// Create a GWEN skin
//
#ifdef USE_TEXTURED_SKIN
Gwen::Skin::TexturedBase skin;
skin.SetRender( pRenderer );
skin.Init("DefaultSkin.png");
#else
skin.SetRender( gwenRenderer );
#endif
//
// Create a Canvas (it's root, on which all other GWEN panels are created)
//
pCanvas = new Gwen::Controls::Canvas( &skin );
pCanvas->SetSize( sWidth, sHeight);
pCanvas->SetDrawBackground( true );
pCanvas->SetBackgroundColor( Gwen::Color( 150, 170, 170, 255 ) );
window->setMouseButtonCallback(MyMouseButtonCallback);
window->setMouseMoveCallback(MyMouseMoveCallback);
//
// Create our unittest control (which is a Window with controls in it)
//
UnitTest* pUnit = new UnitTest( pCanvas );
pUnit->SetPos( 10, 10 );
//
// Create a Windows Control helper
// (Processes Windows MSG's and fires input at GWEN)
//
//Gwen::Input::Windows GwenInput;
//GwenInput.Initialize( pCanvas );
//
// Begin the main game loop
//
// MSG msg;
while( !window->requestedExit() )
{
if (majorGlVersion<3 || wci.m_openglVersion<3)
{
saveOpenGLState(sWidth,sHeight);
}
// Skip out if the window is closed
//if ( !IsWindowVisible( g_pHWND ) )
//break;
// If we have a message from windows..
// if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
// .. give it to the input handler to process
// GwenInput.ProcessMessage( msg );
// if it's QUIT then quit..
// if ( msg.message == WM_QUIT )
// break;
// Handle the regular window stuff..
// TranslateMessage(&msg);
// DispatchMessage(&msg);
}
window->startRendering();
// Main OpenGL Render Loop
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_BLEND);
GLint err = glGetError();
assert(err==GL_NO_ERROR);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
err = glGetError();
assert(err==GL_NO_ERROR);
err = glGetError();
assert(err==GL_NO_ERROR);
glDisable(GL_DEPTH_TEST);
err = glGetError();
assert(err==GL_NO_ERROR);
//glColor4ub(255,0,0,255);
err = glGetError();
assert(err==GL_NO_ERROR);
err = glGetError();
assert(err==GL_NO_ERROR);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// saveOpenGLState(width,height);//m_glutScreenWidth,m_glutScreenHeight);
err = glGetError();
assert(err==GL_NO_ERROR);
err = glGetError();
assert(err==GL_NO_ERROR);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
err = glGetError();
assert(err==GL_NO_ERROR);
err = glGetError();
assert(err==GL_NO_ERROR);
glEnable(GL_BLEND);
err = glGetError();
assert(err==GL_NO_ERROR);
pCanvas->RenderCanvas();
if (avoidUpdate<=0)
avoidUpdate++;
// SwapBuffers( GetDC( g_pHWND ) );
}
window->endRendering();
if (majorGlVersion<3 || wci.m_openglVersion<3)
{
restoreOpenGLState();
}
}
window->closeWindow();
delete window;
}