Browse Source

render geometry to a texture

feature/meson
Martin Dørum 3 years ago
parent
commit
bc1d0e4db7
4 changed files with 136 additions and 4 deletions
  1. 3
    0
      libcygnet/include/cygnet/shaders.h
  2. 108
    2
      libcygnet/src/Renderer.cc
  3. 2
    2
      libcygnet/src/Window.cc
  4. 23
    0
      libcygnet/src/shaders.cc

+ 3
- 0
libcygnet/include/cygnet/shaders.h View File

extern const char *rectVx; extern const char *rectVx;
extern const char *rectFr; extern const char *rectFr;


extern const char *blendVx;
extern const char *blendFr;

} }

+ 108
- 2
libcygnet/src/Renderer.cc View File

} }
}; };


struct BlendProg: public GlProgram {
template<typename... T>
BlendProg(const T &... shaders): GlProgram(shaders...) { init(); }
~BlendProg() { deinit(); }

GLint vertex = attribLoc("vertex");
GLint texCoord = attribLoc("texCoord");
GLint tex = uniformLoc("tex");

GLuint vbo;

static constexpr GLfloat vertexes[] = {
-1.0f, -1.0f, 0.0f, 0.0f, // pos 0: top left
-1.0f, 1.0f, 0.0f, 1.0f, // pos 1: bottom left
1.0f, 1.0f, 1.0f, 1.0f, // pos 2: bottom right
1.0f, 1.0f, 1.0f, 1.0f, // pos 2: bottom right
1.0f, -1.0f, 1.0f, 0.0f, // pos 3: top right
-1.0f, -1.0f, 0.0f, 0.0f, // pos 0: top left
};

void enable() {
glUseProgram(id());
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(vertex, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void *)0);
glVertexAttribPointer(texCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void *)(2 * sizeof(GLfloat)));
glEnableVertexAttribArray(vertex);
glEnableVertexAttribArray(texCoord);
glCheck();

glUniform1i(tex, 0);
glCheck();
}

void disable() {
glDisableVertexAttribArray(vertex);
glCheck();
}

void init() {
glGenBuffers(1, &vbo);
glCheck();

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), vertexes, GL_STATIC_DRAW);
glCheck();
}

void deinit() {
glDeleteBuffers(1, &vbo);
glCheck();
}
};

struct RendererState { struct RendererState {
GlVxShader chunkVx{Shaders::chunkVx}; GlVxShader chunkVx{Shaders::chunkVx};
GlFrShader chunkFr{Shaders::chunkFr}; GlFrShader chunkFr{Shaders::chunkFr};
GlFrShader spriteFr{Shaders::spriteFr}; GlFrShader spriteFr{Shaders::spriteFr};
GlVxShader rectVx{Shaders::rectVx}; GlVxShader rectVx{Shaders::rectVx};
GlFrShader rectFr{Shaders::rectFr}; GlFrShader rectFr{Shaders::rectFr};
GlVxShader blendVx{Shaders::blendVx};
GlFrShader blendFr{Shaders::blendFr};


ChunkProg chunkProg{chunkVx, chunkFr}; ChunkProg chunkProg{chunkVx, chunkFr};
ChunkShadowProg chunkShadowProg{chunkShadowVx, chunkShadowFr}; ChunkShadowProg chunkShadowProg{chunkShadowVx, chunkShadowFr};
TileProg tileProg{tileVx, tileFr}; TileProg tileProg{tileVx, tileFr};
SpriteProg spriteProg{spriteVx, spriteFr}; SpriteProg spriteProg{spriteVx, spriteFr};
RectProg rectProg{rectVx, rectFr}; RectProg rectProg{rectVx, rectFr};
BlendProg blendProg{blendVx, blendFr};


GLuint atlasTex;
SwanCommon::Vec2i screenSize;
GLuint offscreenFramebuffer = 0;
GLuint offscreenTex = 0;
GLuint atlasTex = 0;
SwanCommon::Vec2 atlasTexSize; SwanCommon::Vec2 atlasTexSize;
}; };


Renderer::Renderer(): state_(std::make_unique<RendererState>()) { Renderer::Renderer(): state_(std::make_unique<RendererState>()) {
glGenTextures(1, &state_->atlasTex); glGenTextures(1, &state_->atlasTex);
glCheck(); glCheck();

glGenTextures(1, &state_->offscreenTex);
glCheck();
} }


Renderer::~Renderer() = default;
Renderer::~Renderer() {
glDeleteFramebuffers(1, &state_->offscreenFramebuffer);
glDeleteTextures(1, &state_->offscreenFramebuffer);
glDeleteTextures(1, &state_->atlasTex);
}


void Renderer::draw(const RenderCamera &cam) { void Renderer::draw(const RenderCamera &cam) {
Mat3gf camMat; Mat3gf camMat;
auto &tileProg = state_->tileProg; auto &tileProg = state_->tileProg;
auto &spriteProg = state_->spriteProg; auto &spriteProg = state_->spriteProg;
auto &rectProg = state_->rectProg; auto &rectProg = state_->rectProg;
auto &blendProg = state_->blendProg;

if (state_->screenSize != cam.size) {
state_->screenSize = cam.size;
glBindTexture(GL_TEXTURE_2D, state_->offscreenTex);
glCheck();
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, cam.size.x, cam.size.y, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glCheck();

glGenFramebuffers(1, &state_->offscreenFramebuffer);
glCheck();
glBindFramebuffer(GL_FRAMEBUFFER, state_->offscreenFramebuffer);
glCheck();
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
state_->offscreenTex, 0);
glCheck();
}

glBindFramebuffer(GL_FRAMEBUFFER, state_->offscreenFramebuffer);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
state_->offscreenTex, 0);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);


{ {
chunkProg.enable(); chunkProg.enable();
rectProg.disable(); rectProg.disable();
} }


glBindFramebuffer(GL_FRAMEBUFFER, 0);

{
blendProg.enable();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, state_->offscreenTex);
glDrawArrays(GL_TRIANGLES, 0, 6);
glCheck();
blendProg.disable();
}

{ {
chunkShadowProg.enable(); chunkShadowProg.enable();
glUniformMatrix3fv(chunkShadowProg.camera, 1, GL_TRUE, camMat.data()); glUniformMatrix3fv(chunkShadowProg.camera, 1, GL_TRUE, camMat.data());

+ 2
- 2
libcygnet/src/Window.cc View File

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);


SDL_GL_SetSwapInterval(1); SDL_GL_SetSwapInterval(1);
state_->window = SDL_CreateWindow(name, state_->window = SDL_CreateWindow(name,

+ 23
- 0
libcygnet/src/shaders.cc View File

} }
)glsl"; )glsl";


const char *blendVx = R"glsl(
precision mediump float;
attribute vec2 vertex;
attribute vec2 texCoord;
varying vec2 v_texCoord;

void main() {
gl_Position = vec4(vertex.xy, 0, 1);
v_texCoord = texCoord;
}
)glsl";

const char *blendFr = R"glsl(
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D tex;

void main() {
//gl_FragColor = vec4(v_texCoord.x, v_texCoord.y, 0, 1);
gl_FragColor = texture2D(tex, v_texCoord);
}
)glsl";

} }

Loading…
Cancel
Save