0
我試圖實現與谷歌本地客戶端的渲染循環,我知道你不能在除主線程之外的任何線程上進行Pepper API調用,所以我試圖執行以下操作。使用DoGL_() - > DoGL()調用函數使用Pepper API調用函數在主線程上調用函數 - > DoGL_()仍然在單獨的線程上調用DoGL()。谷歌本地客戶端渲染循環
我試圖用胡椒19做到這一點,我真的不知道有關線程來解決這個問題。現在模塊崩潰了。
這裏是我的代碼(不漂亮,我只是試圖讓苦差事碼的方式進行):
DoGL.h
#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();
}
DoGL.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();
}
}