|
本帖最后由 lxlbgd1 于 2010-12-30 23:45 编辑
想把一个openGL写的程序嵌入到osg中,但是什么也不能显示,请版主帮看看是哪里出了问题,应该怎样改正? 我是参照了osgteapot的例子进行更改的,主要代码的功能函数如下(引用文件是openGL的实现算法):
#include <windows.h>
#include <osg/Geode>
#include <osg/TexGen>
#include <osg/Texture2D>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
//#include <GL/gl.h>
#include "glut.h"
#include "./fire/FlameMain.h"
#include "./fire/Flame3D.h"
#include "./fire/FlameVolRend.h"
#include "./fire/FlameUtils.h"
#include "./fire/PBuffer.h"
#include "./fire/perlin.h"
#define strict
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <windowsx.h>
#include <stdio.h>
#define FOVY 45
static int g_x=50, g_y=50, g_w=800, g_h=600;
///////////////////////////////////////
// global variables
char s[200];
char szClsName[] = "Flame Animation - Creative Labs Contest";
static HINSTANCE g_hInst = NULL;
static HGLRC g_hRC = NULL;
static HDC g_hDC = NULL;
static HWND g_hWnd=NULL, g_hWndDbg=NULL;
float g_transX=0, g_transY=0, g_transZ=40, g_rotX=0, g_rotY=57;
float g_obstX=0.0f, g_obstY=0.0f, g_obstZ=0.0f, g_obstR=4.0f;
int g_oldMX=0, g_oldMY=0, g_simCount=0,g_oldSimCount=0;
extern int i;
bool g_doVolRend=true, g_simStop=false, g_doScreens=false, g_useObstacles=false;
static LARGE_INTEGER timerFreq; static LARGE_INTEGER startTime;
float g_fps=1.0f; int g_frames=0;
int g_showFieldId=CM_SHOW_VEL_FIELD;
Flame3D *g_smoke;
VolumeRenderer g_volRend;
VolumeRenderer::SFieldId g_scalarFieldId = VolumeRenderer::T_ID;
PBuffer g_pbufferMirror;
int g_mirrorTexW = 256;
int g_mirrorTexH = 256;
static const int g_procImgW = 64;
static const int g_procImgH = 64;
unsigned int g_texId[1];
static unsigned char g_imgData[g_procImgW*g_procImgH*3];
extern int i,j,k;
extern float x,y,z;
void init (void)
{
// create pbuffer
g_pbufferMirror.create(g_mirrorTexW,g_mirrorTexH,true);
QueryPerformanceFrequency(&timerFreq); QueryPerformanceCounter(&startTime);
glClearColor(0,0,0,0);
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
g_smoke=new Flame3D();
g_volRend.init();
glMatrixMode(GL_PROJECTION); glLoadIdentity();
gluPerspective(FOVY, (float)g_w/g_h, 0.1f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
// init texture unit parameters
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &g_texId[0]);
glBindTexture(GL_TEXTURE_2D, g_texId[0]);
//glPixelStorei(GL_UNPACK_ALIGNMENT,0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
for (int j=0; j<g_procImgH; ++j) {
for (int i=0; i<3*g_procImgW; i+=3) {
x=((i/3)*(1.0f/g_procImgW)-0.5)*2; y=(j*(1.0f/g_procImgH)-0.5)*2;
float noise=fabs(PerlinNoise2D(3*x,3*y,2,2,4));
g_imgData[j*3*g_procImgH+i] = (int)((sin(4*(1.1*x+noise))*(cos(1.1*y*(x+noise)))+1)*127*1.0);
g_imgData[j*3*g_procImgH+i+1] = (int)((sin(4*(x+noise))*(cos(1.2*y*(x+noise)))+1)*127*0.8);
g_imgData[j*3*g_procImgH+i+2] = (int)((sin(4*(x+noise))*(cos(y*(x+noise)))+1)*127*0.6);
}
}
glTexImage2D(GL_TEXTURE_2D,0,3,g_procImgW,g_procImgH,0,GL_RGB,GL_UNSIGNED_BYTE,&g_imgData[0]);
}
void G_SimUpdate() {
g_smoke->update(); ++g_simCount;
}
void OnPaint() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_3D);
// -------------------------------------------------------------------------
// Update simulation
// -------------------------------------------------------------------------
if (! g_simStop) { G_SimUpdate(); }
// -------------------------------------------------------------------------
// draw the mirror plane itself (procedurally textured)
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// draw actual flame
// -------------------------------------------------------------------------
glLoadIdentity();
glTranslatef(g_transX, g_transY, g_transZ-88.0f);
glRotatef(g_rotX, 1.0f,0.0f,0.0f); glRotatef(g_rotY, 0.0f,1.0f,0.0f);
g_smoke->render(g_doVolRend); // draw geometry first
if (g_doVolRend) {
glColor4f(1,1,1,1);
g_volRend.setVolumeData(g_scalarFieldId, g_smoke);
g_volRend.update3DTexture();
g_volRend.render();
}
if(g_doScreens) if(g_oldSimCount!=g_simCount) {saveBmp24(g_w,g_h);}
// Show FPS
sprintf(s,"Frame: %i",g_simCount); show_fps(5,20, g_w,g_h, s);
sprintf(s,"FPS: %.3f",g_fps); show_fps(5,40, g_w,g_h, s);
g_oldSimCount=g_simCount;
glFlush();/* SwapBuffers(NULL);*/
//SwapBuffers(g_hDC);
///*glFinish;*/
//glutSwapBuffers();
}
static void teapot()
{
/*glutInitDisplayMode (GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize (800, 600);
glutInitWindowPosition (50, 50);*/
glutCreateWindow ("hello");
init ();
OnPaint();
//glutDisplayFunc();
}
// Now the OSG wrapper for the above OpenGL code, the most complicated bit is computing
// the bounding box for the above example, normally you'll find this the easy bit.
class Teapot : public osg:rawable
{
public:
Teapot() {/*setUseDisplayList(false);*/}
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
Teapot(const Teapot& teapot,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
osg::Drawable(teapot,copyop) {}
META_Object(myTeapotApp,Teapot)
// the draw immediate mode method is where the OSG wraps up the drawing of
// of OpenGL primitives.
virtual void drawImplementation(osg::RenderInfo&) const
{
// teapot(..) doens't use vertex arrays at all so we don't need to toggle their state
// if we did we'd need to something like following call
// state.disableAllVertexArrays(), see src/osg/Geometry.cpp for the low down.
// just call the OpenGL code.
teapot();
}
protected:
virtual ~Teapot() {}
};
osg::Geode* createTeapot()
{
osg::Geode* geode = new osg::Geode();
// add the teapot to the geode.
geode->addDrawable( new Teapot );
return geode;
}
int main(int , char **)
{
#if 1
// create viewer on heap as a test, this looks to be causing problems
// on init on some platforms, and seg fault on exit when multi-threading on linux.
// Normal stack based version below works fine though...
// construct the viewer.
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
// add model to viewer.
viewer->setSceneData( createTeapot() );
return viewer->run();
#else
// construct the viewer.
osgViewer::Viewer viewer;
// add model to viewer.
viewer.setSceneData( createTeapot() );
// create the windows and run the threads.
return viewer.run();
#endif
} |
|