Panda3D
|
00001 // Filename: rocketRenderInterface.cxx 00002 // Created by: rdb (04Nov11) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "rocketRenderInterface.h" 00016 #include "cullableObject.h" 00017 #include "cullHandler.h" 00018 #include "geomVertexData.h" 00019 #include "geomVertexArrayData.h" 00020 #include "internalName.h" 00021 #include "geomVertexWriter.h" 00022 #include "geomTriangles.h" 00023 #include "colorBlendAttrib.h" 00024 #include "cullBinAttrib.h" 00025 #include "depthTestAttrib.h" 00026 #include "depthWriteAttrib.h" 00027 #include "scissorAttrib.h" 00028 #include "texture.h" 00029 #include "textureAttrib.h" 00030 #include "texturePool.h" 00031 00032 //////////////////////////////////////////////////////////////////// 00033 // Function: RocketRenderInterface::render 00034 // Access: Public 00035 // Description: Called by RocketNode in cull_callback. Invokes 00036 // context->Render() and culls the result. 00037 //////////////////////////////////////////////////////////////////// 00038 void RocketRenderInterface:: 00039 render(Rocket::Core::Context* context, CullTraverser *trav) { 00040 nassertv(context != NULL); 00041 MutexHolder holder(_lock); 00042 00043 _trav = trav; 00044 _net_transform = trav->get_world_transform(); 00045 _net_state = RenderState::make( 00046 CullBinAttrib::make("unsorted", 0), 00047 DepthTestAttrib::make(RenderAttrib::M_none), 00048 DepthWriteAttrib::make(DepthWriteAttrib::M_off), 00049 ColorBlendAttrib::make(ColorBlendAttrib::M_add, 00050 ColorBlendAttrib::O_incoming_alpha, 00051 ColorBlendAttrib::O_one_minus_incoming_alpha 00052 ) 00053 ); 00054 _dimensions = context->GetDimensions(); 00055 00056 context->Render(); 00057 00058 _trav = NULL; 00059 _net_transform = NULL; 00060 _net_state = NULL; 00061 } 00062 00063 //////////////////////////////////////////////////////////////////// 00064 // Function: RocketRenderInterface::make_geom 00065 // Access: Protected 00066 // Description: Called internally to make a Geom from Rocket data. 00067 //////////////////////////////////////////////////////////////////// 00068 PT(Geom) RocketRenderInterface:: 00069 make_geom(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, GeomEnums::UsageHint uh) { 00070 PT(GeomVertexData) vdata = new GeomVertexData("", GeomVertexFormat::get_v3c4t2(), uh); 00071 vdata->unclean_set_num_rows(num_vertices); 00072 { 00073 GeomVertexWriter vwriter(vdata, InternalName::get_vertex()); 00074 GeomVertexWriter cwriter(vdata, InternalName::get_color()); 00075 GeomVertexWriter twriter(vdata, InternalName::get_texcoord()); 00076 00077 // Write the vertex information. 00078 for (int i = 0; i < num_vertices; ++i) { 00079 const Rocket::Core::Vertex &vertex = vertices[i]; 00080 00081 vwriter.add_data3f(LVector3f::right() * vertex.position.x + LVector3f::up() * vertex.position.y); 00082 cwriter.add_data4i(vertex.colour.red, vertex.colour.green, 00083 vertex.colour.blue, vertex.colour.alpha); 00084 twriter.add_data2f(vertex.tex_coord.x, 1.0f - vertex.tex_coord.y); 00085 } 00086 } 00087 00088 // Create a primitive and write the indices. 00089 PT(GeomTriangles) triangles = new GeomTriangles(uh); 00090 { 00091 PT(GeomVertexArrayData) idata = triangles->modify_vertices(); 00092 idata->unclean_set_num_rows(num_indices); 00093 GeomVertexWriter iwriter(idata, 0); 00094 00095 for (int i = 0; i < num_indices; ++i) { 00096 iwriter.add_data1i(indices[i]); 00097 } 00098 } 00099 00100 PT(Geom) geom = new Geom(vdata); 00101 geom->add_primitive(triangles); 00102 return geom; 00103 } 00104 00105 //////////////////////////////////////////////////////////////////// 00106 // Function: RocketRenderInterface::render_geom 00107 // Access: Protected 00108 // Description: Only call this during render(). Culls a geom. 00109 //////////////////////////////////////////////////////////////////// 00110 void RocketRenderInterface:: 00111 render_geom(const Geom* geom, const RenderState* state, const Rocket::Core::Vector2f& translation) { 00112 LVector3 offset = LVector3::right() * translation.x + LVector3::up() * translation.y; 00113 00114 if (_enable_scissor) { 00115 state = state->add_attrib(ScissorAttrib::make(_scissor)); 00116 rocket_cat.spam() 00117 << "Rendering geom " << geom << " with state " 00118 << *state << ", translation (" << offset << "), " 00119 << "scissor region (" << _scissor << ")\n"; 00120 } else { 00121 rocket_cat.spam() 00122 << "Rendering geom " << geom << " with state " 00123 << *state << ", translation (" << offset << ")\n"; 00124 } 00125 00126 CPT(TransformState) net_transform, modelview_transform; 00127 net_transform = _net_transform->compose(TransformState::make_pos(offset)); 00128 modelview_transform = _trav->get_world_transform()->compose(net_transform); 00129 00130 CullableObject *object = 00131 new CullableObject(geom, _net_state->compose(state), 00132 net_transform, modelview_transform, 00133 _trav->get_gsg()); 00134 _trav->get_cull_handler()->record_object(object, _trav); 00135 } 00136 00137 //////////////////////////////////////////////////////////////////// 00138 // Function: RocketRenderInterface::RenderGeometry 00139 // Access: Protected 00140 // Description: Called by Rocket when it wants to render geometry 00141 // that the application does not wish to optimize. 00142 //////////////////////////////////////////////////////////////////// 00143 void RocketRenderInterface:: 00144 RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation) { 00145 PT(Geom) geom = make_geom(vertices, num_vertices, indices, num_indices, GeomEnums::UH_stream); 00146 00147 CPT(RenderState) state; 00148 if ((Texture*) texture != (Texture*) NULL) { 00149 state = RenderState::make(TextureAttrib::make((Texture*) texture)); 00150 } else { 00151 state = RenderState::make_empty(); 00152 } 00153 00154 render_geom(geom, state, translation); 00155 } 00156 00157 //////////////////////////////////////////////////////////////////// 00158 // Function: RocketRenderInterface::CompileGeometry 00159 // Access: Protected 00160 // Description: Called by Rocket when it wants to compile geometry 00161 // it believes will be static for the forseeable future. 00162 //////////////////////////////////////////////////////////////////// 00163 Rocket::Core::CompiledGeometryHandle RocketRenderInterface:: 00164 CompileGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture) { 00165 00166 CompiledGeometry *c = new CompiledGeometry; 00167 c->_geom = make_geom(vertices, num_vertices, indices, num_indices, GeomEnums::UH_static); 00168 00169 if ((Texture*) texture != (Texture*) NULL) { 00170 PT(TextureStage) stage = new TextureStage(""); 00171 stage->set_mode(TextureStage::M_modulate); 00172 00173 CPT(TextureAttrib) attr = DCAST(TextureAttrib, TextureAttrib::make()); 00174 attr = DCAST(TextureAttrib, attr->add_on_stage(stage, (Texture*) texture)); 00175 00176 c->_state = RenderState::make(attr); 00177 00178 rocket_cat.debug() 00179 << "Compiled geom " << c->_geom << " with texture '" 00180 << ((Texture*) texture)->get_name() << "'\n"; 00181 } else { 00182 c->_state = RenderState::make_empty(); 00183 00184 rocket_cat.debug() 00185 << "Compiled geom " << c->_geom << " without texture\n"; 00186 } 00187 00188 return (Rocket::Core::CompiledGeometryHandle) c; 00189 } 00190 00191 //////////////////////////////////////////////////////////////////// 00192 // Function: RocketRenderInterface::RenderCompiledGeometry 00193 // Access: Protected 00194 // Description: Called by Rocket when it wants to render 00195 // application-compiled geometry. 00196 //////////////////////////////////////////////////////////////////// 00197 void RocketRenderInterface:: 00198 RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry, const Rocket::Core::Vector2f& translation) { 00199 00200 CompiledGeometry *c = (CompiledGeometry*) geometry; 00201 render_geom(c->_geom, c->_state, translation); 00202 } 00203 00204 //////////////////////////////////////////////////////////////////// 00205 // Function: RocketRenderInterface::ReleaseCompiledGeometry 00206 // Access: Protected 00207 // Description: Called by Rocket when it wants to release 00208 // application-compiled geometry. 00209 //////////////////////////////////////////////////////////////////// 00210 void RocketRenderInterface:: 00211 ReleaseCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry) { 00212 delete (CompiledGeometry*) geometry; 00213 } 00214 00215 //////////////////////////////////////////////////////////////////// 00216 // Function: RocketRenderInterface::LoadTexture 00217 // Access: Protected 00218 // Description: Called by Rocket when a texture is required by the 00219 // library. 00220 //////////////////////////////////////////////////////////////////// 00221 bool RocketRenderInterface:: 00222 LoadTexture(Rocket::Core::TextureHandle& texture_handle, 00223 Rocket::Core::Vector2i& texture_dimensions, 00224 const Rocket::Core::String& source) { 00225 00226 PT(Texture) tex = TexturePool::load_texture(Filename::from_os_specific(source.CString())); 00227 if (tex == NULL) { 00228 texture_handle = 0; 00229 texture_dimensions.x = 0; 00230 texture_dimensions.y = 0; 00231 return false; 00232 } 00233 00234 texture_dimensions.x = tex->get_x_size(); 00235 texture_dimensions.y = tex->get_y_size(); 00236 tex->ref(); 00237 texture_handle = (Rocket::Core::TextureHandle) tex.p(); 00238 00239 return true; 00240 } 00241 00242 //////////////////////////////////////////////////////////////////// 00243 // Function: RocketRenderInterface::GenerateTexture 00244 // Access: Protected 00245 // Description: Called by Rocket when a texture is required to be 00246 // built from an internally-generated sequence of pixels. 00247 //////////////////////////////////////////////////////////////////// 00248 bool RocketRenderInterface:: 00249 GenerateTexture(Rocket::Core::TextureHandle& texture_handle, 00250 const Rocket::Core::byte* source, 00251 const Rocket::Core::Vector2i& source_dimensions) { 00252 00253 PT(Texture) tex = new Texture; 00254 tex->setup_2d_texture(source_dimensions.x, source_dimensions.y, 00255 Texture::T_unsigned_byte, Texture::F_rgba); 00256 PTA_uchar image = tex->modify_ram_image(); 00257 00258 // Convert RGBA to BGRA 00259 size_t row_size = source_dimensions.x * 4; 00260 size_t y2 = image.size(); 00261 for (size_t y = 0; y < image.size(); y += row_size) { 00262 y2 -= row_size; 00263 for (size_t i = 0; i < row_size; i += 4) { 00264 image[y2 + i + 0] = source[y + i + 2]; 00265 image[y2 + i + 1] = source[y + i + 1]; 00266 image[y2 + i + 2] = source[y + i]; 00267 image[y2 + i + 3] = source[y + i + 3]; 00268 } 00269 } 00270 00271 tex->set_wrap_u(Texture::WM_clamp); 00272 tex->set_wrap_v(Texture::WM_clamp); 00273 00274 tex->ref(); 00275 texture_handle = (Rocket::Core::TextureHandle) tex.p(); 00276 00277 return true; 00278 } 00279 00280 //////////////////////////////////////////////////////////////////// 00281 // Function: RocketRenderInterface::ReleaseTexture 00282 // Access: Protected 00283 // Description: Called by Rocket when a loaded texture is no longer 00284 // required. 00285 //////////////////////////////////////////////////////////////////// 00286 void RocketRenderInterface:: 00287 ReleaseTexture(Rocket::Core::TextureHandle texture_handle) { 00288 Texture* tex = (Texture*) texture_handle; 00289 if (tex != (Texture*) NULL) { 00290 tex->unref(); 00291 } 00292 } 00293 00294 //////////////////////////////////////////////////////////////////// 00295 // Function: RocketRenderInterface::EnableScissorRegion 00296 // Access: Protected 00297 // Description: Called by Rocket when it wants to enable or disable 00298 // scissoring to clip content. 00299 //////////////////////////////////////////////////////////////////// 00300 void RocketRenderInterface:: 00301 EnableScissorRegion(bool enable) { 00302 _enable_scissor = enable; 00303 } 00304 00305 //////////////////////////////////////////////////////////////////// 00306 // Function: RocketRenderInterface::SetScissorRegion 00307 // Access: Protected 00308 // Description: Called by Rocket when it wants to change the 00309 // scissor region. 00310 //////////////////////////////////////////////////////////////////// 00311 void RocketRenderInterface:: 00312 SetScissorRegion(int x, int y, int width, int height) { 00313 _scissor[0] = x / (PN_stdfloat) _dimensions.x; 00314 _scissor[1] = (x + width) / (PN_stdfloat) _dimensions.x; 00315 _scissor[2] = 1.0f - ((y + height) / (PN_stdfloat) _dimensions.y); 00316 _scissor[3] = 1.0f - (y / (PN_stdfloat) _dimensions.y); 00317 }