|
@@ -0,0 +1,302 @@
|
|
|
|
|
+// Filename: rocketRenderInterface.cxx
|
|
|
|
|
+// Created by: rdb (04Nov11)
|
|
|
|
|
+//
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+//
|
|
|
|
|
+// PANDA 3D SOFTWARE
|
|
|
|
|
+// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
|
|
|
+//
|
|
|
|
|
+// All use of this software is subject to the terms of the revised BSD
|
|
|
|
|
+// license. You should have received a copy of this license along
|
|
|
|
|
+// with this source code in a file named "LICENSE."
|
|
|
|
|
+//
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+
|
|
|
|
|
+#include "rocketRenderInterface.h"
|
|
|
|
|
+#include "cullableObject.h"
|
|
|
|
|
+#include "cullHandler.h"
|
|
|
|
|
+#include "geomVertexData.h"
|
|
|
|
|
+#include "geomVertexArrayData.h"
|
|
|
|
|
+#include "internalName.h"
|
|
|
|
|
+#include "geomVertexWriter.h"
|
|
|
|
|
+#include "geomTriangles.h"
|
|
|
|
|
+#include "texture.h"
|
|
|
|
|
+#include "textureAttrib.h"
|
|
|
|
|
+#include "texturePool.h"
|
|
|
|
|
+#include "colorBlendAttrib.h"
|
|
|
|
|
+#include "cullBinAttrib.h"
|
|
|
|
|
+#include "depthTestAttrib.h"
|
|
|
|
|
+#include "depthWriteAttrib.h"
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::render
|
|
|
|
|
+// Access: Public
|
|
|
|
|
+// Description: Called by RocketNode in cull_callback. Invokes
|
|
|
|
|
+// context->Render() and culls the result.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void RocketRenderInterface::
|
|
|
|
|
+render(Rocket::Core::Context* context, CullTraverser *trav) {
|
|
|
|
|
+ nassertv(context != NULL);
|
|
|
|
|
+ MutexHolder holder(_lock);
|
|
|
|
|
+
|
|
|
|
|
+ const Rocket::Core::Vector2i &dimensions = context->GetDimensions();
|
|
|
|
|
+ //CPT(TransformState) scale = TransformState::make_scale(
|
|
|
|
|
+ // LVector3::right() * (1.0 / dimensions.x) +
|
|
|
|
|
+ // LVector3::down() * (1.0 / dimensions.y));
|
|
|
|
|
+
|
|
|
|
|
+ _trav = trav;
|
|
|
|
|
+ _net_transform = trav->get_world_transform();
|
|
|
|
|
+ _net_state = RenderState::make(
|
|
|
|
|
+ CullBinAttrib::make("unsorted", 0),
|
|
|
|
|
+ DepthTestAttrib::make(RenderAttrib::M_none),
|
|
|
|
|
+ DepthWriteAttrib::make(DepthWriteAttrib::M_off),
|
|
|
|
|
+ ColorBlendAttrib::make(ColorBlendAttrib::M_add,
|
|
|
|
|
+ ColorBlendAttrib::O_incoming_alpha,
|
|
|
|
|
+ ColorBlendAttrib::O_one_minus_incoming_alpha
|
|
|
|
|
+ )
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ context->Render();
|
|
|
|
|
+
|
|
|
|
|
+ _trav = NULL;
|
|
|
|
|
+ _net_transform = NULL;
|
|
|
|
|
+ _net_state = NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::make_geom
|
|
|
|
|
+// Access: Protected
|
|
|
|
|
+// Description: Called internally to make a Geom from Rocket data.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+PT(Geom) RocketRenderInterface::
|
|
|
|
|
+make_geom(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, GeomEnums::UsageHint uh) {
|
|
|
|
|
+ PT(GeomVertexData) vdata = new GeomVertexData("", GeomVertexFormat::get_v3c4t2(), uh);
|
|
|
|
|
+ vdata->unclean_set_num_rows(num_vertices);
|
|
|
|
|
+ {
|
|
|
|
|
+ GeomVertexWriter vwriter(vdata, InternalName::get_vertex());
|
|
|
|
|
+ GeomVertexWriter cwriter(vdata, InternalName::get_color());
|
|
|
|
|
+ GeomVertexWriter twriter(vdata, InternalName::get_texcoord());
|
|
|
|
|
+
|
|
|
|
|
+ // Write the vertex information.
|
|
|
|
|
+ for (int i = 0; i < num_vertices; ++i) {
|
|
|
|
|
+ const Rocket::Core::Vertex &vertex = vertices[i];
|
|
|
|
|
+
|
|
|
|
|
+ vwriter.add_data3f(LVector3f::right() * vertex.position.x + LVector3f::up() * vertex.position.y);
|
|
|
|
|
+ cwriter.add_data4i(vertex.colour.red, vertex.colour.green,
|
|
|
|
|
+ vertex.colour.blue, vertex.colour.alpha);
|
|
|
|
|
+ twriter.add_data2f(vertex.tex_coord.x, 1.0f - vertex.tex_coord.y);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Create a primitive and write the indices.
|
|
|
|
|
+ PT(GeomTriangles) triangles = new GeomTriangles(uh);
|
|
|
|
|
+ {
|
|
|
|
|
+ PT(GeomVertexArrayData) idata = triangles->modify_vertices();
|
|
|
|
|
+ idata->unclean_set_num_rows(num_indices);
|
|
|
|
|
+ GeomVertexWriter iwriter(idata, 0);
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < num_indices; ++i) {
|
|
|
|
|
+ iwriter.add_data1i(indices[i]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ PT(Geom) geom = new Geom(vdata);
|
|
|
|
|
+ geom->add_primitive(triangles);
|
|
|
|
|
+ return geom;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::render_geom
|
|
|
|
|
+// Access: Protected
|
|
|
|
|
+// Description: Only call this during render(). Culls a geom.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void RocketRenderInterface::
|
|
|
|
|
+render_geom(const Geom* geom, const RenderState* state, const Rocket::Core::Vector2f& translation) {
|
|
|
|
|
+ LVector3 offset = LVector3::right() * translation.x + LVector3::up() * translation.y;
|
|
|
|
|
+
|
|
|
|
|
+ rocket_cat.spam()
|
|
|
|
|
+ << "Rendering geom " << geom << " with state "
|
|
|
|
|
+ << *state << " and translation " << offset << "\n";
|
|
|
|
|
+
|
|
|
|
|
+ CPT(TransformState) net_transform, modelview_transform;
|
|
|
|
|
+ net_transform = _net_transform->compose(TransformState::make_pos(offset));
|
|
|
|
|
+ modelview_transform = _trav->get_world_transform()->compose(net_transform);
|
|
|
|
|
+
|
|
|
|
|
+ CullableObject *object =
|
|
|
|
|
+ new CullableObject(geom, _net_state->compose(state),
|
|
|
|
|
+ net_transform, modelview_transform,
|
|
|
|
|
+ _trav->get_gsg());
|
|
|
|
|
+ _trav->get_cull_handler()->record_object(object, _trav);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::RenderGeometry
|
|
|
|
|
+// Access: Protected
|
|
|
|
|
+// Description: Called by Rocket when it wants to render geometry
|
|
|
|
|
+// that the application does not wish to optimize.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void RocketRenderInterface::
|
|
|
|
|
+RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation) {
|
|
|
|
|
+ PT(Geom) geom = make_geom(vertices, num_vertices, indices, num_indices, GeomEnums::UH_stream);
|
|
|
|
|
+
|
|
|
|
|
+ CPT(RenderState) state;
|
|
|
|
|
+ if ((Texture*) texture != (Texture*) NULL) {
|
|
|
|
|
+ state = RenderState::make(TextureAttrib::make((Texture*) texture));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ state = RenderState::make_empty();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ render_geom(geom, state, translation);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::CompileGeometry
|
|
|
|
|
+// Access: Protected
|
|
|
|
|
+// Description: Called by Rocket when it wants to compile geometry
|
|
|
|
|
+// it believes will be static for the forseeable future.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+Rocket::Core::CompiledGeometryHandle RocketRenderInterface::
|
|
|
|
|
+CompileGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture) {
|
|
|
|
|
+
|
|
|
|
|
+ CompiledGeometry *c = new CompiledGeometry;
|
|
|
|
|
+ c->_geom = make_geom(vertices, num_vertices, indices, num_indices, GeomEnums::UH_static);
|
|
|
|
|
+
|
|
|
|
|
+ if ((Texture*) texture != (Texture*) NULL) {
|
|
|
|
|
+ PT(TextureStage) stage = new TextureStage("");
|
|
|
|
|
+ stage->set_mode(TextureStage::M_replace);
|
|
|
|
|
+
|
|
|
|
|
+ CPT(TextureAttrib) attr = DCAST(TextureAttrib, TextureAttrib::make());
|
|
|
|
|
+ attr = DCAST(TextureAttrib, attr->add_on_stage(stage, (Texture*) texture));
|
|
|
|
|
+
|
|
|
|
|
+ c->_state = RenderState::make(attr);
|
|
|
|
|
+
|
|
|
|
|
+ rocket_cat.debug()
|
|
|
|
|
+ << "Compiled geom " << c->_geom << " with texture '"
|
|
|
|
|
+ << ((Texture*) texture)->get_name() << "'\n";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ c->_state = RenderState::make_empty();
|
|
|
|
|
+
|
|
|
|
|
+ rocket_cat.debug()
|
|
|
|
|
+ << "Compiled geom " << c->_geom << " without texture\n";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return (Rocket::Core::CompiledGeometryHandle) c;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::RenderCompiledGeometry
|
|
|
|
|
+// Access: Protected
|
|
|
|
|
+// Description: Called by Rocket when it wants to render
|
|
|
|
|
+// application-compiled geometry.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void RocketRenderInterface::
|
|
|
|
|
+RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry, const Rocket::Core::Vector2f& translation) {
|
|
|
|
|
+
|
|
|
|
|
+ CompiledGeometry *c = (CompiledGeometry*) geometry;
|
|
|
|
|
+ render_geom(c->_geom, c->_state, translation);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::ReleaseCompiledGeometry
|
|
|
|
|
+// Access: Protected
|
|
|
|
|
+// Description: Called by Rocket when it wants to release
|
|
|
|
|
+// application-compiled geometry.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void RocketRenderInterface::
|
|
|
|
|
+ReleaseCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry) {
|
|
|
|
|
+ delete (CompiledGeometry*) geometry;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::LoadTexture
|
|
|
|
|
+// Access: Protected
|
|
|
|
|
+// Description: Called by Rocket when a texture is required by the
|
|
|
|
|
+// library.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+bool RocketRenderInterface::
|
|
|
|
|
+LoadTexture(Rocket::Core::TextureHandle& texture_handle,
|
|
|
|
|
+ Rocket::Core::Vector2i& texture_dimensions,
|
|
|
|
|
+ const Rocket::Core::String& source) {
|
|
|
|
|
+
|
|
|
|
|
+ PT(Texture) tex = TexturePool::load_texture(Filename::from_os_specific(source.CString()));
|
|
|
|
|
+ if (tex == NULL) {
|
|
|
|
|
+ texture_handle = 0;
|
|
|
|
|
+ texture_dimensions.x = 0;
|
|
|
|
|
+ texture_dimensions.y = 0;
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ texture_dimensions.x = tex->get_x_size();
|
|
|
|
|
+ texture_dimensions.y = tex->get_y_size();
|
|
|
|
|
+ tex->ref();
|
|
|
|
|
+ texture_handle = (Rocket::Core::TextureHandle) tex.p();
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::GenerateTexture
|
|
|
|
|
+// Access: Protected
|
|
|
|
|
+// Description: Called by Rocket when a texture is required to be
|
|
|
|
|
+// built from an internally-generated sequence of pixels.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+bool RocketRenderInterface::
|
|
|
|
|
+GenerateTexture(Rocket::Core::TextureHandle& texture_handle,
|
|
|
|
|
+ const Rocket::Core::byte* source,
|
|
|
|
|
+ const Rocket::Core::Vector2i& source_dimensions) {
|
|
|
|
|
+
|
|
|
|
|
+ PT(Texture) tex = new Texture;
|
|
|
|
|
+ tex->setup_2d_texture(source_dimensions.x, source_dimensions.y,
|
|
|
|
|
+ Texture::T_unsigned_byte, Texture::F_rgba);
|
|
|
|
|
+ PTA_uchar image = tex->modify_ram_image();
|
|
|
|
|
+
|
|
|
|
|
+ // Convert RGBA to BGRA
|
|
|
|
|
+ for (size_t i = 0; i < image.size(); i += 4) {
|
|
|
|
|
+ image[i] = source[i + 2];
|
|
|
|
|
+ image[i + 1] = source[i + 1];
|
|
|
|
|
+ image[i + 2] = source[i];
|
|
|
|
|
+ image[i + 3] = source[i + 3];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tex->set_wrap_u(Texture::WM_clamp);
|
|
|
|
|
+ tex->set_wrap_v(Texture::WM_clamp);
|
|
|
|
|
+
|
|
|
|
|
+ tex->ref();
|
|
|
|
|
+ texture_handle = (Rocket::Core::TextureHandle) tex.p();
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::ReleaseTexture
|
|
|
|
|
+// Access: Protected
|
|
|
|
|
+// Description: Called by Rocket when a loaded texture is no longer
|
|
|
|
|
+// required.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void RocketRenderInterface::
|
|
|
|
|
+ReleaseTexture(Rocket::Core::TextureHandle texture_handle) {
|
|
|
|
|
+ Texture* tex = (Texture*) texture_handle;
|
|
|
|
|
+ if (tex != (Texture*) NULL) {
|
|
|
|
|
+ tex->unref();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::EnableScissorRegion
|
|
|
|
|
+// Access: Protected
|
|
|
|
|
+// Description: Called by Rocket when it wants to enable or disable
|
|
|
|
|
+// scissoring to clip content.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void RocketRenderInterface::
|
|
|
|
|
+EnableScissorRegion(bool enable) {
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: RocketRenderInterface::SetScissorRegion
|
|
|
|
|
+// Access: Protected
|
|
|
|
|
+// Description: Called by Rocket when it wants to change the
|
|
|
|
|
+// scissor region.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void RocketRenderInterface::
|
|
|
|
|
+SetScissorRegion(int x, int y, int width, int height) {
|
|
|
|
|
+}
|