1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-07 03:12:36 +01:00

clang-format files in rwengine/src/render

This commit is contained in:
Daniel Evans 2016-09-09 21:13:20 +01:00
parent 1e4d7ea133
commit e888d04303
20 changed files with 2763 additions and 2965 deletions

View File

@ -6,9 +6,7 @@
#include <iostream>
DebugDraw::DebugDraw()
: shaderProgram(nullptr)
{
DebugDraw::DebugDraw() : shaderProgram(nullptr) {
lineBuff = new GeometryBuffer;
dbuff = new DrawBuffer;
dbuff->setFaceType(GL_LINES);
@ -18,41 +16,33 @@ DebugDraw::DebugDraw()
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
int img = 0xFFFFFFFF;
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
0, GL_RGBA, GL_UNSIGNED_BYTE, &img
);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
&img);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
maxlines = 0;
}
DebugDraw::~DebugDraw()
{
DebugDraw::~DebugDraw() {
delete dbuff;
delete lineBuff;
}
void DebugDraw::drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)
{
void DebugDraw::drawLine(const btVector3 &from, const btVector3 &to,
const btVector3 &color) {
btVector3 c = color * 255;
lines.push_back({
glm::vec3(from.getX(), from.getY(), from.getZ()),
glm::vec3(0.f),
lines.push_back({glm::vec3(from.getX(), from.getY(), from.getZ()),
glm::vec3(0.f), glm::vec2(0.f),
glm::u8vec4(c.getX(), c.getY(), c.getZ(), 255)});
lines.push_back({glm::vec3(to.getX(), to.getY(), to.getZ()), glm::vec3(0.f),
glm::vec2(0.f),
glm::u8vec4(c.getX(), c.getY(), c.getZ(), 255)
});
lines.push_back({
glm::vec3(to.getX(), to.getY(), to.getZ()),
glm::vec3(0.f),
glm::vec2(0.f),
glm::u8vec4(c.getX(), c.getY(), c.getZ(), 255)
});
glm::u8vec4(c.getX(), c.getY(), c.getZ(), 255)});
}
void DebugDraw::drawContactPoint(const btVector3 &pointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color)
{
void DebugDraw::drawContactPoint(const btVector3 &pointOnB,
const btVector3 &normalOnB, btScalar distance,
int lifeTime, const btVector3 &color) {
RW_UNUSED(pointOnB);
RW_UNUSED(normalOnB);
RW_UNUSED(distance);
@ -60,8 +50,7 @@ void DebugDraw::drawContactPoint(const btVector3 &pointOnB, const btVector3 &nor
RW_UNUSED(color);
}
void DebugDraw::flush(GameRenderer* renderer)
{
void DebugDraw::flush(GameRenderer *renderer) {
if (lines.size() == 0) {
return;
}
@ -91,23 +80,19 @@ void DebugDraw::flush(GameRenderer* renderer)
lines.clear();
}
void DebugDraw::reportErrorWarning(const char *warningString)
{
void DebugDraw::reportErrorWarning(const char *warningString) {
std::cerr << warningString << std::endl;
}
void DebugDraw::draw3dText(const btVector3 &location, const char *textString)
{
void DebugDraw::draw3dText(const btVector3 &location, const char *textString) {
RW_UNUSED(location);
std::cout << textString << std::endl;
}
void DebugDraw::setDebugMode(int debugMode)
{
void DebugDraw::setDebugMode(int debugMode) {
this->debugMode = debugMode;
}
int DebugDraw::getDebugMode() const
{
int DebugDraw::getDebugMode() const {
return debugMode;
}

View File

@ -1,17 +1,19 @@
#pragma once
#include <LinearMath/btIDebugDraw.h>
#include <render/GameRenderer.hpp>
#include <data/Model.hpp>
#include <render/GameRenderer.hpp>
class DebugDraw : public btIDebugDraw
{
class DebugDraw : public btIDebugDraw {
public:
DebugDraw();
~DebugDraw();
void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color);
void drawContactPoint(const btVector3 &pointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color);
void drawLine(const btVector3 &from, const btVector3 &to,
const btVector3 &color);
void drawContactPoint(const btVector3 &pointOnB, const btVector3 &normalOnB,
btScalar distance, int lifeTime,
const btVector3 &color);
void reportErrorWarning(const char *warningString);
void draw3dText(const btVector3 &location, const char *textString);
void setDebugMode(int debugMode);

View File

@ -1,14 +1,14 @@
#include <render/GameRenderer.hpp>
#include <engine/GameWorld.hpp>
#include <data/Model.hpp>
#include <engine/Animator.hpp>
#include <engine/GameState.hpp>
#include <data/Model.hpp>
#include <engine/GameWorld.hpp>
#include <render/GameRenderer.hpp>
#include <objects/CharacterObject.hpp>
#include <objects/InstanceObject.hpp>
#include <objects/VehicleObject.hpp>
#include <objects/PickupObject.hpp>
#include <objects/ProjectileObject.hpp>
#include <objects/VehicleObject.hpp>
#include <ai/CharacterController.hpp>
#include <data/ObjectData.hpp>
@ -19,8 +19,8 @@
#include <objects/CutsceneObject.hpp>
#include <render/ObjectRenderer.hpp>
#include <render/GameShaders.hpp>
#include <core/Logger.hpp>
#include <render/GameShaders.hpp>
#include <deque>
#include <glm/gtc/constants.hpp>
@ -31,17 +31,14 @@
const size_t skydomeSegments = 8, skydomeRows = 10;
constexpr uint32_t kMissingTextureBytes[] = {
0xFF0000FF, 0xFFFF00FF, 0xFF0000FF, 0xFFFF00FF,
0xFFFF00FF, 0xFF0000FF, 0xFFFF00FF, 0xFF0000FF,
0xFF0000FF, 0xFFFF00FF, 0xFF0000FF, 0xFFFF00FF,
0xFF0000FF, 0xFFFF00FF, 0xFF0000FF, 0xFFFF00FF, 0xFFFF00FF, 0xFF0000FF,
0xFFFF00FF, 0xFF0000FF, 0xFF0000FF, 0xFFFF00FF, 0xFF0000FF, 0xFFFF00FF,
0xFFFF00FF, 0xFF0000FF, 0xFFFF00FF, 0xFF0000FF,
};
struct WaterVertex {
static const AttributeList vertex_attributes() {
return {
{ATRS_Position, 2, sizeof(WaterVertex), 0ul}
};
return {{ATRS_Position, 2, sizeof(WaterVertex), 0ul}};
}
float x, y;
@ -50,11 +47,9 @@ struct WaterVertex {
/// @todo collapse all of these into "VertPNC" etc.
struct ParticleVert {
static const AttributeList vertex_attributes() {
return {
{ATRS_Position, 2, sizeof(ParticleVert), 0ul},
return {{ATRS_Position, 2, sizeof(ParticleVert), 0ul},
{ATRS_TexCoord, 2, sizeof(ParticleVert), 2ul * sizeof(float)},
{ATRS_Colour, 3, sizeof(ParticleVert), 4ul * sizeof(float)}
};
{ATRS_Colour, 3, sizeof(ParticleVert), 4ul * sizeof(float)}};
}
float x, y;
@ -66,10 +61,7 @@ GeometryBuffer particleGeom;
DrawBuffer particleDraw;
std::vector<VertexP2> sspaceRect = {
{-1.f, -1.f},
{ 1.f, -1.f},
{-1.f, 1.f},
{ 1.f, 1.f},
{-1.f, -1.f}, {1.f, -1.f}, {-1.f, 1.f}, {1.f, 1.f},
};
GeometryBuffer ssRectGeom;
@ -84,41 +76,40 @@ GameRenderer::GameRenderer(Logger* log, GameData* _data)
, cullOverride(false)
, map(renderer, _data)
, water(this)
, text(this)
{
, text(this) {
logger->info("Renderer", renderer->getIDString());
worldProg = renderer->createShader(
GameShaders::WorldObject::VertexShader,
worldProg =
renderer->createShader(GameShaders::WorldObject::VertexShader,
GameShaders::WorldObject::FragmentShader);
renderer->setUniformTexture(worldProg, "texture", 0);
renderer->setProgramBlockBinding(worldProg, "SceneData", 1);
renderer->setProgramBlockBinding(worldProg, "ObjectData", 2);
particleProg = renderer->createShader(
GameShaders::WorldObject::VertexShader,
particleProg =
renderer->createShader(GameShaders::WorldObject::VertexShader,
GameShaders::Particle::FragmentShader);
renderer->setUniformTexture(particleProg, "texture", 0);
renderer->setProgramBlockBinding(particleProg, "SceneData", 1);
renderer->setProgramBlockBinding(particleProg, "ObjectData", 2);
skyProg = renderer->createShader(
GameShaders::Sky::VertexShader,
skyProg = renderer->createShader(GameShaders::Sky::VertexShader,
GameShaders::Sky::FragmentShader);
renderer->setProgramBlockBinding(skyProg, "SceneData", 1);
postProg = renderer->createShader(
GameShaders::DefaultPostProcess::VertexShader,
postProg =
renderer->createShader(GameShaders::DefaultPostProcess::VertexShader,
GameShaders::DefaultPostProcess::FragmentShader);
glGenVertexArrays(1, &vao);
glGenTextures(1, &m_missingTexture);
glBindTexture(GL_TEXTURE_2D, m_missingTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, kMissingTextureBytes);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
kMissingTextureBytes);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -127,17 +118,21 @@ GameRenderer::GameRenderer(Logger* log, GameData* _data)
glGenTextures(2, fbTextures);
glBindTexture(GL_TEXTURE_2D, fbTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, fbTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, 128, 128, 0, GL_RED, GL_FLOAT, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, 128, 128, 0, GL_RED, GL_FLOAT,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbTextures[0], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, fbTextures[1], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
fbTextures[0], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
fbTextures[1], 0);
// Give water renderer the data texture
water.setDataTexture(1, fbTextures[1]);
@ -145,9 +140,8 @@ GameRenderer::GameRenderer(Logger* log, GameData* _data)
glGenRenderbuffers(1, fbRenderBuffers);
glBindRenderbuffer(GL_RENDERBUFFER, fbRenderBuffers[0]);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 128, 128);
glFramebufferRenderbuffer(
GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbRenderBuffers[0]
);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, fbRenderBuffers[0]);
// Create the skydome
@ -159,11 +153,12 @@ GameRenderer::GameRenderer(Logger* log, GameData* _data)
skydomeVerts.resize(rows * segments);
for (size_t r = 0, i = 0; r < rows; ++r) {
for (size_t s = 0; s < segments; ++s) {
skydomeVerts[i++].position = glm::vec3(
cos(2.f * glm::pi<float>() * s * S) * cos(glm::half_pi<float>() * r * R),
sin(2.f * glm::pi<float>() * s * S) * cos(glm::half_pi<float>() * r * R),
sin(glm::half_pi<float>() * r * R)
);
skydomeVerts[i++].position =
glm::vec3(cos(2.f * glm::pi<float>() * s * S) *
cos(glm::half_pi<float>() * r * R),
sin(2.f * glm::pi<float>() * s * S) *
cos(glm::half_pi<float>() * r * R),
sin(glm::half_pi<float>() * r * R));
}
}
skyGbuff.uploadVertices(skydomeVerts);
@ -184,7 +179,9 @@ GameRenderer::GameRenderer(Logger* log, GameData* _data)
}
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skydomeIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * skydomeIndBuff.size(), skydomeIndBuff.data(), GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(GLuint) * skydomeIndBuff.size(), skydomeIndBuff.data(),
GL_STATIC_DRAW);
glBindVertexArray(0);
@ -193,12 +190,10 @@ GameRenderer::GameRenderer(Logger* log, GameData* _data)
glGenVertexArrays(1, &debugVAO);
particleGeom.uploadVertices<ParticleVert>(
{
{ 0.5f, 0.5f, 1.f, 1.f, 1.f, 1.f, 1.f},
{{0.5f, 0.5f, 1.f, 1.f, 1.f, 1.f, 1.f},
{-0.5f, 0.5f, 0.f, 1.f, 1.f, 1.f, 1.f},
{0.5f, -0.5f, 1.f, 0.f, 1.f, 1.f, 1.f},
{-0.5f,-0.5f, 0.f, 0.f, 1.f, 1.f, 1.f}
});
{-0.5f, -0.5f, 0.f, 0.f, 1.f, 1.f, 1.f}});
particleDraw.addGeometry(&particleGeom);
particleDraw.setFaceType(GL_TRIANGLE_STRIP);
@ -206,7 +201,8 @@ GameRenderer::GameRenderer(Logger* log, GameData* _data)
ssRectDraw.addGeometry(&ssRectGeom);
ssRectDraw.setFaceType(GL_TRIANGLE_STRIP);
ssRectProgram = compileProgram(GameShaders::ScreenSpaceRect::VertexShader,
ssRectProgram =
compileProgram(GameShaders::ScreenSpaceRect::VertexShader,
GameShaders::ScreenSpaceRect::FragmentShader);
ssRectTexture = glGetUniformLocation(ssRectProgram, "texture");
@ -216,8 +212,7 @@ GameRenderer::GameRenderer(Logger* log, GameData* _data)
const static int cylsegments = 16;
std::vector<Model::GeometryVertex> cylverts;
for(int s = 0; s < cylsegments; ++s)
{
for (int s = 0; s < cylsegments; ++s) {
float theta = (2.f * glm::pi<float>() / cylsegments) * (s + 0);
float gamma = (2.f * glm::pi<float>() / cylsegments) * (s + 1);
glm::vec2 p0(glm::sin(theta), glm::cos(theta));
@ -226,31 +221,40 @@ GameRenderer::GameRenderer(Logger* log, GameData* _data)
p0 *= 0.5f;
p1 *= 0.5f;
cylverts.push_back({glm::vec3(p0, 2.f), glm::vec3(), glm::vec2(0.45f,0.6f), glm::u8vec4(255, 255, 255, 50)});
cylverts.push_back({glm::vec3(p0,-1.f), glm::vec3(), glm::vec2(0.45f,0.4f), glm::u8vec4(255, 255, 255, 150)});
cylverts.push_back({glm::vec3(p1, 2.f), glm::vec3(), glm::vec2(0.55f,0.6f), glm::u8vec4(255, 255, 255, 50)});
cylverts.push_back({glm::vec3(p0, 2.f), glm::vec3(),
glm::vec2(0.45f, 0.6f),
glm::u8vec4(255, 255, 255, 50)});
cylverts.push_back({glm::vec3(p0, -1.f), glm::vec3(),
glm::vec2(0.45f, 0.4f),
glm::u8vec4(255, 255, 255, 150)});
cylverts.push_back({glm::vec3(p1, 2.f), glm::vec3(),
glm::vec2(0.55f, 0.6f),
glm::u8vec4(255, 255, 255, 50)});
cylverts.push_back({glm::vec3(p0,-1.f), glm::vec3(), glm::vec2(0.45f,0.4f), glm::u8vec4(255, 255, 255, 150)});
cylverts.push_back({glm::vec3(p1,-1.f), glm::vec3(), glm::vec2(0.55f,0.4f), glm::u8vec4(255, 255, 255, 150)});
cylverts.push_back({glm::vec3(p1, 2.f), glm::vec3(), glm::vec2(0.55f,0.6f), glm::u8vec4(255, 255, 255, 50)});
cylverts.push_back({glm::vec3(p0, -1.f), glm::vec3(),
glm::vec2(0.45f, 0.4f),
glm::u8vec4(255, 255, 255, 150)});
cylverts.push_back({glm::vec3(p1, -1.f), glm::vec3(),
glm::vec2(0.55f, 0.4f),
glm::u8vec4(255, 255, 255, 150)});
cylverts.push_back({glm::vec3(p1, 2.f), glm::vec3(),
glm::vec2(0.55f, 0.6f),
glm::u8vec4(255, 255, 255, 50)});
}
cylinderGeometry.uploadVertices<Model::GeometryVertex>(cylverts);
cylinderBuffer.addGeometry(&cylinderGeometry);
cylinderBuffer.setFaceType(GL_TRIANGLES);
}
GameRenderer::~GameRenderer()
{
GameRenderer::~GameRenderer() {
glDeleteFramebuffers(1, &framebufferName);
}
float mix(uint8_t a, uint8_t b, float num)
{
float mix(uint8_t a, uint8_t b, float num) {
return a + (b - a) * num;
}
void GameRenderer::setupRender()
{
void GameRenderer::setupRender() {
// Set the viewport
const glm::ivec2& vp = getRenderer()->getViewport();
glViewport(0, 0, vp.x, vp.y);
@ -258,8 +262,8 @@ void GameRenderer::setupRender()
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
}
void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float alpha)
{
void GameRenderer::renderWorld(GameWorld* world, const ViewCamera& camera,
float alpha) {
_renderAlpha = alpha;
_renderWorld = world;
@ -273,7 +277,8 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
float tod = world->getHour() + world->getMinute() / 60.f;
// Requires a float 0-24
auto weatherID = static_cast<WeatherLoader::WeatherCondition>(world->state->basic.nextWeather * 24);
auto weatherID = static_cast<WeatherLoader::WeatherCondition>(
world->state->basic.nextWeather * 24);
auto weather = world->data->weatherLoader.getWeatherData(weatherID, tod);
glm::vec3 skyTop = weather.skyTopColor;
@ -283,9 +288,7 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
float theta = (tod / (60.f * 24.f) - 0.5f) * 2 * 3.14159265;
glm::vec3 sunDirection{
sin(theta),
0.0,
cos(theta),
sin(theta), 0.0, cos(theta),
};
sunDirection = glm::normalize(sunDirection);
@ -295,26 +298,23 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
auto view = _camera.getView();
auto proj = _camera.frustum.projection();
Renderer::SceneUniformData sceneParams {
proj,
Renderer::SceneUniformData sceneParams{proj,
view,
glm::vec4{ambient, 0.0f},
glm::vec4{dynamic, 0.0f},
glm::vec4(skyBottom, 1.f),
glm::vec4(camera.position, 0.f),
weather.fogStart,
_camera.frustum.far
};
_camera.frustum.far};
renderer->setSceneParameters(sceneParams);
renderer->clear(glm::vec4(skyBottom, 1.f));
_camera.frustum.update(proj * view);
if (cullOverride)
{
cullingCamera.frustum.update(
cullingCamera.frustum.projection() * cullingCamera.getView());
if (cullOverride) {
cullingCamera.frustum.update(cullingCamera.frustum.projection() *
cullingCamera.getView());
}
culled = 0;
@ -337,8 +337,7 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
ObjectRenderer objectRenderer(_renderWorld,
(cullOverride ? cullingCamera : _camera),
_renderAlpha,
getMissingTexture());
_renderAlpha, getMissingTexture());
// World Objects
for (auto object : world->allObjects) {
@ -369,12 +368,10 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
// Render arrows above anything that isn't radar only (or hidden)
ModelRef& arrowModel = world->data->models["arrow"];
if( arrowModel && arrowModel->resource )
{
if (arrowModel && arrowModel->resource) {
auto arrowTex = world->data->textures[{"copblue", ""}];
auto arrowFrame = arrowModel->resource->findFrame("arrow");
for( auto& blip : world->state->radarBlips )
{
for (auto& blip : world->state->radarBlips) {
auto dm = blip.second.display;
if (dm == BlipData::Hide || dm == BlipData::RadarOnly) {
continue;
@ -382,21 +379,18 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
glm::mat4 model;
if( blip.second.target > 0 )
{
if (blip.second.target > 0) {
auto object = world->getBlipTarget(blip.second);
if( object )
{
if (object) {
model = object->getTimeAdjustedTransform(_renderAlpha);
}
}
else
{
} 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::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));
@ -405,7 +399,8 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
dp.ambient = 1.f;
dp.colour = glm::u8vec4(255, 255, 255, 255);
auto geom = arrowModel->resource->geometries[arrowFrame->getGeometries()[0]];
auto geom = arrowModel->resource
->geometries[arrowFrame->getGeometries()[0]];
Model::SubGeometry& sg = geom->subgeom[0];
dp.start = sg.start;
@ -419,8 +414,7 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
// Draw goal indicators
glDepthMask(GL_FALSE);
renderer->useProgram(particleProg);
for(auto& i : world->getAreaIndicators())
{
for (auto& i : world->getAreaIndicators()) {
renderAreaIndicator(&i);
}
glDepthMask(GL_TRUE);
@ -457,13 +451,13 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
auto fc = world->state->fadeColour;
if ((fc.r + fc.g + fc.b) == 0 && world->state->currentSplash.size() > 0) {
auto splash = world->data->findTexture(world->state->currentSplash);
if ( splash )
{
if (splash) {
splashTexName = splash->getName();
}
}
if( (world->state->isCinematic || world->state->currentCutscene ) && splashTexName != 0 ) {
if ((world->state->isCinematic || world->state->currentCutscene) &&
splashTexName != 0) {
renderLetterbox();
}
@ -478,8 +472,7 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
if (splashTexName != 0) {
glBindTexture(GL_TEXTURE_2D, splashTexName);
fc = glm::u16vec3(0, 0, 0);
}
else {
} else {
glBindTexture(GL_TEXTURE_2D, 0);
}
@ -498,7 +491,8 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
if( (world->state->isCinematic || world->state->currentCutscene ) && splashTexName == 0 ) {
if ((world->state->isCinematic || world->state->currentCutscene) &&
splashTexName == 0) {
renderLetterbox();
}
@ -510,12 +504,12 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float
glBindVertexArray(0);
}
void GameRenderer::renderPostProcess()
{
void GameRenderer::renderPostProcess() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glStencilMask(0xFF);
glClearStencil(0x00);
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);
renderer->useProgram(postProg);
@ -527,10 +521,10 @@ void GameRenderer::renderPostProcess()
renderer->drawArrays(glm::mat4(), &ssRectDraw, wdp);
}
void GameRenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelMatrix, float opacity, GameObject* object)
{
for(size_t sg = 0; sg < model->geometries[g]->subgeom.size(); ++sg)
{
void GameRenderer::renderGeometry(Model* model, size_t g,
const glm::mat4& modelMatrix, float opacity,
GameObject* object) {
for (size_t sg = 0; sg < model->geometries[g]->subgeom.size(); ++sg) {
Model::SubGeometry& subgeom = model->geometries[g]->subgeom[sg];
Renderer::DrawParameters dp;
@ -541,36 +535,38 @@ void GameRenderer::renderGeometry(Model* model, size_t g, const glm::mat4& model
dp.textures = {0};
if (model->geometries[g]->materials.size() > subgeom.material) {
Model::Material& mat = model->geometries[g]->materials[subgeom.material];
Model::Material& mat =
model->geometries[g]->materials[subgeom.material];
if (mat.textures.size() > 0) {
auto tex = mat.textures[0].texture;
if( ! tex )
{
if (!tex) {
auto& tC = mat.textures[0].name;
auto& tA = mat.textures[0].alphaName;
tex = data->findTexture(tC, tA);
if( ! tex )
{
//logger->warning("Renderer", "Missing texture: " + tC + " " + tA);
if (!tex) {
// logger->warning("Renderer", "Missing texture: " + tC
// + " " + tA);
}
mat.textures[0].texture = tex;
}
if( tex )
{
if (tex) {
dp.textures = {tex->getName()};
}
}
if( (model->geometries[g]->flags & RW::BSGeometry::ModuleMaterialColor) == RW::BSGeometry::ModuleMaterialColor) {
if ((model->geometries[g]->flags &
RW::BSGeometry::ModuleMaterialColor) ==
RW::BSGeometry::ModuleMaterialColor) {
dp.colour = mat.colour;
if (object && object->type() == GameObject::Vehicle) {
auto vehicle = static_cast<VehicleObject*>(object);
if( dp.colour.r == 60 && dp.colour.g == 255 && dp.colour.b == 0 ) {
if (dp.colour.r == 60 && dp.colour.g == 255 &&
dp.colour.b == 0) {
dp.colour = glm::u8vec4(vehicle->colourPrimary, 255);
}
else if( dp.colour.r == 255 && dp.colour.g == 0 && dp.colour.b == 175 ) {
} else if (dp.colour.r == 255 && dp.colour.g == 0 &&
dp.colour.b == 175) {
dp.colour = glm::u8vec4(vehicle->colourSecondary, 255);
}
}
@ -587,11 +583,11 @@ void GameRenderer::renderGeometry(Model* model, size_t g, const glm::mat4& model
}
#define GOAL_RINGS 3
void GameRenderer::renderAreaIndicator(const AreaIndicatorInfo* info)
{
void GameRenderer::renderAreaIndicator(const AreaIndicatorInfo* info) {
glm::mat4 m(1.f);
m = glm::translate(m, info->position);
glm::vec3 scale = info->radius + 0.15f * glm::sin(_renderWorld->getGameTime() * 5.f);
glm::vec3 scale =
info->radius + 0.15f * glm::sin(_renderWorld->getGameTime() * 5.f);
Renderer::DrawParameters dp;
dp.textures = {data->findTexture("cloud1")->getName()};
@ -601,30 +597,31 @@ void GameRenderer::renderAreaIndicator(const AreaIndicatorInfo* info)
dp.count = cylinderGeometry.getCount();
dp.diffuse = 1.f;
for(int i = 0; i < GOAL_RINGS; i++)
{
for (int i = 0; i < GOAL_RINGS; i++) {
glm::mat4 mt = m;
glm::vec3 final = scale * glm::pow(0.9f, i + 1.0f);
mt = glm::scale(mt, glm::vec3(final.x, final.y, 1.0f + i * 0.1f));
int reverse = (i % 2 ? 1 : -1);
mt = glm::rotate(mt, reverse * _renderWorld->getGameTime() * 0.5f, glm::vec3(0.f, 0.f, 1.f) );
mt = glm::rotate(mt, reverse * _renderWorld->getGameTime() * 0.5f,
glm::vec3(0.f, 0.f, 1.f));
renderer->drawArrays(mt, &cylinderBuffer, dp);
}
}
void GameRenderer::renderEffects(GameWorld* world)
{
void GameRenderer::renderEffects(GameWorld* world) {
renderer->useProgram(particleProg);
auto cpos = _camera.position;
auto cfwd = glm::normalize(glm::inverse(_camera.rotation) * glm::vec3(0.f, 1.f, 0.f));
auto cfwd = glm::normalize(glm::inverse(_camera.rotation) *
glm::vec3(0.f, 1.f, 0.f));
auto& effects = world->effects;
std::sort(effects.begin(), effects.end(),
[&](const VisualFX* a, const VisualFX* b) {
return glm::distance( a->getPosition(), cpos ) > glm::distance( b->getPosition(), cpos );
return glm::distance(a->getPosition(), cpos) >
glm::distance(b->getPosition(), cpos);
});
for (VisualFX* fx : effects) {
@ -643,8 +640,7 @@ void GameRenderer::renderEffects(GameWorld* world)
if (particle.orientation == VisualFX::ParticleData::UpCamera) {
ptc = glm::normalize(amp - (glm::dot(amp, cfwd)) * cfwd);
}
else if( particle.orientation == VisualFX::ParticleData::Camera ) {
} else if (particle.orientation == VisualFX::ParticleData::Camera) {
ptc = amp;
}
@ -679,13 +675,11 @@ void GameRenderer::renderEffects(GameWorld* world)
}
}
void GameRenderer::drawOnScreenText()
{
void GameRenderer::drawOnScreenText() {
/// @ TODO
}
void GameRenderer::drawTexture(TextureData* texture, glm::vec4 extents)
{
void GameRenderer::drawTexture(TextureData* texture, glm::vec4 extents) {
glUseProgram(ssRectProgram);
// Move into NDC
@ -715,8 +709,7 @@ void GameRenderer::drawTexture(TextureData* texture, glm::vec4 extents)
renderer->invalidate();
}
void GameRenderer::drawColour(const glm::vec4& colour, glm::vec4 extents)
{
void GameRenderer::drawColour(const glm::vec4& colour, glm::vec4 extents) {
glUseProgram(ssRectProgram);
// Move into NDC
@ -746,8 +739,9 @@ void GameRenderer::drawColour(const glm::vec4& colour, glm::vec4 extents)
renderer->invalidate();
}
bool GameRenderer::renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix, GameObject* object, float opacity, bool queueTransparent)
{
bool GameRenderer::renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix,
GameObject* object, float opacity,
bool queueTransparent) {
auto localmatrix = matrix;
bool vis = true;
@ -756,15 +750,13 @@ bool GameRenderer::renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix,
localmatrix *= object->skeleton->getMatrix(f);
vis = object->skeleton->getData(f->getIndex()).enabled;
}
else {
} else {
localmatrix *= f->getTransform();
}
if (vis) {
for (size_t g : f->getGeometries()) {
if( !object || !object->animator )
{
if (!object || !object->animator) {
RW::BSGeometryBounds& bounds = m->geometries[g]->geometryBounds;
glm::vec3 boundpos = bounds.center + glm::vec3(localmatrix[3]);
@ -784,13 +776,13 @@ bool GameRenderer::renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix,
return true;
}
void GameRenderer::renderModel(Model* model, const glm::mat4& modelMatrix, GameObject* object)
{
renderFrame(model, model->frames[model->rootFrameIdx], modelMatrix, object, 1.f);
void GameRenderer::renderModel(Model* model, const glm::mat4& modelMatrix,
GameObject* object) {
renderFrame(model, model->frames[model->rootFrameIdx], modelMatrix, object,
1.f);
}
void GameRenderer::renderPaths()
{
void GameRenderer::renderPaths() {
/*glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, debugTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
@ -819,8 +811,10 @@ void GameRenderer::renderPaths()
}
}
else {
carlines.push_back(start->position-glm::vec3(start->size / 2.f, 0.f, 0.f));
carlines.push_back(start->position+glm::vec3(start->size / 2.f, 0.f, 0.f));
carlines.push_back(start->position-glm::vec3(start->size / 2.f, 0.f,
0.f));
carlines.push_back(start->position+glm::vec3(start->size / 2.f, 0.f,
0.f));
}
for( size_t c = 0; c < start->connections.size(); ++c ) {
@ -842,7 +836,8 @@ void GameRenderer::renderPaths()
glEnableVertexAttribArray(posAttrib);
glBindBuffer(GL_ARRAY_BUFFER, debugVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * carlines.size(), &(carlines[0]), GL_STREAM_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * carlines.size(),
&(carlines[0]), GL_STREAM_DRAW);
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
float img[] = {1.f, 0.f, 0.f};
@ -853,7 +848,8 @@ void GameRenderer::renderPaths()
glDrawArrays(GL_LINES, 0, carlines.size());
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * pedlines.size(), &(pedlines[0]), GL_STREAM_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * pedlines.size(),
&(pedlines[0]), GL_STREAM_DRAW);
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
float img2[] = {0.f, 1.f, 0.f};
@ -869,8 +865,7 @@ void GameRenderer::renderPaths()
glBindVertexArray( 0 );*/
}
void GameRenderer::renderLetterbox()
{
void GameRenderer::renderLetterbox() {
glUseProgram(ssRectProgram);
const float cinematicExperienceSize = 0.15f;
glUniform2f(ssRectOffset, 0.f, -1.f * (1.f - cinematicExperienceSize));
@ -889,17 +884,17 @@ void GameRenderer::renderLetterbox()
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
void GameRenderer::setViewport(int w, int h)
{
void GameRenderer::setViewport(int w, int h) {
auto& lastViewport = renderer->getViewport();
if( lastViewport.x != w || lastViewport.y != h)
{
if (lastViewport.x != w || lastViewport.y != h) {
renderer->setViewport({w, h});
glBindTexture(GL_TEXTURE_2D, fbTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB,
GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, fbTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, w, h, 0, GL_RED, GL_FLOAT, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, w, h, 0, GL_RED, GL_FLOAT,
NULL);
glBindRenderbuffer(GL_RENDERBUFFER, fbRenderBuffers[0]);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h);

View File

@ -42,8 +42,7 @@ class Renderer;
* Rendering of object types is handled by drawWorld, calling the respective
* render function for each object.
*/
class GameRenderer
{
class GameRenderer {
/** Game data to use for rendering */
GameData* data;
@ -69,10 +68,13 @@ class GameRenderer
* @param f
* @param matrix
* @param object
* @param queueTransparent abort the draw if the frame contains transparent materials
* @param queueTransparent abort the draw if the frame contains transparent
* materials
* @return True if the frame was drawn, false if it should be queued
*/
bool renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix, GameObject* object, float opacity, bool queueTransparent = true);
bool renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix,
GameObject* object, float opacity,
bool queueTransparent = true);
// Temporary variables used during rendering
float _renderAlpha;
@ -95,7 +97,6 @@ class GameRenderer
GLuint m_missingTexture;
public:
GameRenderer(Logger* log, GameData* data);
~GameRenderer();
@ -119,9 +120,13 @@ public:
DrawBuffer cylinderBuffer;
GeometryBuffer cylinderGeometry;
GameData* getData() const { return data; }
GameData* getData() const {
return data;
}
GLuint getMissingTexture() const { return m_missingTexture; }
GLuint getMissingTexture() const {
return m_missingTexture;
}
/**
* Renders the world using the parameters of the passed Camera.
@ -153,9 +158,11 @@ public:
/**
* Renders a model (who'd have thought)
*/
void renderModel(Model*, const glm::mat4& modelMatrix, GameObject* = nullptr);
void renderModel(Model*, const glm::mat4& modelMatrix,
GameObject* = nullptr);
void renderGeometry(Model*, size_t geom, const glm::mat4& modelMatrix, float opacity, GameObject* = nullptr);
void renderGeometry(Model*, size_t geom, const glm::mat4& modelMatrix,
float opacity, GameObject* = nullptr);
/** Renders the area indicator */
void renderAreaIndicator(const AreaIndicatorInfo* info);
@ -169,15 +176,13 @@ public:
void setupRender();
void renderPostProcess();
Renderer* getRenderer()
{
Renderer* getRenderer() {
return renderer;
}
void setViewport(int w, int h);
void setCullOverride(bool override, const ViewCamera& cullCamera)
{
void setCullOverride(bool override, const ViewCamera& cullCamera) {
cullingCamera = cullCamera;
cullOverride = override;
}

View File

@ -268,7 +268,6 @@ void main()
outColour = c * tint;
})";
const char* ScreenSpaceRect::VertexShader = R"(
#version 330
@ -325,5 +324,4 @@ void main()
vec4 c = texture(colour, TexCoords);
outColour = c;
})";
}

View File

@ -49,7 +49,6 @@ struct ScreenSpaceRect {
};
SHADER_VF(DefaultPostProcess);
}
#endif

View File

@ -1,10 +1,10 @@
#include <render/MapRenderer.hpp>
#include <render/GameShaders.hpp>
#include <engine/GameWorld.hpp>
#include <ai/PlayerController.hpp>
#include <engine/GameData.hpp>
#include <engine/GameState.hpp>
#include <ai/PlayerController.hpp>
#include <engine/GameWorld.hpp>
#include <objects/CharacterObject.hpp>
#include <render/GameShaders.hpp>
#include <render/MapRenderer.hpp>
const char* MapVertexShader = R"(
#version 330
@ -37,43 +37,32 @@ void main()
outColour = vec4(colour.rgb + c.rgb, colour.a * c.a);
})";
MapRenderer::MapRenderer(Renderer* renderer, GameData* _data)
: data(_data), renderer(renderer)
{
rectGeom.uploadVertices<VertexP2>({
{-.5f, -.5f},
{ .5f, -.5f},
{ .5f, .5f},
{-.5f, .5f}
});
: data(_data), renderer(renderer) {
rectGeom.uploadVertices<VertexP2>(
{{-.5f, -.5f}, {.5f, -.5f}, {.5f, .5f}, {-.5f, .5f}});
rect.addGeometry(&rectGeom);
rect.setFaceType(GL_TRIANGLE_FAN);
std::vector<VertexP2> circleVerts;
circleVerts.push_back({0.f, 0.f});
for (int v = 0; v < 181; ++v) {
circleVerts.push_back({
0.5f * glm::cos(2*(v/180.f)*glm::pi<float>()),
0.5f * glm::sin(2*(v/180.f)*glm::pi<float>())
});
circleVerts.push_back(
{0.5f * glm::cos(2 * (v / 180.f) * glm::pi<float>()),
0.5f * glm::sin(2 * (v / 180.f) * glm::pi<float>())});
}
circleGeom.uploadVertices(circleVerts);
circle.addGeometry(&circleGeom);
circle.setFaceType(GL_TRIANGLE_FAN);
rectProg = renderer->createShader(
MapVertexShader,
MapFragmentShader
);
rectProg = renderer->createShader(MapVertexShader, MapFragmentShader);
renderer->setUniform(rectProg, "colour", glm::vec4(1.f));
}
#define GAME_MAP_SIZE 4000
void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
{
void MapRenderer::draw(GameWorld* world, const MapInfo& mi) {
renderer->pushDebugGroup("Map");
renderer->useProgram(rectProg);
@ -92,8 +81,7 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
view = glm::translate(view, glm::vec3(mi.screenPosition, 0.f));
if (mi.clipToSize)
{
if (mi.clipToSize) {
glBindVertexArray(circle.getVAOName());
glBindTexture(GL_TEXTURE_2D, 0);
glm::mat4 circleView = glm::scale(view, glm::vec3(mi.screenSize));
@ -110,7 +98,8 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
view = glm::scale(view, glm::vec3(worldScale));
view = glm::rotate(view, mi.rotation, glm::vec3(0.f, 0.f, 1.f));
view = glm::translate(view, glm::vec3(glm::vec2(-1.f, 1.f) * mi.worldCenter, 0.f));
view = glm::translate(
view, glm::vec3(glm::vec2(-1.f, 1.f) * mi.worldCenter, 0.f));
renderer->setUniform(rectProg, "view", view);
glBindVertexArray(rect.getVAOName());
@ -123,8 +112,7 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
int initX = -(mapBlockLine / 2);
int initY = -(mapBlockLine / 2);
for( int m = 0; m < MAP_BLOCK_SIZE; ++m )
{
for (int m = 0; m < MAP_BLOCK_SIZE; ++m) {
std::string num = (m < 10 ? "0" : "");
std::string name = "radar" + num + std::to_string(m);
auto texture = world->data->textures[{name, ""}];
@ -160,28 +148,23 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
renderer->setUniform(rectProg, "model", model);
glBindTexture(GL_TEXTURE_2D, radarDisc->getName());
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE,
GL_ZERO);
}
// Draw the player blip
auto player = world->pedestrianPool.find(world->state->playerObject);
if( player )
{
if (player) {
glm::vec2 plyblip(player->getPosition());
float hdg = glm::roll(player->getRotation());
drawBlip(
plyblip, view, mi,
"radar_centre", glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), 18.0f, 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", glm::vec4(0.0f, 0.0f, 0.0f, 1.0f), 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)
{
for (auto& radarBlip : world->state->radarBlips) {
const auto& blip = radarBlip.second;
auto dm = blip.display;
@ -190,20 +173,20 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
}
glm::vec2 blippos(blip.coord);
if( blip.target > 0 )
{
if (blip.target > 0) {
GameObject* object = world->getBlipTarget(blip);
if( object )
{
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);
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!)
// Colours from http://www.gtamodding.com/wiki/0165 (colors not
// specific to that opcode!)
uint32_t rgbaValue;
switch (blip.colour) {
case 0: // RED
@ -232,8 +215,7 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
break;
}
glm::vec4 colour(
(rgbaValue >> 24) / 255.0f,
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
@ -252,19 +234,21 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi)
renderer->popDebugGroup();
}
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)
{
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)
{
if (mi.clipToSize) {
float maxDist = mi.worldSize / 2.f;
float centerDist = glm::distance(coord, mi.worldCenter);
if (centerDist > maxDist) {
adjustedCoord = mi.worldCenter + ((coord - mi.worldCenter)/centerDist)*maxDist;
adjustedCoord = mi.worldCenter +
((coord - mi.worldCenter) / centerDist) * maxDist;
}
}
glm::vec3 viewPos(view * glm::vec4(glm::vec2(1.f,-1.f)*adjustedCoord, 0.f, 1.f));
glm::vec3 viewPos(
view * glm::vec4(glm::vec2(1.f, -1.f) * adjustedCoord, 0.f, 1.f));
glm::mat4 model;
model = glm::translate(model, viewPos);
model = glm::scale(model, glm::vec3(size));
@ -272,8 +256,7 @@ void MapRenderer::prepareBlip(const glm::vec2& coord, const glm::mat4& view, con
renderer->setUniform(rectProg, "model", model);
GLuint tex = 0;
if ( !texture.empty() )
{
if (!texture.empty()) {
auto sprite = data->findTexture(texture);
tex = sprite->getName();
}
@ -284,13 +267,16 @@ void MapRenderer::prepareBlip(const glm::vec2& coord, const glm::mat4& view, con
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) {
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) {
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));

View File

@ -9,12 +9,9 @@ class GameWorld;
/**
* Utility class for rendering the world map, in the menu and radar.
*/
class MapRenderer
{
class MapRenderer {
public:
struct MapInfo
{
struct MapInfo {
/// World coordinate center
glm::vec2 worldCenter;
/// World units to fit on the map
@ -45,7 +42,12 @@ private:
Renderer::ShaderProgram* rectProg;
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);
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);
};

View File

@ -1,19 +1,19 @@
#include <render/ObjectRenderer.hpp>
#include <data/Skeleton.hpp>
#include <data/CutsceneData.hpp>
#include <data/Model.hpp>
#include <data/Skeleton.hpp>
#include <engine/GameData.hpp>
#include <engine/GameState.hpp>
#include <data/CutsceneData.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <render/ObjectRenderer.hpp>
// Objects that we know how to turn into renderlist entries
#include <objects/InstanceObject.hpp>
#include <objects/VehicleObject.hpp>
#include <objects/CharacterObject.hpp>
#include <objects/ProjectileObject.hpp>
#include <objects/PickupObject.hpp>
#include <objects/CutsceneObject.hpp>
#include <items/InventoryItem.hpp>
#include <objects/CharacterObject.hpp>
#include <objects/CutsceneObject.hpp>
#include <objects/InstanceObject.hpp>
#include <objects/PickupObject.hpp>
#include <objects/ProjectileObject.hpp>
#include <objects/VehicleObject.hpp>
#ifdef RW_WINDOWS
#include <rw_mingw.hpp>
#endif
@ -25,22 +25,19 @@ constexpr float kVehicleDrawDistanceFactor = kDrawDistanceFactor;
constexpr float kPedestrianDrawDistanceFactor = kDrawDistanceFactor;
#endif
RenderKey createKey(bool transparent, float normalizedDepth, Renderer::Textures& textures)
{
return ((transparent?0x1:0x0) << 31)
| uint32_t(0x7FFFFF * (transparent? 1.f - normalizedDepth : normalizedDepth)) << 8
| uint8_t(0xFF & (textures.size() > 0 ? textures[0] : 0)) << 0;
RenderKey createKey(bool transparent, float normalizedDepth,
Renderer::Textures& textures) {
return ((transparent ? 0x1 : 0x0) << 31) |
uint32_t(0x7FFFFF *
(transparent ? 1.f - normalizedDepth : normalizedDepth))
<< 8 |
uint8_t(0xFF & (textures.size() > 0 ? textures[0] : 0)) << 0;
}
void ObjectRenderer::renderGeometry(Model* model,
size_t g,
const glm::mat4& modelMatrix,
float opacity,
GameObject* object,
RenderList& outList)
{
for(size_t sg = 0; sg < model->geometries[g]->subgeom.size(); ++sg)
{
void ObjectRenderer::renderGeometry(Model* model, size_t g,
const glm::mat4& modelMatrix, float opacity,
GameObject* object, RenderList& outList) {
for (size_t sg = 0; sg < model->geometries[g]->subgeom.size(); ++sg) {
Model::SubGeometry& subgeom = model->geometries[g]->subgeom[sg];
bool isTransparent = false;
@ -55,28 +52,28 @@ void ObjectRenderer::renderGeometry(Model* model,
if (object && object->type() == GameObject::Instance) {
auto instance = static_cast<InstanceObject*>(object);
dp.depthWrite = !(instance->object->flags & ObjectData::NO_ZBUFFER_WRITE);
dp.depthWrite =
!(instance->object->flags & ObjectData::NO_ZBUFFER_WRITE);
}
if (model->geometries[g]->materials.size() > subgeom.material) {
Model::Material& mat = model->geometries[g]->materials[subgeom.material];
Model::Material& mat =
model->geometries[g]->materials[subgeom.material];
if (mat.textures.size() > 0) {
auto tex = mat.textures[0].texture;
if( ! tex )
{
if (!tex) {
auto& tC = mat.textures[0].name;
auto& tA = mat.textures[0].alphaName;
tex = m_world->data->findTexture(tC, tA);
if( ! tex )
{
//logger->warning("Renderer", "Missing texture: " + tC + " " + tA);
if (!tex) {
// logger->warning("Renderer", "Missing texture: " + tC
// + " " + tA);
dp.textures = {m_errorTexture};
}
mat.textures[0].texture = tex;
}
if( tex )
{
if (tex) {
if (tex->isTransparent()) {
isTransparent = true;
}
@ -84,15 +81,18 @@ void ObjectRenderer::renderGeometry(Model* model,
}
}
if( (model->geometries[g]->flags & RW::BSGeometry::ModuleMaterialColor) == RW::BSGeometry::ModuleMaterialColor) {
if ((model->geometries[g]->flags &
RW::BSGeometry::ModuleMaterialColor) ==
RW::BSGeometry::ModuleMaterialColor) {
dp.colour = mat.colour;
if (object && object->type() == GameObject::Vehicle) {
auto vehicle = static_cast<VehicleObject*>(object);
if( dp.colour.r == 60 && dp.colour.g == 255 && dp.colour.b == 0 ) {
if (dp.colour.r == 60 && dp.colour.g == 255 &&
dp.colour.b == 0) {
dp.colour = glm::u8vec4(vehicle->colourPrimary, 255);
}
else if( dp.colour.r == 255 && dp.colour.g == 0 && dp.colour.b == 175 ) {
} else if (dp.colour.r == 255 && dp.colour.g == 0 &&
dp.colour.b == 175) {
dp.colour = glm::u8vec4(vehicle->colourSecondary, 255);
}
}
@ -112,22 +112,16 @@ void ObjectRenderer::renderGeometry(Model* model,
glm::vec3 position(modelMatrix[3]);
float distance = glm::length(m_camera.position - position);
float depth = (distance - m_camera.frustum.near) / (m_camera.frustum.far - m_camera.frustum.near);
float depth = (distance - m_camera.frustum.near) /
(m_camera.frustum.far - m_camera.frustum.near);
outList.emplace_back(
createKey(isTransparent, depth * depth, dp.textures),
modelMatrix,
&model->geometries[g]->dbuff,
dp
);
createKey(isTransparent, depth * depth, dp.textures), modelMatrix,
&model->geometries[g]->dbuff, dp);
}
}
bool ObjectRenderer::renderFrame(Model* m,
ModelFrame* f,
const glm::mat4& matrix,
GameObject* object,
float opacity,
RenderList& outList)
{
bool ObjectRenderer::renderFrame(Model* m, ModelFrame* f,
const glm::mat4& matrix, GameObject* object,
float opacity, RenderList& outList) {
auto localmatrix = matrix;
bool vis = true;
@ -136,15 +130,13 @@ bool ObjectRenderer::renderFrame(Model* m,
localmatrix *= object->skeleton->getMatrix(f);
vis = object->skeleton->getData(f->getIndex()).enabled;
}
else {
} else {
localmatrix *= f->getTransform();
}
if (vis) {
for (size_t g : f->getGeometries()) {
if( !object || !object->animator )
{
if (!object || !object->animator) {
RW::BSGeometryBounds& bounds = m->geometries[g]->geometryBounds;
glm::vec3 boundpos = bounds.center + glm::vec3(localmatrix[3]);
@ -165,32 +157,27 @@ bool ObjectRenderer::renderFrame(Model* m,
void ObjectRenderer::renderItem(InventoryItem* item,
const glm::mat4& modelMatrix,
RenderList& outList)
{
RenderList& outList) {
// srhand
if (item->getModelID() == -1) {
return; // No model for this item
}
std::shared_ptr<ObjectData> odata = m_world->data->findObjectType<ObjectData>(item->getModelID());
std::shared_ptr<ObjectData> odata =
m_world->data->findObjectType<ObjectData>(item->getModelID());
auto weapons = m_world->data->models["weapons"];
if (weapons && weapons->resource) {
auto itemModel = weapons->resource->findFrame(odata->modelName + "_l0");
auto matrix = glm::inverse(itemModel->getTransform());
if (itemModel) {
renderFrame(weapons->resource,
itemModel,
modelMatrix * matrix,
nullptr,
1.f,
outList);
renderFrame(weapons->resource, itemModel, modelMatrix * matrix,
nullptr, 1.f, outList);
}
}
}
void ObjectRenderer::renderInstance(InstanceObject* instance,
RenderList& outList)
{
RenderList& outList) {
if (!instance->model->resource) {
return;
}
@ -200,28 +187,29 @@ void ObjectRenderer::renderInstance(InstanceObject *instance,
return;
}
// Handles times provided by TOBJ data
const auto currentHour = m_world->getHour();
if (instance->object->timeOff < instance->object->timeOn)
{
if ( currentHour >= instance->object->timeOff && currentHour < instance->object->timeOn )
if (instance->object->timeOff < instance->object->timeOn) {
if (currentHour >= instance->object->timeOff &&
currentHour < instance->object->timeOn)
return;
} else {
if ( currentHour >= instance->object->timeOff || currentHour < instance->object->timeOn )
if (currentHour >= instance->object->timeOff ||
currentHour < instance->object->timeOn)
return;
}
auto matrixModel = instance->getTimeAdjustedTransform(m_renderAlpha);
float mindist = glm::length(instance->getPosition()-m_camera.position)
- instance->model->resource->getBoundingRadius();
float mindist = glm::length(instance->getPosition() - m_camera.position) -
instance->model->resource->getBoundingRadius();
mindist *= 1.f / kDrawDistanceFactor;
Model* model = nullptr;
ModelFrame* frame = nullptr;
// These are used to gracefully fade out things that are just out of view distance.
// These are used to gracefully fade out things that are just out of view
// distance.
Model* fadingModel = nullptr;
ModelFrame* fadingFrame = nullptr;
auto fadingMatrix = matrixModel;
@ -238,20 +226,18 @@ void ObjectRenderer::renderInstance(InstanceObject *instance,
// Is the closest point greater than the *LOD* draw distance
float LODrange = instance->LODinstance->object->drawDistance[0];
if (mindist > LODrange) {
}
else if (instance->LODinstance->model->resource) {
} else if (instance->LODinstance->model->resource) {
// The model matrix needs to be for the LOD instead
matrixModel = instance->LODinstance->getTimeAdjustedTransform(m_renderAlpha);
matrixModel =
instance->LODinstance->getTimeAdjustedTransform(
m_renderAlpha);
// If the object is only just out of range, keep
// rendering it and screen-door the LOD.
if (overlap < fadeRange)
{
if (overlap < fadeRange) {
model = instance->LODinstance->model->resource;
fadingModel = instance->model->resource;
opacity = 1.f - (overlap / fadeRange);
}
else
{
} else {
model = instance->LODinstance->model->resource;
}
}
@ -266,8 +252,7 @@ void ObjectRenderer::renderInstance(InstanceObject *instance,
else if (!instance->object->LOD) {
model = instance->model->resource;
}
}
else {
} else {
auto root = instance->model->resource->frames[0];
auto objectModel = instance->model->resource;
fadingFrame = nullptr;
@ -275,17 +260,14 @@ void ObjectRenderer::renderInstance(InstanceObject *instance,
matrixModel *= root->getTransform();
for (int i = 0; i < instance->object->numClumps-1; ++i)
{
for (int i = 0; i < instance->object->numClumps - 1; ++i) {
auto ind = (instance->object->numClumps - 1) - i;
float lodDistance = instance->object->drawDistance[i];
if (mindist > lodDistance) {
fadingFrame = root->getChildren()[ind];
fadingModel = objectModel;
opacity = 1.f - ((mindist - lodDistance) / fadeRange);
}
else
{
} else {
model = objectModel;
frame = root->getChildren()[ind];
}
@ -294,49 +276,39 @@ void ObjectRenderer::renderInstance(InstanceObject *instance,
if (model) {
frame = frame ? frame : model->frames[0];
renderFrame(model,
frame,
matrixModel * glm::inverse(frame->getTransform()),
instance,
1.f,
outList);
renderFrame(model, frame,
matrixModel * glm::inverse(frame->getTransform()), instance,
1.f, outList);
}
if (fadingModel) {
if (opacity >= 0.01f) {
fadingFrame = fadingFrame ? fadingFrame : fadingModel->frames[0];
renderFrame(fadingModel,
fadingFrame,
renderFrame(
fadingModel, fadingFrame,
fadingMatrix * glm::inverse(fadingFrame->getTransform()),
instance,
opacity,
outList);
instance, opacity, outList);
}
}
}
void ObjectRenderer::renderCharacter(CharacterObject* pedestrian,
RenderList& outList)
{
RenderList& outList) {
glm::mat4 matrixModel;
if (pedestrian->getCurrentVehicle())
{
if (pedestrian->getCurrentVehicle()) {
auto vehicle = pedestrian->getCurrentVehicle();
auto seat = pedestrian->getCurrentSeat();
matrixModel = vehicle->getTimeAdjustedTransform(m_renderAlpha);
if (pedestrian->isEnteringOrExitingVehicle())
{
matrixModel = glm::translate(matrixModel, vehicle->getSeatEntryPosition(seat));
}
else
{
if (pedestrian->isEnteringOrExitingVehicle()) {
matrixModel = glm::translate(matrixModel,
vehicle->getSeatEntryPosition(seat));
} else {
if (seat < vehicle->info->seats.size()) {
matrixModel = glm::translate(matrixModel, vehicle->info->seats[seat].offset);
matrixModel = glm::translate(matrixModel,
vehicle->info->seats[seat].offset);
}
}
}
else
{
} else {
matrixModel = pedestrian->getTimeAdjustedTransform(m_renderAlpha);
}
@ -344,37 +316,29 @@ void ObjectRenderer::renderCharacter(CharacterObject *pedestrian,
auto root = pedestrian->model->resource->frames[0];
renderFrame(pedestrian->model->resource,
root->getChildren()[0],
matrixModel,
pedestrian,
1.f,
outList);
renderFrame(pedestrian->model->resource, root->getChildren()[0],
matrixModel, pedestrian, 1.f, outList);
if (pedestrian->getActiveItem()) {
auto handFrame = pedestrian->model->resource->findFrame("srhand");
glm::mat4 localMatrix;
if (handFrame) {
while (handFrame->getParent()) {
localMatrix = pedestrian->skeleton->getMatrix(handFrame->getIndex()) * localMatrix;
localMatrix =
pedestrian->skeleton->getMatrix(handFrame->getIndex()) *
localMatrix;
handFrame = handFrame->getParent();
}
}
renderItem(pedestrian->getActiveItem(),
matrixModel * localMatrix,
renderItem(pedestrian->getActiveItem(), matrixModel * localMatrix,
outList);
}
}
void ObjectRenderer::renderWheel(
VehicleObject* vehicle,
Model* model,
void ObjectRenderer::renderWheel(VehicleObject* vehicle, Model* model,
const glm::mat4& matrix,
const std::string& name,
RenderList& outList)
{
for (const ModelFrame* f : model->frames)
{
const std::string& name, RenderList& outList) {
for (const ModelFrame* f : model->frames) {
const std::string& fname = f->getName();
if (fname != name) {
continue;
@ -384,7 +348,8 @@ void ObjectRenderer::renderWheel(
for (auto& g : firstLod->getGeometries()) {
RW::BSGeometryBounds& bounds = model->geometries[g]->geometryBounds;
if(! m_camera.frustum.intersects(bounds.center + glm::vec3(matrix[3]), bounds.radius)) {
if (!m_camera.frustum.intersects(
bounds.center + glm::vec3(matrix[3]), bounds.radius)) {
continue;
}
@ -395,8 +360,7 @@ void ObjectRenderer::renderWheel(
}
void ObjectRenderer::renderVehicle(VehicleObject* vehicle,
RenderList& outList)
{
RenderList& outList) {
RW_CHECK(vehicle->model, "Vehicle model is null");
if (!vehicle->model) {
@ -405,23 +369,21 @@ void ObjectRenderer::renderVehicle(VehicleObject *vehicle,
glm::mat4 matrixModel = vehicle->getTimeAdjustedTransform(m_renderAlpha);
renderFrame(vehicle->model->resource,
vehicle->model->resource->frames[0],
matrixModel,
vehicle,
1.f,
outList);
renderFrame(vehicle->model->resource, vehicle->model->resource->frames[0],
matrixModel, vehicle, 1.f, outList);
// Draw wheels n' stuff
for (size_t w = 0; w < vehicle->info->wheels.size(); ++w) {
auto woi = m_world->data->findObjectType<ObjectData>(vehicle->vehicle->wheelModelID);
auto woi = m_world->data->findObjectType<ObjectData>(
vehicle->vehicle->wheelModelID);
if (woi) {
Model* wheelModel = m_world->data->models["wheels"]->resource;
auto& wi = vehicle->physVehicle->getWheelInfo(w);
if (wheelModel) {
// Construct our own matrix so we can use the local transform
vehicle->physVehicle->updateWheelTransform(w, false);
/// @todo migrate this into Vehicle physics tick so we can interpolate old -> new
/// @todo migrate this into Vehicle physics tick so we can
/// interpolate old -> new
glm::mat4 wheelM(matrixModel);
@ -431,68 +393,59 @@ void ObjectRenderer::renderVehicle(VehicleObject *vehicle,
btQuaternion steerQ(up, wi.m_steering);
btQuaternion rollQ(right, -wi.m_rotation);
btMatrix3x3 basis(
right[0], fwd[0], up[0],
right[1], fwd[1], up[1],
right[2], fwd[2], up[2]
);
btMatrix3x3 basis(right[0], fwd[0], up[0], right[1], fwd[1],
up[1], right[2], fwd[2], up[2]);
btTransform t;
t.setBasis(btMatrix3x3(steerQ) * btMatrix3x3(rollQ) * basis);
t.setOrigin(wi.m_chassisConnectionPointCS + wi.m_wheelDirectionCS * wi.m_raycastInfo.m_suspensionLength);
t.setOrigin(wi.m_chassisConnectionPointCS +
wi.m_wheelDirectionCS *
wi.m_raycastInfo.m_suspensionLength);
t.getOpenGLMatrix(glm::value_ptr(wheelM));
wheelM = matrixModel * wheelM;
wheelM = glm::scale(wheelM, glm::vec3(vehicle->vehicle->wheelScale));
wheelM =
glm::scale(wheelM, glm::vec3(vehicle->vehicle->wheelScale));
if (wi.m_chassisConnectionPointCS.x() < 0.f) {
wheelM = glm::scale(wheelM, glm::vec3(-1.f, 1.f, 1.f));
}
renderWheel(vehicle,
wheelModel,
wheelM,
woi->modelName,
renderWheel(vehicle, wheelModel, wheelM, woi->modelName,
outList);
}
}
}
}
void ObjectRenderer::renderPickup(PickupObject *pickup,
RenderList& outList)
{
void ObjectRenderer::renderPickup(PickupObject* pickup, RenderList& outList) {
if (!pickup->isEnabled()) return;
glm::mat4 modelMatrix = glm::translate(glm::mat4(), pickup->getPosition());
modelMatrix = glm::rotate(modelMatrix, m_world->getGameTime(), glm::vec3(0.f, 0.f, 1.f));
modelMatrix = glm::rotate(modelMatrix, m_world->getGameTime(),
glm::vec3(0.f, 0.f, 1.f));
auto odata = m_world->data->findObjectType<ObjectData>(pickup->getModelID());
auto odata =
m_world->data->findObjectType<ObjectData>(pickup->getModelID());
Model* model = nullptr;
ModelFrame* itemModel = nullptr;
/// @todo Better determination of is this object a weapon.
if( odata->ID >= 170 && odata->ID <= 184 )
{
if (odata->ID >= 170 && odata->ID <= 184) {
auto weapons = m_world->data->models["weapons"];
if (weapons && weapons->resource && odata) {
model = weapons->resource;
itemModel = weapons->resource->findFrame(odata->modelName + "_l0");
RW_CHECK(itemModel, "Weapon Frame not present int weapon model");
if ( ! itemModel )
{
if (!itemModel) {
return;
}
}
}
else
{
} else {
auto handle = m_world->data->models[odata->modelName];
RW_CHECK(handle && handle->resource, "Pickup has no model");
if ( handle && handle->resource )
{
if (handle && handle->resource) {
model = handle->resource;
itemModel = model->frames[model->rootFrameIdx];
}
@ -500,41 +453,38 @@ void ObjectRenderer::renderPickup(PickupObject *pickup,
if (itemModel) {
auto matrix = glm::inverse(itemModel->getTransform());
renderFrame(model,
itemModel,
modelMatrix * matrix,
pickup,
1.f,
renderFrame(model, itemModel, modelMatrix * matrix, pickup, 1.f,
outList);
}
}
void ObjectRenderer::renderCutsceneObject(CutsceneObject* cutscene,
RenderList& outList)
{
RenderList& outList) {
if (!m_world->state->currentCutscene) return;
if(!cutscene->model->resource)
{
if (!cutscene->model->resource) {
return;
}
glm::mat4 matrixModel;
auto cutsceneOffset = m_world->state->currentCutscene->meta.sceneOffset + glm::vec3(0.f, 0.f, 1.f);
auto cutsceneOffset = m_world->state->currentCutscene->meta.sceneOffset +
glm::vec3(0.f, 0.f, 1.f);
if (cutscene->getParentActor()) {
matrixModel = glm::translate(matrixModel, cutsceneOffset);
//matrixModel = cutscene->getParentActor()->getTimeAdjustedTransform(_renderAlpha);
// matrixModel =
// cutscene->getParentActor()->getTimeAdjustedTransform(_renderAlpha);
// matrixModel = glm::translate(matrixModel, glm::vec3(0.f, 0.f, 1.f));
glm::mat4 localMatrix;
auto boneframe = cutscene->getParentFrame();
while (boneframe) {
localMatrix = cutscene->getParentActor()->skeleton->getMatrix(boneframe->getIndex()) * localMatrix;
localMatrix = cutscene->getParentActor()->skeleton->getMatrix(
boneframe->getIndex()) *
localMatrix;
boneframe = boneframe->getParent();
}
matrixModel = matrixModel * localMatrix;
}
else {
} else {
matrixModel = glm::translate(matrixModel, cutsceneOffset);
}
@ -543,29 +493,20 @@ void ObjectRenderer::renderCutsceneObject(CutsceneObject *cutscene,
glm::mat4 align;
/// @todo figure out where this 90 degree offset is coming from.
align = glm::rotate(align, glm::half_pi<float>(), {0.f, 1.f, 0.f});
renderFrame(model,
model->frames[0],
matrixModel * align,
cutscene,
1.f,
renderFrame(model, model->frames[0], matrixModel * align, cutscene, 1.f,
outList);
}
else {
renderFrame(model,
model->frames[0],
matrixModel,
cutscene,
1.f,
} else {
renderFrame(model, model->frames[0], matrixModel, cutscene, 1.f,
outList);
}
}
void ObjectRenderer::renderProjectile(ProjectileObject* projectile,
RenderList& outList)
{
RenderList& outList) {
glm::mat4 modelMatrix = projectile->getTimeAdjustedTransform(m_renderAlpha);
auto odata = m_world->data->findObjectType<ObjectData>(projectile->getProjectileInfo().weapon->modelID);
auto odata = m_world->data->findObjectType<ObjectData>(
projectile->getProjectileInfo().weapon->modelID);
auto weapons = m_world->data->models["weapons"];
RW_CHECK(weapons, "Weapons model not loaded");
@ -575,48 +516,38 @@ void ObjectRenderer::renderProjectile(ProjectileObject *projectile,
auto matrix = glm::inverse(itemModel->getTransform());
RW_CHECK(itemModel, "Weapon frame not in model");
if (itemModel) {
renderFrame(weapons->resource,
itemModel,
modelMatrix * matrix,
projectile,
1.f,
outList);
renderFrame(weapons->resource, itemModel, modelMatrix * matrix,
projectile, 1.f, outList);
}
}
}
void ObjectRenderer::buildRenderList(GameObject* object, RenderList& outList)
{
if( object->skeleton )
{
void ObjectRenderer::buildRenderList(GameObject* object, RenderList& outList) {
if (object->skeleton) {
object->skeleton->interpolate(m_renderAlpha);
}
// Right now specialized on each object type
switch (object->type()) {
case GameObject::Instance:
renderInstance(static_cast<InstanceObject*>(object),
outList);
renderInstance(static_cast<InstanceObject*>(object), outList);
break;
case GameObject::Character:
renderCharacter(static_cast<CharacterObject*>(object),
outList);
break;;
renderCharacter(static_cast<CharacterObject*>(object), outList);
break;
;
case GameObject::Vehicle:
renderVehicle(static_cast<VehicleObject*>(object),
outList);
break;;
renderVehicle(static_cast<VehicleObject*>(object), outList);
break;
;
case GameObject::Pickup:
renderPickup(static_cast<PickupObject*>(object),
outList);
renderPickup(static_cast<PickupObject*>(object), outList);
break;
case GameObject::Projectile:
renderProjectile(static_cast<ProjectileObject*>(object),
outList);
renderProjectile(static_cast<ProjectileObject*>(object), outList);
break;
case GameObject::Cutscene:
renderCutsceneObject(static_cast<CutsceneObject*>(object),
outList);
renderCutsceneObject(static_cast<CutsceneObject*>(object), outList);
break;
default:
break;

View File

@ -1,13 +1,13 @@
#ifndef _RWENGINE_OBJECTRENDERER_HPP_
#define _RWENGINE_OBJECTRENDERER_HPP_
#include <glm/glm.hpp>
#include <rw/types.hpp>
#include <render/ViewCamera.hpp>
#include <render/OpenGLRenderer.hpp>
#include <objects/GameObject.hpp>
#include <engine/GameWorld.hpp>
#include <gl/DrawBuffer.hpp>
#include <glm/glm.hpp>
#include <objects/GameObject.hpp>
#include <render/OpenGLRenderer.hpp>
#include <render/ViewCamera.hpp>
#include <rw/types.hpp>
class ProjectileObject;
class PickupObject;
@ -18,18 +18,15 @@ class PickupObject;
* Determines what parts of an object are within a camera frustum and exports
* a list of things to render for the object.
*/
class ObjectRenderer
{
class ObjectRenderer {
public:
ObjectRenderer(GameWorld* world,
const ViewCamera& camera,
float renderAlpha,
GLuint errorTexture)
ObjectRenderer(GameWorld* world, const ViewCamera& camera,
float renderAlpha, GLuint errorTexture)
: m_world(world)
, m_camera(camera)
, m_renderAlpha(renderAlpha)
, m_errorTexture(errorTexture)
{ }
, m_errorTexture(errorTexture) {
}
/**
* @brief buildRenderList
@ -51,28 +48,17 @@ private:
void renderCutsceneObject(CutsceneObject* cutscene, RenderList& outList);
void renderProjectile(ProjectileObject* projectile, RenderList& outList);
void renderItem(InventoryItem *item,
const glm::mat4 &modelMatrix,
void renderItem(InventoryItem* item, const glm::mat4& modelMatrix,
RenderList& outList);
void renderWheel(VehicleObject* vehicle,
Model* model,
const glm::mat4 &matrix,
const std::string& name,
void renderWheel(VehicleObject* vehicle, Model* model,
const glm::mat4& matrix, const std::string& name,
RenderList& outList);
bool renderFrame(Model* m,
ModelFrame* f,
const glm::mat4& matrix,
GameObject* object,
float opacity,
RenderList& outList);
bool renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix,
GameObject* object, float opacity, RenderList& outList);
void renderGeometry(Model* model,
size_t g,
const glm::mat4& modelMatrix,
float opacity,
GameObject* object,
RenderList& outList);
void renderGeometry(Model* model, size_t g, const glm::mat4& modelMatrix,
float opacity, GameObject* object, RenderList& outList);
};
#endif

View File

@ -1,12 +1,11 @@
#include <render/OpenGLRenderer.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <render/OpenGLRenderer.hpp>
#include <sstream>
#include <iostream>
#include <sstream>
GLuint compileShader(GLenum type, const char *source)
{
GLuint compileShader(GLenum type, const char* source) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
@ -29,7 +28,9 @@ GLuint compileShader(GLenum type, const char *source)
GLchar* sourceBuff = new GLchar[sourceLen];
glGetShaderSource(shader, sourceLen, nullptr, sourceBuff);
std::cerr << "[OGL] Shader InfoLog(" << shader << "):\n" << buffer << "\nSource:\n" << sourceBuff << std::endl;
std::cerr << "[OGL] Shader InfoLog(" << shader << "):\n"
<< buffer << "\nSource:\n"
<< sourceBuff << std::endl;
delete[] buffer;
delete[] sourceBuff;
@ -42,8 +43,7 @@ GLuint compileShader(GLenum type, const char *source)
return shader;
}
GLuint compileProgram(const char* vertex, const char* fragment)
{
GLuint compileProgram(const char* vertex, const char* fragment) {
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertex);
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragment);
GLuint prog = glCreateProgram();
@ -64,7 +64,8 @@ GLuint compileProgram(const char* vertex, const char* fragment)
GLchar* buffer = new GLchar[len];
glGetProgramInfoLog(prog, len, NULL, buffer);
std::cerr << "[OGL] Program InfoLog(" << prog << "):\n" << buffer << std::endl;
std::cerr << "[OGL] Program InfoLog(" << prog << "):\n"
<< buffer << std::endl;
delete[] buffer;
}
@ -79,78 +80,64 @@ GLuint compileProgram(const char* vertex, const char* fragment)
return prog;
}
void Renderer::setViewport(const glm::ivec2& vp)
{
void Renderer::setViewport(const glm::ivec2& vp) {
viewport = vp;
projection2D = glm::ortho(0.f, (float)viewport.x, (float)viewport.y, 0.f, -1.f, 1.f);
projection2D =
glm::ortho(0.f, (float)viewport.x, (float)viewport.y, 0.f, -1.f, 1.f);
}
void Renderer::swap()
{
void Renderer::swap() {
drawCounter = 0;
textureCounter = 0;
bufferCounter = 0;
}
int Renderer::getDrawCount()
{
int Renderer::getDrawCount() {
return drawCounter;
}
int Renderer::getBufferCount()
{
int Renderer::getBufferCount() {
return bufferCounter;
}
int Renderer::getTextureCount()
{
int Renderer::getTextureCount() {
return textureCounter;
}
const Renderer::SceneUniformData& Renderer::getSceneData() const
{
const Renderer::SceneUniformData& Renderer::getSceneData() const {
return lastSceneData;
}
void OpenGLRenderer::useDrawBuffer(DrawBuffer* dbuff)
{
if( dbuff != currentDbuff )
{
void OpenGLRenderer::useDrawBuffer(DrawBuffer* dbuff) {
if (dbuff != currentDbuff) {
glBindVertexArray(dbuff->getVAOName());
currentDbuff = dbuff;
bufferCounter++;
#if RW_PROFILER
if( currentDebugDepth > 0 )
{
if (currentDebugDepth > 0) {
profileInfo[currentDebugDepth - 1].buffers++;
}
#endif
}
}
void OpenGLRenderer::useTexture(GLuint unit, GLuint tex)
{
if( currentTextures[unit] != tex )
{
void OpenGLRenderer::useTexture(GLuint unit, GLuint tex) {
if (currentTextures[unit] != tex) {
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, tex);
currentTextures[unit] = tex;
textureCounter++;
#if RW_PROFILER
if( currentDebugDepth > 0 )
{
if (currentDebugDepth > 0) {
profileInfo[currentDebugDepth - 1].textures++;
}
#endif
}
}
void OpenGLRenderer::useProgram(Renderer::ShaderProgram* p)
{
if( p != currentProgram )
{
void OpenGLRenderer::useProgram(Renderer::ShaderProgram* p) {
if (p != currentProgram) {
currentProgram = static_cast<OpenGLShaderProgram*>(p);
glUseProgram(currentProgram->getName());
}
@ -191,8 +178,7 @@ OpenGLRenderer::OpenGLRenderer()
, entryAlignment(0)
, blendEnabled(false)
, depthWriteEnabled(true)
, currentDebugDepth(0)
{
, currentDebugDepth(0) {
// We need to query for some profiling exts.
ogl_CheckExtensions();
@ -214,16 +200,13 @@ OpenGLRenderer::OpenGLRenderer()
std::cout << "Max batch size: " << maxObjectEntries << std::endl;
glBindBuffer(GL_UNIFORM_BUFFER, UBOObject);
glBufferData(GL_UNIFORM_BUFFER,
entryAlignment * maxObjectEntries,
NULL,
glBufferData(GL_UNIFORM_BUFFER, entryAlignment * maxObjectEntries, NULL,
GL_STREAM_DRAW);
glGenQueries(1, &debugQuery);
}
std::string OpenGLRenderer::getIDString() const
{
std::string OpenGLRenderer::getIDString() const {
std::stringstream ss;
ss << "OpenGL Renderer";
ss << " Version: " << glGetString(GL_VERSION);
@ -232,64 +215,68 @@ std::string OpenGLRenderer::getIDString() const
return ss.str();
}
Renderer::ShaderProgram* OpenGLRenderer::createShader(const std::string& vert, const std::string& frag)
{
return new OpenGLShaderProgram(
compileProgram(vert.c_str(), frag.c_str()));
Renderer::ShaderProgram* OpenGLRenderer::createShader(const std::string& vert,
const std::string& frag) {
return new OpenGLShaderProgram(compileProgram(vert.c_str(), frag.c_str()));
}
void OpenGLRenderer::setProgramBlockBinding(Renderer::ShaderProgram* p, const std::string& name, GLint point)
{
void OpenGLRenderer::setProgramBlockBinding(Renderer::ShaderProgram* p,
const std::string& name,
GLint point) {
OpenGLShaderProgram* glsh = static_cast<OpenGLShaderProgram*>(p);
auto ubi = glGetUniformBlockIndex(glsh->getName(), name.c_str());
glUniformBlockBinding(glsh->getName(), ubi, point);
}
void OpenGLRenderer::setUniformTexture(Renderer::ShaderProgram* p, const std::string& name, GLint tex)
{
void OpenGLRenderer::setUniformTexture(Renderer::ShaderProgram* p,
const std::string& name, GLint tex) {
useProgram(p);
glUniform1i(currentProgram->getUniformLocation(name), tex);
}
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p, const std::string& name, const glm::mat4& m)
{
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p,
const std::string& name, const glm::mat4& m) {
useProgram(p);
glUniformMatrix4fv(currentProgram->getUniformLocation(name.c_str()), 1, GL_FALSE, glm::value_ptr(m));
glUniformMatrix4fv(currentProgram->getUniformLocation(name.c_str()), 1,
GL_FALSE, glm::value_ptr(m));
}
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p, const std::string& name, const glm::vec4& m)
{
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p,
const std::string& name, const glm::vec4& m) {
useProgram(p);
glUniform4fv(currentProgram->getUniformLocation(name.c_str()), 1, glm::value_ptr(m));
glUniform4fv(currentProgram->getUniformLocation(name.c_str()), 1,
glm::value_ptr(m));
}
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p, const std::string& name, const glm::vec3& m)
{
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p,
const std::string& name, const glm::vec3& m) {
useProgram(p);
glUniform3fv(currentProgram->getUniformLocation(name.c_str()), 1, glm::value_ptr(m));
glUniform3fv(currentProgram->getUniformLocation(name.c_str()), 1,
glm::value_ptr(m));
}
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p, const std::string& name, const glm::vec2& m)
{
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p,
const std::string& name, const glm::vec2& m) {
useProgram(p);
glUniform2fv(currentProgram->getUniformLocation(name.c_str()), 1, glm::value_ptr(m));
glUniform2fv(currentProgram->getUniformLocation(name.c_str()), 1,
glm::value_ptr(m));
}
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p, const std::string& name, float f)
{
void OpenGLRenderer::setUniform(Renderer::ShaderProgram* p,
const std::string& name, float f) {
useProgram(p);
glUniform1fv(currentProgram->getUniformLocation(name.c_str()), 1, &f);
}
void OpenGLRenderer::clear(const glm::vec4& colour, bool clearColour, bool clearDepth)
{
void OpenGLRenderer::clear(const glm::vec4& colour, bool clearColour,
bool clearDepth) {
auto flags = 0;
if (clearColour) {
flags |= GL_COLOR_BUFFER_BIT;
@ -308,60 +295,54 @@ void OpenGLRenderer::clear(const glm::vec4& colour, bool clearColour, bool clear
}
}
void OpenGLRenderer::setSceneParameters(const Renderer::SceneUniformData& data)
{
void OpenGLRenderer::setSceneParameters(
const Renderer::SceneUniformData& data) {
uploadUBO(UBOScene, data);
lastSceneData = data;
}
void OpenGLRenderer::setDrawState(const glm::mat4& model, DrawBuffer* draw, const Renderer::DrawParameters& p)
{
void OpenGLRenderer::setDrawState(const glm::mat4& model, DrawBuffer* draw,
const Renderer::DrawParameters& p) {
useDrawBuffer(draw);
for( GLuint u = 0; u < p.textures.size(); ++u )
{
for (GLuint u = 0; u < p.textures.size(); ++u) {
useTexture(u, p.textures[u]);
}
setBlend(p.blend);
setDepthWrite(p.depthWrite);
ObjectUniformData oudata {
model,
glm::vec4(p.colour.r/255.f, p.colour.g/255.f, p.colour.b/255.f, p.colour.a/255.f),
1.f,
1.f,
p.visibility
};
ObjectUniformData oudata{model,
glm::vec4(p.colour.r / 255.f, p.colour.g / 255.f,
p.colour.b / 255.f, p.colour.a / 255.f),
1.f, 1.f, p.visibility};
uploadUBO(UBOObject, oudata);
drawCounter++;
#if RW_PROFILER
if( currentDebugDepth > 0 )
{
if (currentDebugDepth > 0) {
profileInfo[currentDebugDepth - 1].draws++;
profileInfo[currentDebugDepth - 1].primitives += p.count;
}
#endif
}
void OpenGLRenderer::draw(const glm::mat4& model, DrawBuffer* draw, const Renderer::DrawParameters& p)
{
void OpenGLRenderer::draw(const glm::mat4& model, DrawBuffer* draw,
const Renderer::DrawParameters& p) {
setDrawState(model, draw, p);
glDrawElements(draw->getFaceType(), p.count, GL_UNSIGNED_INT,
(void*)(sizeof(RenderIndex) * p.start));
}
void OpenGLRenderer::drawArrays(const glm::mat4& model, DrawBuffer* draw, const Renderer::DrawParameters& p)
{
void OpenGLRenderer::drawArrays(const glm::mat4& model, DrawBuffer* draw,
const Renderer::DrawParameters& p) {
setDrawState(model, draw, p);
glDrawArrays(draw->getFaceType(), p.start, p.count);
}
void OpenGLRenderer::drawBatched(const RenderList& list)
{
void OpenGLRenderer::drawBatched(const RenderList& list) {
#if 0 // Needs shader changes
// Determine how many batches we need to process the entire list
auto entries = list.size();
@ -405,29 +386,26 @@ void OpenGLRenderer::drawBatched(const RenderList& list)
}
}
#else
for(auto& ri : list)
{
for (auto& ri : list) {
draw(ri.model, ri.dbuff, ri.drawInfo);
}
#endif
}
void OpenGLRenderer::invalidate()
{
void OpenGLRenderer::invalidate() {
currentDbuff = nullptr;
currentProgram = nullptr;
currentTextures.clear();
currentUBO = 0;
}
void OpenGLRenderer::pushDebugGroup(const std::string& title)
{
void OpenGLRenderer::pushDebugGroup(const std::string& title) {
#if RW_PROFILER
if( ogl_ext_KHR_debug )
{
if (ogl_ext_KHR_debug) {
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, title.c_str());
ProfileInfo& prof = profileInfo[currentDebugDepth];
prof.buffers = prof.draws = prof.textures = prof.uploads = prof.primitives = 0;
prof.buffers = prof.draws = prof.textures = prof.uploads =
prof.primitives = 0;
glQueryCounter(debugQuery, GL_TIMESTAMP);
glGetQueryObjectui64v(debugQuery, GL_QUERY_RESULT, &prof.timerStart);
@ -440,11 +418,9 @@ void OpenGLRenderer::pushDebugGroup(const std::string& title)
#endif
}
const Renderer::ProfileInfo& OpenGLRenderer::popDebugGroup()
{
const Renderer::ProfileInfo& OpenGLRenderer::popDebugGroup() {
#if RW_PROFILER
if( ogl_ext_KHR_debug )
{
if (ogl_ext_KHR_debug) {
glPopDebugGroup();
currentDebugDepth--;
assert(currentDebugDepth >= 0);
@ -458,8 +434,7 @@ const Renderer::ProfileInfo& OpenGLRenderer::popDebugGroup()
prof.duration = current_time - prof.timerStart;
// Add counters to the parent group
if( currentDebugDepth > 0 )
{
if (currentDebugDepth > 0) {
ProfileInfo& p = profileInfo[currentDebugDepth - 1];
p.draws += prof.draws;
p.buffers += prof.buffers;

View File

@ -2,10 +2,10 @@
#ifndef _OPENGLRENDERER_HPP_
#define _OPENGLRENDERER_HPP_
#include <rw/types.hpp>
#include <gl/DrawBuffer.hpp>
#include <gl/GeometryBuffer.hpp>
#include <glm/vec2.hpp>
#include <rw/types.hpp>
typedef uint64_t RenderKey;
@ -14,8 +14,7 @@ typedef uint64_t RenderKey;
typedef std::uint32_t RenderIndex;
struct VertexP3
{
struct VertexP3 {
glm::vec3 position;
static const AttributeList vertex_attributes() {
@ -28,18 +27,14 @@ struct VertexP3
/// @todo normalize this to have the same interface as VertexP3
struct VertexP2 {
static const AttributeList vertex_attributes() {
return {
{ATRS_Position, 2, sizeof(VertexP2), 0ul}
};
return {{ATRS_Position, 2, sizeof(VertexP2), 0ul}};
}
float x, y;
};
class Renderer
{
class Renderer {
public:
typedef std::vector<GLuint> Textures;
/**
@ -51,8 +46,7 @@ public:
* Since not all draws use the same shaders, material properties
* should be controlled via a different mechanism.
*/
struct DrawParameters
{
struct DrawParameters {
/// Number of indicies
size_t count;
/// Start index.
@ -78,8 +72,8 @@ public:
, depthWrite(true)
, ambient(1.f)
, diffuse(1.f)
, visibility(1.f)
{ }
, visibility(1.f) {
}
};
/**
@ -88,30 +82,21 @@ public:
* These are generated by the ObjectRenderer, and passed in to the
* OpenGLRenderer by GameRenderer.
*/
struct RenderInstruction
{
struct RenderInstruction {
RenderKey sortKey;
// Ideally, this would just be an index into a buffer that contains the matrix
// Ideally, this would just be an index into a buffer that contains the
// matrix
glm::mat4 model;
DrawBuffer* dbuff;
Renderer::DrawParameters drawInfo;
RenderInstruction(
RenderKey key,
const glm::mat4& model,
DrawBuffer* dbuff,
const Renderer::DrawParameters& dp)
: sortKey(key)
, model(model)
, dbuff(dbuff)
, drawInfo(dp)
{
RenderInstruction(RenderKey key, const glm::mat4& model,
DrawBuffer* dbuff, const Renderer::DrawParameters& dp)
: sortKey(key), model(model), dbuff(dbuff), drawInfo(dp) {
}
};
typedef std::vector<RenderInstruction> RenderList;
struct ObjectUniformData {
glm::mat4 model;
glm::vec4 colour;
@ -137,32 +122,48 @@ public:
virtual std::string getIDString() const = 0;
virtual ShaderProgram* createShader(const std::string& vert, const std::string& frag) = 0;
virtual ShaderProgram* createShader(const std::string& vert,
const std::string& frag) = 0;
virtual void useProgram(ShaderProgram* p) = 0;
/// @todo dont use GLint in the interface.
virtual void setProgramBlockBinding(ShaderProgram* p, const std::string& name, GLint point) = 0;
virtual void setUniformTexture(ShaderProgram*p, const std::string& name, GLint tex) = 0;
virtual void setUniform(ShaderProgram*p, const std::string& name, const glm::mat4& m) = 0;
virtual void setUniform(ShaderProgram*p, const std::string& name, const glm::vec4& v) = 0;
virtual void setUniform(ShaderProgram*p, const std::string& name, const glm::vec3& v) = 0;
virtual void setUniform(ShaderProgram*p, const std::string& name, const glm::vec2& v) = 0;
virtual void setUniform(ShaderProgram*p, const std::string& name, float f) = 0;
virtual void setProgramBlockBinding(ShaderProgram* p,
const std::string& name,
GLint point) = 0;
virtual void setUniformTexture(ShaderProgram* p, const std::string& name,
GLint tex) = 0;
virtual void setUniform(ShaderProgram* p, const std::string& name,
const glm::mat4& m) = 0;
virtual void setUniform(ShaderProgram* p, const std::string& name,
const glm::vec4& v) = 0;
virtual void setUniform(ShaderProgram* p, const std::string& name,
const glm::vec3& v) = 0;
virtual void setUniform(ShaderProgram* p, const std::string& name,
const glm::vec2& v) = 0;
virtual void setUniform(ShaderProgram* p, const std::string& name,
float f) = 0;
virtual void clear(const glm::vec4& colour, bool clearColour = true, bool clearDepth = true) = 0;
virtual void clear(const glm::vec4& colour, bool clearColour = true,
bool clearDepth = true) = 0;
virtual void setSceneParameters(const SceneUniformData& data) = 0;
virtual void draw(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p) = 0;
virtual void drawArrays(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p) = 0;
virtual void draw(const glm::mat4& model, DrawBuffer* draw,
const DrawParameters& p) = 0;
virtual void drawArrays(const glm::mat4& model, DrawBuffer* draw,
const DrawParameters& p) = 0;
virtual void drawBatched(const RenderList& list) = 0;
void setViewport(const glm::ivec2& vp);
const glm::ivec2& getViewport() const { return viewport; }
const glm::ivec2& getViewport() const {
return viewport;
}
const glm::mat4& get2DProjection() const { return projection2D; }
const glm::mat4& get2DProjection() const {
return projection2D;
}
virtual void invalidate() = 0;
@ -185,8 +186,7 @@ public:
* Not all fields will be populated, depending on
* USING(RENDER_PROFILER)
*/
struct ProfileInfo
{
struct ProfileInfo {
GLuint64 timerStart;
GLuint64 duration;
unsigned int primitives;
@ -210,6 +210,7 @@ public:
private:
glm::ivec2 viewport;
glm::mat4 projection2D;
protected:
int drawCounter;
int textureCounter;
@ -217,19 +218,19 @@ protected:
SceneUniformData lastSceneData;
};
class OpenGLRenderer : public Renderer
{
class OpenGLRenderer : public Renderer {
public:
class OpenGLShaderProgram : public ShaderProgram {
GLuint program;
std::map<std::string, GLint> uniforms;
public:
OpenGLShaderProgram(GLuint p)
: program(p)
{ }
GLuint getName() const { return program; }
public:
OpenGLShaderProgram(GLuint p) : program(p) {
}
GLuint getName() const {
return program;
}
GLint getUniformLocation(const std::string& name) {
auto c = uniforms.find(name.c_str());
@ -237,8 +238,7 @@ public:
if (c == uniforms.end()) {
loc = glGetUniformLocation(program, name.c_str());
uniforms[name] = loc;
}
else {
} else {
loc = c->second;
}
return loc;
@ -249,24 +249,36 @@ public:
std::string getIDString() const override;
ShaderProgram* createShader(const std::string &vert, const std::string &frag) override;
void setProgramBlockBinding(ShaderProgram* p, const std::string &name, GLint point) override;
void setUniformTexture(ShaderProgram* p, const std::string &name, GLint tex) override;
void setUniform(ShaderProgram* p, const std::string& name, const glm::mat4& m) override;
void setUniform(ShaderProgram* p, const std::string& name, const glm::vec4& m) override;
void setUniform(ShaderProgram* p, const std::string& name, const glm::vec3& m) override;
void setUniform(ShaderProgram* p, const std::string& name, const glm::vec2& m) override;
void setUniform(ShaderProgram* p, const std::string& name, float f) override;
ShaderProgram* createShader(const std::string& vert,
const std::string& frag) override;
void setProgramBlockBinding(ShaderProgram* p, const std::string& name,
GLint point) override;
void setUniformTexture(ShaderProgram* p, const std::string& name,
GLint tex) override;
void setUniform(ShaderProgram* p, const std::string& name,
const glm::mat4& m) override;
void setUniform(ShaderProgram* p, const std::string& name,
const glm::vec4& m) override;
void setUniform(ShaderProgram* p, const std::string& name,
const glm::vec3& m) override;
void setUniform(ShaderProgram* p, const std::string& name,
const glm::vec2& m) override;
void setUniform(ShaderProgram* p, const std::string& name,
float f) override;
void useProgram(ShaderProgram* p) override;
void clear(const glm::vec4 &colour, bool clearColour, bool clearDepth) override;
void clear(const glm::vec4& colour, bool clearColour,
bool clearDepth) override;
void setSceneParameters(const SceneUniformData& data) override;
void setDrawState(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p);
void setDrawState(const glm::mat4& model, DrawBuffer* draw,
const DrawParameters& p);
void draw(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p) override;
void drawArrays(const glm::mat4& model, DrawBuffer* draw, const DrawParameters& p) override;
void draw(const glm::mat4& model, DrawBuffer* draw,
const DrawParameters& p) override;
void drawArrays(const glm::mat4& model, DrawBuffer* draw,
const DrawParameters& p) override;
void drawBatched(const RenderList& list) override;
@ -286,16 +298,15 @@ private:
OpenGLShaderProgram* currentProgram;
GLuint currentUBO;
template<class T> void uploadUBO(GLuint buffer, const T& data)
{
template <class T>
void uploadUBO(GLuint buffer, const T& data) {
if (currentUBO != buffer) {
glBindBuffer(GL_UNIFORM_BUFFER, buffer);
currentUBO = buffer;
}
glBufferData(GL_UNIFORM_BUFFER, sizeof(T), &data, GL_DYNAMIC_DRAW);
#if RW_PROFILER
if( currentDebugDepth > 0 )
{
if (currentDebugDepth > 0) {
profileInfo[currentDebugDepth - 1].uploads++;
}
#endif
@ -312,11 +323,11 @@ private:
bool depthWriteEnabled;
// Set state
void setBlend(bool enable)
{
void setBlend(bool enable) {
RW_UNUSED(enable);
/// @todo set blendEnabled, currently not possible because other functions keep trashing the state
/// @todo set blendEnabled, currently not possible because other functions keep
/// trashing the state
#if 0
if (enable && !blendEnabled) {
glEnable(GL_BLEND);
@ -330,8 +341,7 @@ private:
#endif
}
void setDepthWrite(bool enable)
{
void setDepthWrite(bool enable) {
if (enable != depthWriteEnabled) {
glDepthMask(enable ? GL_TRUE : GL_FALSE);
depthWriteEnabled = enable;
@ -348,7 +358,6 @@ private:
GLuint compileShader(GLenum type, const char* source);
GLuint compileProgram(const char* vertex, const char* fragment);
typedef Renderer::RenderList RenderList;
#endif

View File

@ -1,28 +1,24 @@
#include "render/TextRenderer.hpp"
#include <render/GameRenderer.hpp>
#include <engine/GameWorld.hpp>
#include <render/GameRenderer.hpp>
#include <algorithm>
#include <cctype>
int charToIndex(uint16_t g)
{
int charToIndex(uint16_t g) {
// Correct for the default font maps
/// @todo confirm for JA / RU font maps
return g - 32;
}
glm::vec4 indexToCoord(int font, int index)
{
glm::vec4 indexToCoord(int font, int index) {
float x = int(index % 16);
float y = int(index / 16) + 0.01f;
float fontHeight = ((font == 0) ? 16.f : 13.f);
glm::vec2 gsize(1.f / 16.f, 1.f / fontHeight);
return glm::vec4( x, y, x + 1, y + 0.98f ) *
glm::vec4( gsize, gsize );
return glm::vec4(x, y, x + 1, y + 0.98f) * glm::vec4(gsize, gsize);
}
const char* TextVertexShader = R"(
#version 330
@ -57,8 +53,7 @@ void main()
outColour = vec4(Colour, a);
})";
struct TextVertex
{
struct TextVertex {
glm::vec2 position;
glm::vec2 texcoord;
glm::vec3 colour;
@ -73,19 +68,14 @@ struct TextVertex
};
TextRenderer::TextInfo::TextInfo()
: font(0), size(1.f), baseColour({1.f, 1.f, 1.f}), align(Left), wrapX(0)
{
: font(0), size(1.f), baseColour({1.f, 1.f, 1.f}), align(Left), wrapX(0) {
}
TextRenderer::TextRenderer(GameRenderer* renderer)
: renderer(renderer)
{
textShader = renderer->getRenderer()->createShader(
TextVertexShader, TextFragmentShader );
TextRenderer::TextRenderer(GameRenderer* renderer) : renderer(renderer) {
textShader = renderer->getRenderer()->createShader(TextVertexShader,
TextFragmentShader);
for( int g = 0; g < GAME_GLYPHS; g++ )
{
for (int g = 0; g < GAME_GLYPHS; g++) {
glyphData[g] = {.9f};
}
@ -102,10 +92,8 @@ TextRenderer::TextRenderer(GameRenderer* renderer)
}
// Assumes contigious a-z character encoding
for(char g = 0; g <= ('z'-'a'); g++)
{
switch( ('a' + g) )
{
for (char g = 0; g <= ('z' - 'a'); g++) {
switch (('a' + g)) {
case 'i':
glyphData[charToIndex('a' + g)].widthFrac = 0.4f;
glyphData[charToIndex('A' + g)].widthFrac = 0.4f;
@ -130,21 +118,17 @@ TextRenderer::TextRenderer(GameRenderer* renderer)
}
}
TextRenderer::~TextRenderer()
{
TextRenderer::~TextRenderer() {
}
void TextRenderer::setFontTexture(int index, const std::string& texture)
{
if( index < GAME_FONTS )
{
void TextRenderer::setFontTexture(int index, const std::string& texture) {
if (index < GAME_FONTS) {
fonts[index] = texture;
}
}
void TextRenderer::renderText(const TextRenderer::TextInfo& ti, bool forceColour)
{
void TextRenderer::renderText(const TextRenderer::TextInfo& ti,
bool forceColour) {
renderer->getRenderer()->pushDebugGroup("Text");
renderer->getRenderer()->useProgram(textShader);
@ -168,48 +152,51 @@ void TextRenderer::renderText(const TextRenderer::TextInfo& ti, bool forceColour
auto text = ti.text;
for (size_t i = 0; i < text.length(); ++i)
{
for (size_t i = 0; i < text.length(); ++i) {
char16_t c = text[i];
// Handle any markup changes.
if( c == '~' && text.length() > i + 1 )
{
switch( text[i+1] )
{
if (c == '~' && text.length() > i + 1) {
switch (text[i + 1]) {
case 'g': // Green
text.erase(text.begin() + i, text.begin() + i + 3);
colour = glm::vec3(glm::u8vec3(90, 157, 102)) * (1 / 255.f);
break;
case 'h': // White
text.erase(text.begin() + i, text.begin() + i + 3);
colour = glm::vec3(1.f); /// @todo FIXME! Use proper colour!
colour =
glm::vec3(1.f); /// @todo FIXME! Use proper colour!
break;
case 'k': { // Key
text.erase(text.begin() + i, text.begin() + i + 3);
// Extract the key name from the /next/ markup
auto keyend = text.find('~', i + 1);
auto keyname = text.substr(i + 1, keyend - i - 1);
// Since we don't have a key map yet, just print out the name
// Since we don't have a key map yet, just print out the
// name
text.erase(text.begin() + i, text.begin() + keyend);
text.insert(i, keyname);
break;
}
case 'l': // Black
text.erase(text.begin() + i, text.begin() + i + 3);
colour = glm::vec3(0.f); /// @todo FIXME! Use proper colour!
colour =
glm::vec3(0.f); /// @todo FIXME! Use proper colour!
break;
case 'r': // Red
text.erase(text.begin() + i, text.begin() + i + 3);
colour = glm::vec3(1.f, 0.0f, 0.0f); /// @todo FIXME! Use proper colour!
colour = glm::vec3(
1.f, 0.0f, 0.0f); /// @todo FIXME! Use proper colour!
break;
case 'w': // Gray
text.erase(text.begin() + i, text.begin() + i + 3);
colour = glm::vec3(0.5f); /// @todo FIXME! Use proper colour!
colour =
glm::vec3(0.5f); /// @todo FIXME! Use proper colour!
break;
case 'y': // Yellow
text.erase(text.begin() + i, text.begin() + i + 3);
colour = glm::vec3(1.0f, 1.0f, 0.0f); /// @todo FIXME! Use proper colour!
colour = glm::vec3(
1.0f, 1.0f, 0.0f); /// @todo FIXME! Use proper colour!
break;
}
@ -221,23 +208,18 @@ void TextRenderer::renderText(const TextRenderer::TextInfo& ti, bool forceColour
}
int glyph = charToIndex(c);
if( glyph >= GAME_GLYPHS )
{
if (glyph >= GAME_GLYPHS) {
continue;
}
// If we're not at the start of the column, check if the current word
// will need to be wrapped
if (ti.wrapX > 0 && coord.x > 0.f && !std::isspace(c))
{
auto wend = std::find_if(std::begin(text)+i,
std::end(text),
if (ti.wrapX > 0 && coord.x > 0.f && !std::isspace(c)) {
auto wend = std::find_if(std::begin(text) + i, std::end(text),
[](char x) { return std::isspace(x); });
if (wend != std::end(text))
{
if (wend != std::end(text)) {
auto word = std::distance(std::begin(text) + i, wend);
if (lineLength + word >= ti.wrapX)
{
if (lineLength + word >= ti.wrapX) {
coord.x = 0;
coord.y += ss.y;
maxHeight = coord.y + ss.y;
@ -253,8 +235,7 @@ void TextRenderer::renderText(const TextRenderer::TextInfo& ti, bool forceColour
tex.z = tex.x + (tex.z - tex.x) * data.widthFrac;
// Handle special chars.
if( c == '\n' )
{
if (c == '\n') {
coord.x = 0.f;
coord.y += ss.y;
maxHeight = coord.y + ss.y;
@ -271,35 +252,28 @@ void TextRenderer::renderText(const TextRenderer::TextInfo& ti, bool forceColour
geo.push_back({{p.x + ss.x, p.y + ss.y}, {tex.z, tex.w}, colour});
geo.push_back({{p.x, p.y}, {tex.x, tex.y}, colour});
geo.push_back({{p.x + ss.x, p.y}, {tex.z, tex.y}, colour});
geo.push_back({{p.x, p.y}, {tex.x, tex.y}, colour});
geo.push_back({{p.x + ss.x, p.y + ss.y}, {tex.z, tex.w}, colour});
}
if ( ti.align == TextInfo::Right )
{
if (ti.align == TextInfo::Right) {
alignment.x -= maxWidth;
}
else if ( ti.align == TextInfo::Center )
{
} else if (ti.align == TextInfo::Center) {
alignment.x -= (maxWidth / 2.f);
}
alignment.y -= ti.size * 0.2f;
// If we need to, draw the background.
if (colourBG.a > 0.f)
{
if (colourBG.a > 0.f) {
renderer->drawColour(
colourBG,
glm::vec4(
ti.screenPosition - (ss/3.f),
colourBG, glm::vec4(ti.screenPosition - (ss / 3.f),
glm::vec2(maxWidth, maxHeight) + (ss / 2.f)));
}
renderer->getRenderer()->setUniform(textShader, "proj", renderer->getRenderer()->get2DProjection());
renderer->getRenderer()->setUniform(
textShader, "proj", renderer->getRenderer()->get2DProjection());
renderer->getRenderer()->setUniformTexture(textShader, "fontTexture", 0);
renderer->getRenderer()->setUniform(textShader, "alignment", alignment);

View File

@ -13,21 +13,13 @@ class GameRenderer;
* In future, strings textures might be cached to improve performance, but
* for now, we just render each glyph on it's own quad
*/
class TextRenderer
{
class TextRenderer {
public:
/**
* @todo Can this be merged with the gamestate text entries?
*/
struct TextInfo
{
enum TextAlignemnt
{
Left = 0,
Right = 1,
Center = 2
};
struct TextInfo {
enum TextAlignemnt { Left = 0, Right = 1, Center = 2 };
/// Font index @see TextRenderer::setFontTexture
int font;
@ -52,8 +44,7 @@ public:
/**
* Stores the information for kerning a glyph
*/
struct GlyphInfo
{
struct GlyphInfo {
float widthFrac;
};

View File

@ -1,30 +1,25 @@
#ifndef _VIEWCAMERA_HPP_
#define _VIEWCAMERA_HPP_
#include "ViewFrustum.hpp"
#include <glm/gtc/quaternion.hpp>
#include "ViewFrustum.hpp"
class ViewCamera
{
class ViewCamera {
public:
ViewFrustum frustum;
glm::vec3 position;
glm::quat rotation;
ViewCamera(const glm::vec3& pos = {}, const glm::quat& rot = {})
: frustum({0.1f, 5000.f, glm::radians(45.f), 1.f}),
position(pos), rotation(rot)
{
: frustum({0.1f, 5000.f, glm::radians(45.f), 1.f})
, position(pos)
, rotation(rot) {
}
glm::mat4 getView()
{
glm::mat4 getView() {
auto up = rotation * glm::vec3(0.f, 0.f, 1.f);
return glm::lookAt(position,
position + rotation * glm::vec3(1.f, 0.f, 0.f),
up);
position + rotation * glm::vec3(1.f, 0.f, 0.f), up);
}
};

View File

@ -6,12 +6,9 @@
#include <rw_mingw.hpp>
#endif
class ViewFrustum
{
class ViewFrustum {
public:
class ViewPlane
{
class ViewPlane {
public:
glm::vec3 normal;
float distance;
@ -25,20 +22,15 @@ public:
ViewPlane planes[6];
ViewFrustum(float near, float far, float fov, float aspect)
: near(near), far(far), fov(fov), aspectRatio(aspect)
{
: near(near), far(far), fov(fov), aspectRatio(aspect) {
}
glm::mat4 projection()
{
glm::mat4 projection() {
return glm::perspective(fov / aspectRatio, aspectRatio, near, far);
}
void update(const glm::mat4& proj)
{
for(size_t i = 0; i < 6; ++i)
{
void update(const glm::mat4& proj) {
for (size_t i = 0; i < 6; ++i) {
float sign = (i % 2 == 0) ? 1.f : -1.f;
int r = i / 2;
planes[i].normal.x = proj[0][3] + proj[0][r] * sign;
@ -52,13 +44,11 @@ public:
}
}
bool intersects(glm::vec3 center, float radius) const
{
bool intersects(glm::vec3 center, float radius) const {
float d;
bool result = true;
for(size_t i = 0; i < 6; ++i)
{
for (size_t i = 0; i < 6; ++i) {
d = glm::dot(planes[i].normal, center) + planes[i].distance;
if (d < -radius) result = false;
}

View File

@ -2,26 +2,17 @@
#include <memory>
VisualFX::LightData::~LightData()
{
VisualFX::LightData::~LightData() {
}
VisualFX::ParticleData::~ParticleData()
{
VisualFX::ParticleData::~ParticleData() {
}
VisualFX::TrailData::~TrailData()
{
VisualFX::TrailData::~TrailData() {
}
VisualFX::VisualFX(VisualFX::EffectType type)
: type(type)
{
switch( type )
{
VisualFX::VisualFX(VisualFX::EffectType type) : type(type) {
switch (type) {
case VisualFX::Light:
new (&light) LightData;
break;
@ -34,10 +25,8 @@ VisualFX::VisualFX(VisualFX::EffectType type)
}
}
VisualFX::~VisualFX()
{
switch( type )
{
VisualFX::~VisualFX() {
switch (type) {
case VisualFX::Light:
light.~LightData();
break;
@ -50,15 +39,12 @@ VisualFX::~VisualFX()
}
}
const glm::vec3& VisualFX::getPosition() const
{
const glm::vec3& VisualFX::getPosition() const {
static glm::vec3 errorRef;
switch( type )
{
switch (type) {
case VisualFX::Particle:
return particle.position;
default:
return errorRef;
}
}

View File

@ -1,27 +1,19 @@
#pragma once
#include <glm/glm.hpp>
#include <gl/TextureData.hpp>
#include <glm/glm.hpp>
/**
* Represents a scene effect: lighting, particles etc.
*/
class VisualFX
{
class VisualFX {
public:
enum EffectType
{
Light,
Particle,
Trail
};
enum EffectType { Light, Particle, Trail };
struct LightData
{
struct LightData {
~LightData();
};
struct ParticleData
{
struct ParticleData {
/** Initial world position */
glm::vec3 position;
@ -38,7 +30,8 @@ public:
/** Game time at particle instantiation */
float starttime;
/** Number of seconds particle should exist for, negative values = forever */
/** Number of seconds particle should exist for, negative values =
* forever */
float lifetime;
/** Texture name */
@ -55,12 +48,16 @@ public:
/** Constructs a particle */
ParticleData()
: orientation(Free), starttime(0.f), lifetime(-1.f), size(1.f, 1.f),
up(0.f, 0.f, 1.f), colour(1.f, 1.f, 1.f, 1.f) { }
: orientation(Free)
, starttime(0.f)
, lifetime(-1.f)
, size(1.f, 1.f)
, up(0.f, 0.f, 1.f)
, colour(1.f, 1.f, 1.f, 1.f) {
}
~ParticleData();
};
struct TrailData
{
struct TrailData {
~TrailData();
};
@ -74,7 +71,9 @@ public:
VisualFX(EffectType type);
~VisualFX();
EffectType getType() const { return type; }
EffectType getType() const {
return type;
}
const glm::vec3& getPosition() const;

View File

@ -1,22 +1,19 @@
#include <render/WaterRenderer.hpp>
#include <engine/GameWorld.hpp>
#include <render/GameRenderer.hpp>
#include <render/GameShaders.hpp>
#include <engine/GameWorld.hpp>
#include <render/WaterRenderer.hpp>
#include <glm/glm.hpp>
WaterRenderer::WaterRenderer(GameRenderer* renderer)
: waterProg(nullptr)
{
WaterRenderer::WaterRenderer(GameRenderer* renderer) : waterProg(nullptr) {
maskDraw.setFaceType(GL_TRIANGLES);
gridDraw.setFaceType(GL_TRIANGLES);
waterProg = renderer->getRenderer()->createShader(
GameShaders::WaterHQ::VertexShader, GameShaders::WaterHQ::FragmentShader
);
GameShaders::WaterHQ::VertexShader,
GameShaders::WaterHQ::FragmentShader);
maskProg = renderer->getRenderer()->createShader(
GameShaders::Mask3D::VertexShader, GameShaders::Mask3D::FragmentShader
);
GameShaders::Mask3D::VertexShader, GameShaders::Mask3D::FragmentShader);
renderer->getRenderer()->setProgramBlockBinding(waterProg, "SceneData", 1);
renderer->getRenderer()->setProgramBlockBinding(maskProg, "SceneData", 1);
@ -28,10 +25,8 @@ WaterRenderer::WaterRenderer(GameRenderer* renderer)
std::vector<glm::vec2> grid;
float gridresinv = 1.f / (gridres * 0.5f);
glm::vec2 b(-1.f, -1.f);
for( int x = 0; x < gridres; x++ )
{
for( int y = 0; y < gridres; y++ )
{
for (int x = 0; x < gridres; x++) {
for (int y = 0; y < gridres; y++) {
glm::vec2 tMin(b + glm::vec2(x, y) * gridresinv);
glm::vec2 tMax(b + glm::vec2(x + 1, y + 1) * gridresinv);
@ -46,20 +41,17 @@ WaterRenderer::WaterRenderer(GameRenderer* renderer)
}
}
gridGeom.uploadVertices(grid.size(), sizeof(glm::vec2)*grid.size(), grid.data());
gridGeom.getDataAttributes().push_back(
{ATRS_Position, 2, 0, 0, GL_FLOAT}
);
gridGeom.uploadVertices(grid.size(), sizeof(glm::vec2) * grid.size(),
grid.data());
gridGeom.getDataAttributes().push_back({ATRS_Position, 2, 0, 0, GL_FLOAT});
gridDraw.addGeometry(&gridGeom);
}
WaterRenderer::~WaterRenderer()
{
WaterRenderer::~WaterRenderer() {
}
void WaterRenderer::setWaterTable(float* waterHeights, unsigned int nHeights, uint8_t* tiles, unsigned int nTiles)
{
void WaterRenderer::setWaterTable(float* waterHeights, unsigned int nHeights,
uint8_t* tiles, unsigned int nTiles) {
// Determine the dimensions of the input tiles
int edgeNum = sqrt(nTiles);
float tileSize = WATER_WORLD_SIZE / edgeNum;
@ -67,11 +59,9 @@ void WaterRenderer::setWaterTable(float* waterHeights, unsigned int nHeights, ui
std::vector<glm::vec3> vertexData;
for( int x = 0; x < edgeNum; x++ )
{
for (int x = 0; x < edgeNum; x++) {
int xi = x * WATER_HQ_DATA_SIZE;
for( int y = 0; y < edgeNum; y++ )
{
for (int y = 0; y < edgeNum; y++) {
RW_CHECK(tiles[xi + y] < nHeights, "Tile index out of bounds");
if (tiles[xi + y] >= nHeights) continue;
@ -93,21 +83,19 @@ void WaterRenderer::setWaterTable(float* waterHeights, unsigned int nHeights, ui
}
}
maskGeom.uploadVertices(vertexData.size(), sizeof(glm::vec3)*vertexData.size(), vertexData.data());
maskGeom.getDataAttributes().push_back(
{ATRS_Position, 3, 0, 0, GL_FLOAT}
);
maskGeom.uploadVertices(vertexData.size(),
sizeof(glm::vec3) * vertexData.size(),
vertexData.data());
maskGeom.getDataAttributes().push_back({ATRS_Position, 3, 0, 0, GL_FLOAT});
maskDraw.addGeometry(&maskGeom);
}
void WaterRenderer::setDataTexture(GLuint fbBinding, GLuint dataTex)
{
void WaterRenderer::setDataTexture(GLuint fbBinding, GLuint dataTex) {
fbOutput = fbBinding;
dataTexture = dataTex;
}
void WaterRenderer::render(GameRenderer* renderer, GameWorld* world)
{
void WaterRenderer::render(GameRenderer* renderer, GameWorld* world) {
auto r = renderer->getRenderer();
auto waterTex = world->data->findTexture("water_old");
@ -136,7 +124,6 @@ void WaterRenderer::render(GameRenderer* renderer, GameWorld* world)
r->useProgram(maskProg);
r->drawArrays(m, &maskDraw, wdp);
glStencilFunc(GL_EQUAL, 1, 0xFF);
@ -149,8 +136,10 @@ void WaterRenderer::render(GameRenderer* renderer, GameWorld* world)
glDrawBuffers(1, buffers);
r->setUniform(waterProg, "time", world->getGameTime());
r->setUniform(waterProg, "waveParams", glm::vec2(WATER_SCALE, WATER_HEIGHT));
auto ivp = glm::inverse(r->getSceneData().projection * r->getSceneData().view);
r->setUniform(waterProg, "waveParams",
glm::vec2(WATER_SCALE, WATER_HEIGHT));
auto ivp =
glm::inverse(r->getSceneData().projection * r->getSceneData().view);
r->setUniform(waterProg, "inverseVP", ivp);
wdp.count = gridGeom.getCount();

View File

@ -1,7 +1,7 @@
#pragma once
#include <rw/types.hpp>
#include <render/OpenGLRenderer.hpp>
#include <rw/types.hpp>
class GameRenderer;
class GameWorld;
@ -9,8 +9,7 @@ class GameWorld;
/**
* Implements the rendering routines for drawing the sea water.
*/
class WaterRenderer
{
class WaterRenderer {
public:
WaterRenderer(GameRenderer* renderer);
~WaterRenderer();
@ -23,7 +22,8 @@ public:
* This data is used to create the internal stencil mask for clipping
* the water rendering.
*/
void setWaterTable(float* waterHeights, unsigned int nHeights, uint8_t* tiles, unsigned int nTiles);
void setWaterTable(float* waterHeights, unsigned int nHeights,
uint8_t* tiles, unsigned int nTiles);
void setDataTexture(GLuint fbBinding, GLuint dataTexture);
@ -31,6 +31,7 @@ public:
* Render the water using the currently active render state
*/
void render(GameRenderer* renderer, GameWorld* world);
private:
Renderer::ShaderProgram* waterProg;
Renderer::ShaderProgram* maskProg;