mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-07 03:12:36 +01:00
Merge pull request #222 from JayFoxRox/radar-blips
Coloured radar-blips and radardisc z-order
This commit is contained in:
commit
95a0e31484
@ -181,15 +181,19 @@ struct BlipData
|
||||
Vehicle = 1,
|
||||
Pickup = 2,
|
||||
Character = 3,
|
||||
Instance = 4,
|
||||
};
|
||||
BlipType type;
|
||||
GameObjectID target;
|
||||
// If target is null then use coord
|
||||
glm::vec3 coord;
|
||||
|
||||
/* Texture for use in the radar */
|
||||
std::string texture;
|
||||
|
||||
std::string texture; // Texture for use in the radar
|
||||
uint32_t colour = 0; // Color value (index or RGBA)
|
||||
bool dimmed = false; // Color dimming if not in RGBA mode
|
||||
|
||||
uint16_t size = 3; // Only used if texture is empty
|
||||
|
||||
enum DisplayMode
|
||||
{
|
||||
Hide = 0,
|
||||
|
@ -586,6 +586,8 @@ GameObject*GameWorld::getBlipTarget(const BlipData& blip) const
|
||||
return pedestrianPool.find(blip.target);
|
||||
case BlipData::Pickup:
|
||||
return pickupPool.find(blip.target);
|
||||
case BlipData::Instance:
|
||||
return instancePool.find(blip.target);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -376,42 +376,43 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
|
||||
for( auto& blip : world->state->radarBlips )
|
||||
{
|
||||
auto dm = blip.second.display;
|
||||
if( dm == BlipData::ShowBoth || dm == BlipData::MarkerOnly )
|
||||
{
|
||||
glm::mat4 model;
|
||||
|
||||
if( blip.second.target > 0 )
|
||||
{
|
||||
auto object = world->getBlipTarget(blip.second);
|
||||
if( object )
|
||||
{
|
||||
model = object->getTimeAdjustedTransform( _renderAlpha );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
model = glm::translate( model, blip.second.coord );
|
||||
}
|
||||
|
||||
float a = world->getGameTime() * glm::pi<float>();
|
||||
model = glm::translate( model, glm::vec3(0.f, 0.f, 2.5f + glm::sin( a ) * 0.5f) );
|
||||
model = glm::rotate( model, a, glm::vec3(0.f, 0.f, 1.f) );
|
||||
model = glm::scale( model, glm::vec3(1.5f, 1.5f, 1.5f) );
|
||||
|
||||
Renderer::DrawParameters dp;
|
||||
dp.textures = {arrowTex->getName()};
|
||||
dp.ambient = 1.f;
|
||||
dp.colour = glm::u8vec4(255, 255, 255, 255);
|
||||
|
||||
auto geom = arrowModel->resource->geometries[arrowFrame->getGeometries()[0]];
|
||||
Model::SubGeometry& sg = geom->subgeom[0];
|
||||
|
||||
dp.start = sg.start;
|
||||
dp.count = sg.numIndices;
|
||||
dp.diffuse = 1.f;
|
||||
|
||||
renderer->draw( model, &geom->dbuff, dp );
|
||||
if( dm == BlipData::Hide || dm == BlipData::RadarOnly ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
glm::mat4 model;
|
||||
|
||||
if( blip.second.target > 0 )
|
||||
{
|
||||
auto object = world->getBlipTarget(blip.second);
|
||||
if( object )
|
||||
{
|
||||
model = object->getTimeAdjustedTransform( _renderAlpha );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
model = glm::translate( model, blip.second.coord );
|
||||
}
|
||||
|
||||
float a = world->getGameTime() * glm::pi<float>();
|
||||
model = glm::translate( model, glm::vec3(0.f, 0.f, 2.5f + glm::sin( a ) * 0.5f) );
|
||||
model = glm::rotate( model, a, glm::vec3(0.f, 0.f, 1.f) );
|
||||
model = glm::scale( model, glm::vec3(1.5f, 1.5f, 1.5f) );
|
||||
|
||||
Renderer::DrawParameters dp;
|
||||
dp.textures = {arrowTex->getName()};
|
||||
dp.ambient = 1.f;
|
||||
dp.colour = glm::u8vec4(255, 255, 255, 255);
|
||||
|
||||
auto geom = arrowModel->resource->geometries[arrowFrame->getGeometries()[0]];
|
||||
Model::SubGeometry& sg = geom->subgeom[0];
|
||||
|
||||
dp.start = sg.start;
|
||||
dp.count = sg.numIndices;
|
||||
dp.diffuse = 1.f;
|
||||
|
||||
renderer->draw( model, &geom->dbuff, dp );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,13 +42,13 @@ MapRenderer::MapRenderer(Renderer* renderer, GameData* _data)
|
||||
: data(_data), renderer(renderer)
|
||||
{
|
||||
rectGeom.uploadVertices<VertexP2>({
|
||||
{-.5f, .5f},
|
||||
{ .5f, .5f},
|
||||
{-.5f, -.5f},
|
||||
{ .5f, -.5f}
|
||||
{ .5f, -.5f},
|
||||
{ .5f, .5f},
|
||||
{-.5f, .5f}
|
||||
});
|
||||
rect.addGeometry(&rectGeom);
|
||||
rect.setFaceType(GL_TRIANGLE_STRIP);
|
||||
rect.setFaceType(GL_TRIANGLE_FAN);
|
||||
|
||||
std::vector<VertexP2> circleVerts;
|
||||
circleVerts.push_back({0.f, 0.f});
|
||||
@ -142,7 +142,7 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
|
||||
|
||||
renderer->setUniform(rectProg, "model", tilemodel);
|
||||
|
||||
glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
|
||||
glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
|
||||
}
|
||||
|
||||
// From here on out we will work in screenspace
|
||||
@ -159,35 +159,89 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
|
||||
model = glm::scale(model, glm::vec3(mi.screenSize*1.07));
|
||||
renderer->setUniform(rectProg, "model", model);
|
||||
glBindTexture(GL_TEXTURE_2D, radarDisc->getName());
|
||||
glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
|
||||
glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
}
|
||||
|
||||
for(auto& blip : world->state->radarBlips)
|
||||
{
|
||||
glm::vec2 blippos( blip.second.coord );
|
||||
if( blip.second.target > 0 )
|
||||
{
|
||||
GameObject* object = world->getBlipTarget(blip.second);
|
||||
if( object )
|
||||
{
|
||||
blippos = glm::vec2( object->getPosition() );
|
||||
}
|
||||
}
|
||||
|
||||
drawBlip(blippos, view, mi, blip.second.texture);
|
||||
}
|
||||
|
||||
|
||||
// Draw the player blip
|
||||
auto player = world->pedestrianPool.find(world->state->playerObject);
|
||||
if( player )
|
||||
{
|
||||
glm::vec2 plyblip(player->getPosition());
|
||||
float hdg = glm::roll(player->getRotation());
|
||||
drawBlip(plyblip, view, mi, "radar_centre", mi.rotation - hdg);
|
||||
drawBlip(
|
||||
plyblip, view, mi,
|
||||
"radar_centre", glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), 18.0f, mi.rotation - hdg
|
||||
);
|
||||
}
|
||||
|
||||
drawBlip(mi.worldCenter + glm::vec2(0.f, mi.worldSize), view, mi, "radar_north", 0.f, 24.f);
|
||||
drawBlip(
|
||||
mi.worldCenter + glm::vec2(0.f, mi.worldSize), view, mi,
|
||||
"radar_north", glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), 24.f
|
||||
);
|
||||
|
||||
for(auto& radarBlip : world->state->radarBlips)
|
||||
{
|
||||
const auto& blip = radarBlip.second;
|
||||
|
||||
auto dm = blip.display;
|
||||
if( dm == BlipData::Hide || dm == BlipData::MarkerOnly ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
glm::vec2 blippos( blip.coord );
|
||||
if( blip.target > 0 )
|
||||
{
|
||||
GameObject* object = world->getBlipTarget(blip);
|
||||
if( object )
|
||||
{
|
||||
blippos = glm::vec2( object->getPosition() );
|
||||
}
|
||||
}
|
||||
|
||||
const auto& texture = blip.texture;
|
||||
if (!texture.empty()) {
|
||||
drawBlip(blippos, view, mi, texture, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), 18.0f);
|
||||
} else {
|
||||
// Colours from http://www.gtamodding.com/wiki/0165 (colors not specific to that opcode!)
|
||||
uint32_t rgbaValue;
|
||||
switch(blip.colour) {
|
||||
case 0: // RED
|
||||
rgbaValue = blip.dimmed ? 0x7F0000FF : 0x712B49FF;
|
||||
break;
|
||||
case 1: // GREEN
|
||||
rgbaValue = blip.dimmed ? 0x007F00FF : 0x5FA06AFF;
|
||||
break;
|
||||
case 2: // BLUE
|
||||
rgbaValue = blip.dimmed ? 0x00007FFF : 0x80A7F3FF;
|
||||
break;
|
||||
case 3: // WHITE
|
||||
rgbaValue = blip.dimmed ? 0x7F7F7FFF : 0xE1E1E1FF;
|
||||
break;
|
||||
case 4: // YELLOW
|
||||
rgbaValue = blip.dimmed ? 0x7F7F00FF : 0xFFFF00FF;
|
||||
break;
|
||||
case 5: // PURPLE
|
||||
rgbaValue = blip.dimmed ? 0x7F007FFF : 0xFF00FFFF;
|
||||
break;
|
||||
case 6: // CYAN
|
||||
rgbaValue = blip.dimmed ? 0x007F7FFF : 0x00FFFFFF;
|
||||
break;
|
||||
default: // Extended mode (Dimming ignored)
|
||||
rgbaValue = blip.colour;
|
||||
break;
|
||||
}
|
||||
|
||||
glm::vec4 colour(
|
||||
(rgbaValue >> 24) / 255.0f,
|
||||
((rgbaValue >> 16) & 0xFF) / 255.0f,
|
||||
((rgbaValue >> 8) & 0xFF) / 255.0f,
|
||||
1.0f // Note: Alpha is not controlled by blip
|
||||
);
|
||||
|
||||
drawBlip(blippos, view, mi, colour, blip.size * 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray( 0 );
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
@ -198,7 +252,7 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
|
||||
renderer->popDebugGroup();
|
||||
}
|
||||
|
||||
void MapRenderer::drawBlip(const glm::vec2& coord, const glm::mat4& view, const MapInfo& mi, const std::string& texture, float heading, float size)
|
||||
void MapRenderer::prepareBlip(const glm::vec2& coord, const glm::mat4& view, const MapInfo& mi, const std::string& texture, glm::vec4 colour, float size, float heading)
|
||||
{
|
||||
glm::vec2 adjustedCoord = coord;
|
||||
if (mi.clipToSize)
|
||||
@ -222,14 +276,23 @@ void MapRenderer::drawBlip(const glm::vec2& coord, const glm::mat4& view, const
|
||||
{
|
||||
auto sprite= data->findTexture(texture);
|
||||
tex = sprite->getName();
|
||||
renderer->setUniform(rectProg, "colour", glm::vec4(0.f, 0.f, 0.f, 1.f));
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer->setUniform(rectProg, "colour", glm::vec4(1.0f, 1.0f, 1.0f, 1.f));
|
||||
}
|
||||
renderer->setUniform(rectProg, "colour", colour);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
|
||||
glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
|
||||
glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
|
||||
}
|
||||
|
||||
void MapRenderer::drawBlip(const glm::vec2& coord, const glm::mat4& view, const MapInfo& mi, const std::string& texture, glm::vec4 colour, float size, float heading) {
|
||||
prepareBlip(coord, view, mi, texture, colour, size, heading);
|
||||
glBindVertexArray( rect.getVAOName() );
|
||||
glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
|
||||
}
|
||||
|
||||
void MapRenderer::drawBlip(const glm::vec2& coord, const glm::mat4& view, const MapInfo& mi, glm::vec4 colour, float size) {
|
||||
drawBlip(coord, view, mi, "", colour, size);
|
||||
// Draw outline
|
||||
renderer->setUniform(rectProg, "colour", glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
glDrawArrays( GL_LINE_LOOP, 0, 4 );
|
||||
}
|
||||
|
@ -45,5 +45,7 @@ private:
|
||||
|
||||
Renderer::ShaderProgram* rectProg;
|
||||
|
||||
void drawBlip(const glm::vec2& map, const glm::mat4& view, const MapInfo& mi, const std::string& texture, float heading = 0.f, float size = 18.f);
|
||||
void prepareBlip(const glm::vec2& coord, const glm::mat4& view, const MapInfo& mi, const std::string& texture, glm::vec4 colour, float size, float heading);
|
||||
void drawBlip(const glm::vec2& coord, const glm::mat4& view, const MapInfo& mi, const std::string& texture, glm::vec4 colour, float size, float heading = 0.0f);
|
||||
void drawBlip(const glm::vec2& coord, const glm::mat4& view, const MapInfo& mi, glm::vec4 colour, float size);
|
||||
};
|
||||
|
@ -152,12 +152,19 @@ inline BlipData& createObjectBlip(const ScriptArguments& args, GameObject* objec
|
||||
switch(object->type()) {
|
||||
case GameObject::Vehicle:
|
||||
data.type = BlipData::Vehicle;
|
||||
data.colour = 0; // @todo 4 in Vice City
|
||||
break;
|
||||
case GameObject::Character:
|
||||
data.type = BlipData::Character;
|
||||
data.colour = 1; // @todo 4 in Vice City
|
||||
break;
|
||||
case GameObject::Pickup:
|
||||
data.type = BlipData::Pickup;
|
||||
data.colour = 6; // @todo 4 in Vice City
|
||||
break;
|
||||
case GameObject::Instance:
|
||||
data.type = BlipData::Instance;
|
||||
data.colour = 6; // @todo 4 in Vice City
|
||||
break;
|
||||
default:
|
||||
data.type = BlipData::Location;
|
||||
@ -165,7 +172,9 @@ inline BlipData& createObjectBlip(const ScriptArguments& args, GameObject* objec
|
||||
break;
|
||||
}
|
||||
data.target = object->getScriptObjectID();
|
||||
data.display = BlipData::ShowBoth;
|
||||
data.texture = "";
|
||||
data.size = 3;
|
||||
auto blip = args.getState()->addRadarBlip(data);
|
||||
return args.getState()->radarBlips[blip];
|
||||
}
|
||||
@ -186,6 +195,9 @@ inline BlipData createObjectBlipSprite(const ScriptArguments& args, GameObject*
|
||||
case GameObject::Pickup:
|
||||
data.type = BlipData::Pickup;
|
||||
break;
|
||||
case GameObject::Instance:
|
||||
data.type = BlipData::Instance;
|
||||
break;
|
||||
default:
|
||||
data.type = BlipData::Location;
|
||||
RW_ERROR("Unhandled blip type");
|
||||
|
@ -4398,10 +4398,8 @@ void opcode_0187(const ScriptArguments& args, const ScriptCharacter character, S
|
||||
@arg blip Blip
|
||||
*/
|
||||
void opcode_0188(const ScriptArguments& args, const ScriptObject object, ScriptBlip& blip) {
|
||||
RW_UNIMPLEMENTED_OPCODE(0x0188);
|
||||
RW_UNUSED(object);
|
||||
RW_UNUSED(blip);
|
||||
RW_UNUSED(args);
|
||||
auto& data = script::createObjectBlip(args, object);
|
||||
blip = &data;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4432,6 +4430,8 @@ void opcode_018a(const ScriptArguments& args, ScriptVec3 coord, ScriptBlip& blip
|
||||
// Coordinate blips are not visible
|
||||
data.display = BlipData::RadarOnly;
|
||||
data.texture = "";
|
||||
data.colour = 5;
|
||||
data.size = 3;
|
||||
args.getState()->addRadarBlip(data);
|
||||
blip = &data;
|
||||
}
|
||||
@ -4448,6 +4448,9 @@ void opcode_018b(const ScriptArguments& args, const ScriptBlip blip, const Scrip
|
||||
default:
|
||||
blip->display = BlipData::Hide;
|
||||
break;
|
||||
case 1:
|
||||
blip->display = BlipData::MarkerOnly;
|
||||
break;
|
||||
case 2:
|
||||
blip->display = BlipData::RadarOnly;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user