std::shared_ptr<PROTOCOL> CreateProtocol(ARGS&& ... args) { static_assert(std::is_base_of<bamboo::protocol::ProtocolIf, PROTOCOL>::value, "protocol must be base of bamboo::protocol::ProtocolIf"); BB_ASSERT(!protocol_); BB_ASSERT(!reader_); auto ptr = std::make_shared<PROTOCOL>(std::forward<ARGS>(args)...); protocol_ = std::dynamic_pointer_cast<bamboo::protocol::ProtocolIf>(ptr); reader_ = [this](bamboo::net::SocketPtr so, const char* data, std::size_t size) -> std::size_t { return protocol_->ReceiveData(so, data, size); }; return ptr; }
void BBTexture_activate (BBTexture* texture, GLuint channel) { BB_ASSERT(texture); glActiveTexture(GL_TEXTURE0 + channel); glBindTexture(texture->type, texture->handle); glEnable(texture->type); }
GLuint BBMaterial_activate (BBMaterial* material, GLboolean forceAdditive) { GLsizei i; BB_ASSERT(material && material->program); glUseProgram(material->program); for (i = 0; i < BB_MATERIAL_MAX_TEXTURES; i++) if (material->textures[i]) BBTexture_activate(material->textures[i], i); #if 1 if (material->additive || forceAdditive) { glEnable(GL_BLEND); // glBlendFunc(GL_ONE, GL_ONE); } else if (material->blend) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else if (material->tone) { glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_SRC_ALPHA_SATURATE); } #else glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); #endif return material->program; }
void AcceptorIf::SetAddress(std::string address, uint16_t port) { BB_ASSERT(acceptor_ == nullptr); auto end = boost::asio::ip::make_address(address); boost::asio::ip::tcp::endpoint endpoint(end, port); acceptor_.reset(new boost::asio::ip::tcp::acceptor(io_, endpoint)); }
void BBTexture_destroy (BBTexture* texture) { BB_ASSERT(texture); // printf("Deleting texture %s\n", texture->name); glDeleteTextures(1, &texture->handle); free(texture->name); free(texture); }
/** Uncompress a buffer using zlib, will fail if UncompressedBuffer is too small */ bool UncompressZLIB( void* UncompressedBuffer, uint32 UncompressedSize, const void* CompressedBuffer, uint32 CompressedSize ) { // zlib uses unsigned long unsigned long ZCompressedSize = CompressedSize; unsigned long ZUncompressedSize = UncompressedSize; // Uncompress data. bool bOperationSucceeded = uncompress( (uint8*) UncompressedBuffer, &ZUncompressedSize, (const uint8*) CompressedBuffer, ZCompressedSize ) == Z_OK ? true : false; // Sanity check to make sure we uncompressed as much data as we expected to. BB_ASSERT( UncompressedSize == ZUncompressedSize ); return bOperationSucceeded; }
void BBMaterialStore_destroy (BBMaterialStore* matStore) { BB_ASSERT(matStore); { BBMaterial* current = matStore->firstMaterial; while (current) { BBMaterial* next = current->next; BBMaterial_destroy(current); current = next; } } free(matStore); }
void BBTextureStore_destroy (BBTextureStore* texStore) { BB_ASSERT(texStore); { BBTexture* current = texStore->firstTexture; while (current) { BBTexture* next = current->next; BBTexture_destroy(current); current = next; } } free(texStore); }
BBMaterial* BBMaterialStore_getMaterial (BBMaterialStore* matStore, const char* name) { BBMaterial* current; BB_ASSERT(matStore && name); current = matStore->firstMaterial; while (current) { if (strcmp(current->name, name) == 0) return current; current = current->next; } return NULL; }
void BBMaterial_deactivate (BBMaterial* material, GLboolean forceAdditive) { GLsizei i; BB_ASSERT(material); for (i = 0; i < BB_MATERIAL_MAX_TEXTURES; i++) if (material->textures[i]) BBTexture_deactivate(material->textures[i], i); if (material->additive || forceAdditive) { glDisable(GL_BLEND); } else if (material->blend || material->tone) { glDisable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); } }
void AcceptorIf::SetConnManager(ConnManagerPtr& mgr) { BB_ASSERT(connManager_ == nullptr && mgr != nullptr); connManager_ = mgr; }
GLboolean BBMaterial_isTransparent (BBMaterial* material) { BB_ASSERT(material); return material->blend || material->additive || material->tone; }
const char* BBTexture_getName (BBTexture* texture) { BB_ASSERT(texture); return texture->name; }
void BBMaterial_destroy (BBMaterial* material) { BB_ASSERT(material); free(material->name); free(material); }
GLenum BBTexture_getType (BBTexture* texture) { BB_ASSERT(texture); return texture->type; }
void BBTexture_deactivate (BBTexture* texture, GLuint channel) { BB_ASSERT(texture); glActiveTexture(GL_TEXTURE0 + channel); glDisable(texture->type); }
BBTexture* BBTextureStore_loadCube (BBTextureStore* texStore, const char* name, int startLodLevel) { BBTexture* texture; BBTga* tga[6]; GLubyte* dataList[6]; GLsizei width = 0; GLsizei height = 0; GLsizei bits = 0; GLuint i; BB_ASSERT(texStore && name); texture = BBTextureStore_find(texStore, name, GL_TEXTURE_CUBE_MAP); if (texture) return texture; if (strlen(name) > 240) { #ifdef BB_DEVEL printf("Error: Filename too long \"%s\"\n", name); #endif return NULL; } for (i = 0; i < 6; i++) { char filename[256]; GLboolean error = GL_FALSE; strcpy(filename, name); switch (i) { case 0: strcat(filename, "_px"); break; case 1: strcat(filename, "_py"); break; case 2: strcat(filename, "_pz"); break; case 3: strcat(filename, "_nx"); break; case 4: strcat(filename, "_ny"); break; case 5: strcat(filename, "_nz"); break; default: BB_ASSERT(0); break; } catenateMipMapFilename(filename, startLodLevel); strcat(filename, ".tga"); tga[i] = BBTga_load(filename); if (!tga[i]) error = GL_TRUE; if (!error && width != 0 && height != 0 && bits != 0) if (tga[i]->width != width || tga[i]->height != height || tga[i]->bits != bits) error = GL_TRUE; if (error) { while (i--) BBTga_destroy(tga[i]); return NULL; } width = tga[i]->width; height = tga[i]->height; bits = tga[i]->bits; dataList[i] = tga[i]->data; } texture = BBTexture_create(name, width, height, GL_TEXTURE_CUBE_MAP, bits == 24 ? GL_RGB : GL_RGBA, (const void **)dataList); for (i = 0; i < 6; i++) BBTga_destroy(tga[i]); if (texture) { texture->next = texStore->firstTexture; texStore->firstTexture = texture; } return texture; }
BBTexture* BBTextureStore_load (BBTextureStore* texStore, const char* name, int startLodLevel) { BBTexture* texture = NULL; BBTga* tga[MAX_MIPMAPS]; char filename[256]; GLsizei level = 0; GLboolean bottomOk = GL_TRUE; GLsizei width = 1; GLsizei height = 1; BB_ASSERT(texStore && name); memset(tga, 0, sizeof(BBTga*) * MAX_MIPMAPS); texture = BBTextureStore_find(texStore, name, GL_TEXTURE_2D); if (texture) return texture; if (strlen(name) > 240) { #ifdef BB_DEVEL printf("Error: Filename too long \"%s\"\n", name); #endif return NULL; } while (width >= 1 || height >= 1) { if (width < 1) width = 1; if (height < 1) height = 1; strcpy(filename, name); catenateMipMapFilename(filename, level + startLodLevel); strcat(filename, ".tga"); tga[level] = BBTga_load(filename); if (!tga[level]) { if (level == 0) { bottomOk = GL_FALSE; break; } } else { if (level == 0) { width = tga[0]->width; height = tga[0]->height; } else { if (tga[level]->width != width || tga[level]->height != height || tga[level]->bits != tga[0]->bits) { BBTga_destroy(tga[level]); tga[level] = NULL; } } } width >>= 1; height >>= 1; level++; BB_ASSERT(level < MAX_MIPMAPS); } if (bottomOk) { void* dataList[MAX_MIPMAPS]; GLboolean generated[MAX_MIPMAPS]; GLsizei i; GLboolean errorsInMipMaps = GL_FALSE; memset(dataList, 0, sizeof(void*) * MAX_MIPMAPS); memset(generated, 0, sizeof(GLboolean) * MAX_MIPMAPS); for (i = 0; i < level; i++) { if (tga[i] && tga[i]->data) { dataList[i] = tga[i]->data; } else { GLsizei bpp = tga[0]->bits == 24 ? 3 : 4; GLsizei width = tga[0]->width >> i; GLsizei height = tga[0]->height >> i; BB_ASSERT(i != 0 || (width < 1 && height < 1)); if (width < 1) width = 1; if (height < 1) height = 1; dataList[i] = (GLubyte*)malloc(width * height * bpp * sizeof(GLubyte)); if (dataList[i]) { generateMipMap(tga[0]->data, tga[0]->width, tga[0]->height, tga[0]->bits == 24 ? GL_RGB : GL_RGBA, i, dataList[i]); { strcpy(filename, name); catenateMipMapFilename(filename, i); strcat(filename, ".tga"); if (BBTga_save(filename, width, height, tga[0]->bits == 24 ? 3 : 4, dataList[i], GL_TRUE)) { #ifdef BB_DEVEL printf("Generated mipmap level %d for texture %s.\n", i, name); #endif } else { #ifdef BB_DEVEL printf("Failed to save mipmap level %d for texture %s.\n", i, name); #endif } } generated[i] = GL_TRUE; } else { errorsInMipMaps = GL_TRUE; break; } } } if (!errorsInMipMaps) texture = BBTexture_create(name, tga[0]->width, tga[0]->height, GL_TEXTURE_2D, tga[0]->bits == 24 ? GL_RGB : GL_RGBA, (const void **)dataList); for (i = 0; i < level; i++) { if (generated[i]) free(dataList[i]); } } while (level-- > 0) { if (tga[level]) { BBTga_destroy(tga[level]); tga[level] = NULL; } } if (texture) { texture->next = texStore->firstTexture; texStore->firstTexture = texture; } return texture; }
GLboolean BBMaterialStore_load (BBMaterialStore* matStore, BBShaderStack* shaderStack, BBTextureStore* texStore, const char* filename, int startLodLevel) { char* buffer; BB_ASSERT(matStore && shaderStack && texStore && filename); buffer = bbReadFileToBuffer(filename); if (!buffer) return GL_FALSE; { char* stream = buffer; GLboolean exit = GL_FALSE; while (!exit) { char* materialName = NULL; if (*stream == '"') { stream++; /* Skip '"' */ materialName = bbParseString(&stream, "\""); } if (materialName) { BBMaterial* material = BBMaterial_create(); char* vertexShaderName = NULL; char* fragShaderName = NULL; char* textureName = NULL; char* texture2Name = NULL; char* texture3Name = NULL; char* texture4Name = NULL; char* cubeTextureName = NULL; if (!material) { free(materialName); break; } material->name = materialName; bbSkipWhite(&stream); if (*stream == '{') { GLboolean innerExit = GL_FALSE; stream++; /* Skip '{' */ while (!innerExit) { char* name = bbParseString(&stream, " \t\"\n\r"); bbSkipWhite(&stream); if (*stream == '"') { stream++; /* Skip '"' */ if (!vertexShaderName && strcmp(name, "vertexShader") == 0) vertexShaderName = bbParseString(&stream, "\""); else if (!fragShaderName && strcmp(name, "fragShader") == 0) fragShaderName = bbParseString(&stream, "\""); else if (!textureName && strcmp(name, "texture") == 0) textureName = bbParseString(&stream, "\""); else if (!texture2Name && strcmp(name, "texture2") == 0) texture2Name = bbParseString(&stream, "\""); else if (!texture3Name && strcmp(name, "texture3") == 0) texture3Name = bbParseString(&stream, "\""); else if (!texture4Name && strcmp(name, "texture4") == 0) texture4Name = bbParseString(&stream, "\""); else if (!cubeTextureName && strcmp(name, "cubeTexture") == 0) cubeTextureName = bbParseString(&stream, "\""); } else { if (strcmp(name, "blend") == 0) material->blend = GL_TRUE; else if (strcmp(name, "additive") == 0) material->additive = GL_TRUE; else if (strcmp(name, "tone") == 0) material->tone = GL_TRUE; } bbSkipWhite(&stream); if (*stream == '}' || *stream == '\0') { if (*stream == '}') stream++; /* Skip '}' */ innerExit = GL_TRUE; } free(name); } } if (vertexShaderName && fragShaderName) material->program = BBShaderStack_getProgram(shaderStack, vertexShaderName, fragShaderName); if (cubeTextureName) material->textures[0] = BBTextureStore_loadCube(texStore, cubeTextureName, startLodLevel); else if (textureName) material->textures[0] = BBTextureStore_load(texStore, textureName, startLodLevel); if (texture2Name) material->textures[1] = BBTextureStore_load(texStore, texture2Name, startLodLevel); if (texture3Name) material->textures[2] = BBTextureStore_load(texStore, texture3Name, startLodLevel); if (texture4Name) material->textures[3] = BBTextureStore_load(texStore, texture4Name, startLodLevel); free(cubeTextureName); free(texture4Name); free(texture3Name); free(texture2Name); free(textureName); free(fragShaderName); free(vertexShaderName); if (!material->program) { #ifdef BB_DEVEL printf("Errors in material: \"%s\"\n", material->name); #endif BBMaterial_destroy(material); break; } material->next = matStore->firstMaterial; matStore->firstMaterial = material; bbSkipWhite(&stream); } else { exit = GL_TRUE; } } } free(buffer); return GL_TRUE; }
BBTexture* BBTexture_create (const char* name, GLsizei width, GLsizei height, GLenum type, GLenum channels, const void** data) { BBTexture* texture; BB_ASSERT(data); if (!(isPow2(width) && isPow2(height))) { #ifdef BB_DEVEL printf("Error: Invalid texture size.\n"); #endif return NULL; } texture = malloc(sizeof(BBTexture)); if (!texture) return NULL; texture->name = NULL; texture->width = width; texture->height = height; texture->type = type; texture->handle = 0; texture->next = NULL; texture->name = strdup(name); if (!texture->name) { BBTexture_destroy(texture); return NULL; } switch (type) { case GL_TEXTURE_2D: glGenTextures(1, &texture->handle); glBindTexture(GL_TEXTURE_2D, texture->handle); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // 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_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); { // GLubyte* origBitmap = (GLubyte*)data[0]; // GLubyte* scaledBitmap = NULL; GLuint level = 0; GLuint w = texture->width; GLuint h = texture->height; GLboolean end = GL_FALSE; while (!end) { // if (level > 0) // { // if (!scaledBitmap) // { // GLsizei bpp = 4; // if (channels == GL_RGB) // bpp = 3; // scaledBitmap = (GLubyte*)malloc(w * h * bpp * sizeof(GLubyte)); // if (!scaledBitmap) // break; // } // generateMipMap(origBitmap, texture->width, texture->height, channels, level, scaledBitmap); // glTexImage2D(GL_TEXTURE_2D, level, channels, w, h, 0, channels, GL_UNSIGNED_BYTE, scaledBitmap); // } // else // { // glTexImage2D(GL_TEXTURE_2D, level, channels, w, h, 0, channels, GL_UNSIGNED_BYTE, origBitmap); // } BB_ASSERT(level < MAX_MIPMAPS && data[level]); glTexImage2D(GL_TEXTURE_2D, level, channels, w, h, 0, channels, GL_UNSIGNED_BYTE, data[level]); w >>= 1; h >>= 1; if (w == 0 && h == 0) { end = GL_TRUE; } else { if (w < 1) w = 1; if (h < 1) h = 1; level++; } } // free(scaledBitmap); } break; case GL_TEXTURE_CUBE_MAP: glGenTextures(1, &texture->handle); glBindTexture(GL_TEXTURE_CUBE_MAP, texture->handle); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, channels, texture->width, texture->height, 0, channels, GL_UNSIGNED_BYTE, data[0]); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, channels, texture->width, texture->height, 0, channels, GL_UNSIGNED_BYTE, data[1]); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, channels, texture->width, texture->height, 0, channels, GL_UNSIGNED_BYTE, data[2]); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, channels, texture->width, texture->height, 0, channels, GL_UNSIGNED_BYTE, data[3]); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, channels, texture->width, texture->height, 0, channels, GL_UNSIGNED_BYTE, data[4]); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, channels, texture->width, texture->height, 0, channels, GL_UNSIGNED_BYTE, data[5]); break; default: BBTexture_destroy(texture); return NULL; } return texture; }