00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00034
00035
00036
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
00065
00066
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
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
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
00107
00108
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
00139
00140
00141
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
00159
00160
00161
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
00193
00194
00195
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
00206
00207
00208
00209
00210 void RocketRenderInterface::
00211 ReleaseCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry) {
00212 delete (CompiledGeometry*) geometry;
00213 }
00214
00215
00216
00217
00218
00219
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
00244
00245
00246
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
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
00282
00283
00284
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
00296
00297
00298
00299
00300 void RocketRenderInterface::
00301 EnableScissorRegion(bool enable) {
00302 _enable_scissor = enable;
00303 }
00304
00305
00306
00307
00308
00309
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 }