谷歌原生客户端渲染循环
Google Native Client Render Loop
我正在尝试使用Google Native Client实现渲染循环,我知道您不能在主线程以外的任何线程上进行Pepper API调用,所以我正在尝试实现以下内容。module() -> 使用 DoGL_() -> doGL() 调用函数,在主线程上调用 Pepper API 调用> DoGL_doGL() 仍然在单独的线程上
。我正在尝试仅使用 Pepper 19 执行此操作,但我对线程的了解真的不够多,无法解决此问题。现在模块只是崩溃。
这是我的代码(不漂亮,我只是想把琐事代码排除在外
):多格利·
#include "Include.h"
class Context : public pp::Graphics3DClient
{
pp::Size size;
bool init_;
const struct PPB_OpenGLES2 *gles2Interface;
public:
Context( pp::Instance *instance );
~Context();
virtual void Graphics3DContextLost() {
}
bool MakeCurrentContext( pp::Instance *instance );
void FlushContext();
pp::Graphics3D context;
void ( *callback ) ( void*, int32_t );
pp::Instance *ppinstance;
PPB_Graphics3D* ppb_g3d_interface;
GLuint programObject;
GLuint LoadShader( const char *shaderSrc, GLenum type );
GLuint Init();
void Draw();
void DoGL();
void GLDebug( std::string msg = "" );
static void FillIn( void* v, int32_t i ) {
}
pp::Core *ppb_core_interface;
};
static Context *cjcontext;
void* DoGL_( void* p ) {
cjcontext->DoGL();
}
void Init_( void *p, int32_t i ) {
cjcontext->Init();
}
void Draw_( void *p, int32_t i ) {
cjcontext->Draw();
}
void MakeContext_( void *p, int32_t i ) {
cjcontext->ppinstance->PostMessage( "Called on the main thread!!!!n" );
cjcontext->MakeCurrentContext( cjcontext->ppinstance );
}
void FlushContext_( void *p, int32_t i ) {
cjcontext->FlushContext();
}
道格.cpp
#include "DoGL.h"
Context::Context( pp::Instance *instance ) : pp::Graphics3DClient( instance )
{
pp::Module *module = pp::Module::Get();
gles2Interface = static_cast< const struct PPB_OpenGLES2 * > ( module->GetBrowserInterface( PPB_OPENGLES2_INTERFACE ) );
init_ = false;
}
Context::~Context() {
glSetCurrentContextPPAPI( 0 );
}
bool Context::MakeCurrentContext( pp::Instance *instance )
{
//Is somthing broken?//
if( instance == NULL ) {
glSetCurrentContextPPAPI( 0 );
return ( false );
}
if( context.is_null() == true )
{
//OpenGL attributes.//
int32_t attribs[] =
{
PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24,
PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 8,
PP_GRAPHICS3DATTRIB_SAMPLES, 0,
PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0,
PP_GRAPHICS3DATTRIB_WIDTH, 500,
PP_GRAPHICS3DATTRIB_HEIGHT, 500,
PP_GRAPHICS3DATTRIB_NONE /*Terminate list.*/
};
context = pp::Graphics3D( instance, pp::Graphics3D(), attribs );
if ( context.is_null() == true ) {
glSetCurrentContextPPAPI( 0 );
return ( false );
}
instance->BindGraphics( context );
}
//Get the context.//
glSetCurrentContextPPAPI( context.pp_resource() );
glViewport( 0, 0, 500, 500 );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
return true;
}
void Context::FlushContext()
{
//Make sure that the flush is not pending.//
for( unsigned int wait = 0; wait < 1001; ++wait );
context.SwapBuffers( pp::CompletionCallback( FillIn, ( ( void* ) this ) ) );
}
GLuint Context::LoadShader( const char *shaderSrc, GLenum type )
{
GLuint shader;
GLint compiled;
//Create the shader object.//
shader = glCreateShader( type );
if( shader == 0 ) {
return 0;
}
//Load the shader source.//
glShaderSource( shader, 1, &shaderSrc, NULL );
//Compile the shader.//
glCompileShader( shader );
//Check the compile status.//
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
return shader;
}
GLuint Context::Init()
{
const char* vShaderStr =
"#version 100 n"
"attribute vec4 vPosition; n"
"void main() n"
"{ n"
" gl_Position = vPosition; n"
"} n";
const char* fShaderStr =
"#version 100 n"
"precision mediump float; n"
"void main() n"
"{ n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); n"
"} n";
GLuint vertexShader;
GLuint fragmentShader;
GLint linked;
//Load the vertex/fragment shaders.//
vertexShader = LoadShader( vShaderStr, GL_VERTEX_SHADER );
fragmentShader = LoadShader( fShaderStr, GL_FRAGMENT_SHADER );
//Create the program object.//
programObject = glCreateProgram();
if( programObject == 0 ) {
return 0;
}
glAttachShader( programObject, vertexShader );
glAttachShader( programObject, fragmentShader );
//Bind vPosition to attribute 0.//
glBindAttribLocation( programObject, 0, "vPosition" );
//Link the program.//
glLinkProgram( programObject );
//Check the link status.//
glGetProgramiv( programObject, GL_LINK_STATUS, &linked );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
return programObject;
}
void Context::Draw()
{
ppinstance->PostMessage( "Drawing!" );
GLfloat scaler = 1.f;
GLfloat vVertices[] =
{
0.0f, ( scaler * 0.5f ), 0.0f,
( scaler * -0.5f ), ( scaler * -0.5f ), 0.0f,
( scaler * 0.5f ), ( scaler * -0.5f ), 0.0f
};
++scaler;
ppinstance->PostMessage( "Scaler" );
ppinstance->PostMessage( scaler );
//Set the viewport.
glViewport( 0, 0, 500, 500 );
//Clear the color buffer.//
glClear( GL_COLOR_BUFFER_BIT );
//Use the program object.//
glUseProgram( programObject );
//Load the vertex data.//
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
glEnableVertexAttribArray( 0 );
glDrawArrays( GL_TRIANGLES, 0, 3 );
}
void Context::DoGL()
{
if( init_ == false )
{
pp::CompletionCallback cc;
//ppinstance->PostMessage( "Init is false." );
cjcontext->MakeCurrentContext( ppinstance );
for( int i = 0; i < 10001; ++i );
cc = pp::CompletionCallback( &Init_, 0, 0 );
ppb_core_interface->CallOnMainThread( 0, cc, 0 );
init_ = true;
cjcontext->FlushContext();
}
pp::CompletionCallback cc;
for( int i = 0; i < 101; ++i );
cc = pp::CompletionCallback( &MakeContext_, 0, 0 );
ppb_core_interface->CallOnMainThread( 0, cc, 0 );
for( int i = 0; i < 101; ++i );
cc = pp::CompletionCallback( &Draw_, 0, 0 );
ppb_core_interface->CallOnMainThread( 0, cc, 0 );
for( int i = 0; i < 101; ++i );
cc = pp::CompletionCallback( &FlushContext_, 0, 0 );
ppb_core_interface->CallOnMainThread( 0, cc, 0 );
void *p;
DoGL_( p );
}
pthread_t reanderHandle;
int threadStatus;
//Standard NaCl chore code.//
class CubeJumpInstance : public pp::Instance
{
public:
explicit CubeJumpInstance( PP_Instance instance ) : pp::Instance( instance ) {
PostMessage( "Instance create.n" );
}
virtual ~CubeJumpInstance() {
PostMessage( "Instance destroyed.n" );
}
};
class CubeJumpModule : public pp::Module
{
public:
CubeJumpModule() : pp::Module() {
}
virtual ~CubeJumpModule() {
glTerminatePPAPI();
}
virtual pp::Instance* CreateInstance( PP_Instance instance )
{
glInitializePPAPI( get_browser_interface() );
pp::Instance *instance_ = new CubeJumpInstance( instance );
cjcontext = new Context( instance_ );
cjcontext->ppinstance = instance_;
cjcontext->ppb_core_interface = this->core();
threadStatus = pthread_create( &reanderHandle, 0, DoGL_, 0 );
cjcontext->ppinstance->PostMessage( "Instace done.n" );
//pthread_join( reanderHandle, 0 );
return cjcontext->ppinstance;
}
};
namespace pp
{
pp::Module* CreateModule() {
return new CubeJumpModule();
}
}
这里有很多问题,我将重点介绍主要概念:您不需要渲染线程,只需使用交换缓冲区来驱动渲染循环。
基本概念是:
// do this to kick things off
CallOnMainThread(Render)
Render()
if (!init)
Init();
MakeContext();
Draw();
SwapBuffers(Render);
就是这样。 SwapBuffers
将安排下一次调用在"正确"的时间呈现。
至于为什么你的程序崩溃,可能是很多事情,我猜你的主要问题是递归调用DoGL
直到你的堆栈爆炸。
相关文章:
- "unknown ca"自生成的 CA、证书和客户端/服务器
- 如何将函数集合传递给客户端类,以便将它们当作客户端类本身的成员使用
- 使用调试/崩溃报告将应用程序部署到客户端
- 如何在本地机器上运行c++和javascript客户端代码(hackerbank风格)
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 从服务器传输到客户端的消息不会出现
- OpenSSL TLS服务器-使用客户端证书白名单
- 当服务中的事件被触发时,如何将响应从服务发送回客户端?
- 我可以与 python 服务器而不是 c++ 客户端建立 tcp/ip 套接字吗?
- 提升 Asio TCP 服务器 处理多个客户端
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 如何绑定 C++ gRPC 客户端的网络接口
- C++套接字客户端到 Python 服务器未创建连接
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 将相机数据从服务器实时流式传输到客户端
- 如何在不关闭服务器套接字的情况下在C++客户端的主循环中接收数据?
- Winsock -客户端断开,关闭套接字循环/最大连接数
- 异步http客户端库和glib事件循环
- 谷歌原生客户端渲染循环
- epoll 在客户端断开连接时循环