Browse Source

more cygnet stuff

fix/style
Martin Dørum 3 years ago
parent
commit
3980a87496

+ 2
- 1
libcygnet/CMakeLists.txt View File

@@ -1,9 +1,10 @@
add_library(libcygnet SHARED
src/Context.cc
src/Program.cc
src/GlWrappers.cc
src/Renderer.cc
src/shaders.cc
src/TileAtlas.cc
src/util.cc
src/Window.cc)
target_include_directories(libcygnet
PUBLIC "include"

libcygnet/include/cygnet/Program.h → libcygnet/include/cygnet/GlWrappers.h View File

@@ -23,10 +23,10 @@ public:
GlShader(Type type, const char *source);
~GlShader();

GlID id() const { return id_; }
GLuint id() const { return id_; }

private:
GlID id_;
GLuint id_;
};

class GlVxShader: public GlShader {
@@ -47,18 +47,35 @@ public:
~GlProgram();

void use();
GlID id() const { return id_; }
GLuint id() const { return id_; }

protected:

GlLoc attribLoc(const char *name);
GlLoc uniformLoc(const char *name);
GLint attribLoc(const char *name);
GLint uniformLoc(const char *name);

private:
void addShader(const GlShader &shader);
void link();

GlID id_;
GLuint id_;
};

class GlTexture {
public:
GlTexture();

void bind();
void upload(GLsizei width, GLsizei height, void *data,
GLenum format, GLenum type);
GLuint id() { return id_; }
int width() { return w_; }
int height() { return h_; }

private:
GLuint id_;
int w_;
int h_;
};

}

+ 3
- 1
libcygnet/include/cygnet/Renderer.h View File

@@ -11,9 +11,11 @@ public:
Renderer();
~Renderer();

void clear();
void draw();

void registerTileTexture(size_t tileId, const void *data, size_t len);
void uploadTileTexture();

private:
std::unique_ptr<RendererState> state_;
};

+ 1
- 0
libcygnet/include/cygnet/TileAtlas.h View File

@@ -12,6 +12,7 @@ public:
~TileAtlas();

void addTile(size_t tileId, const void *data, size_t len);
const unsigned char *getImage(size_t *w, size_t *h);

private:
std::unique_ptr<AtlasState> state_;

+ 10
- 31
libcygnet/include/cygnet/util.h View File

@@ -1,13 +1,16 @@
#pragma once

#include <stdexcept>
#include <SDL_opengles2.h>
#include <stdint.h>
#include <SDL.h>

namespace Cygnet {

using GlID = uint32_t;
using GlLoc = int32_t;
// I don't want every use of Cygnet to drag in OpenGL headers.
using GLint = int32_t;
using GLuint = uint32_t;
using GLsizei = int32_t;
using GLenum = uint32_t;

struct SDLError: public std::exception {
SDLError(std::string msg): message(std::move(msg)) {}
@@ -15,37 +18,13 @@ struct SDLError: public std::exception {
std::string message;
};

struct GLError: public std::exception {
GLError(std::string msg): message(std::move(msg)) {}
struct GlError: public std::exception {
GlError(std::string msg): message(std::move(msg)) {}
const char *what() const noexcept override { return message.c_str(); }
std::string message;
};

inline const char *glErrorString(int err) {
#define errcase(x) case x: return #x
switch (err) {
errcase(GL_NO_ERROR);
errcase(GL_INVALID_ENUM);
errcase(GL_INVALID_VALUE);
errcase(GL_INVALID_OPERATION);
errcase(GL_INVALID_FRAMEBUFFER_OPERATION);
errcase(GL_OUT_OF_MEMORY);
default: return "(unknown)";
}
#undef errcase
}

inline void sdlCheck(bool ok) {
if (!ok) {
throw SDLError(SDL_GetError());
}
}

inline void glCheck() {
GLenum err = glGetError();
if (err != GL_NO_ERROR) {
throw GLError(glErrorString(err));
}
}
void sdlCheck(bool ok);
void glCheck();

}

libcygnet/src/Program.cc → libcygnet/src/GlWrappers.cc View File

@@ -1,4 +1,4 @@
#include "Program.h"
#include "GlWrappers.h"

#include <SDL_opengles2.h>
#include <iostream>
@@ -68,11 +68,11 @@ void GlProgram::addShader(const GlShader &shader) {
glCheck();
}

GlLoc GlProgram::attribLoc(const char *name) {
GLint GlProgram::attribLoc(const char *name) {
return glGetAttribLocation(id_, name);
}

GlLoc GlProgram::uniformLoc(const char *name) {
GLint GlProgram::uniformLoc(const char *name) {
return glGetUniformLocation(id_, name);
}

@@ -97,4 +97,27 @@ void GlProgram::link() {
}
}

GlTexture::GlTexture() {
glGenTextures(1, &id_);
glCheck();
}

void GlTexture::bind() {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, id_);
}

void GlTexture::upload(GLsizei width, GLsizei height, void *data,
GLenum format, GLenum type) {
w_ = width;
h_ = height;
bind();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, type, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glCheck();
}

}

+ 23
- 6
libcygnet/src/Renderer.cc View File

@@ -1,7 +1,9 @@
#include "Renderer.h"

#include <SDL_opengles2.h>

#include "shaders.h"
#include "Program.h"
#include "GlWrappers.h"
#include "TileAtlas.h"
#include "util.h"

@@ -10,16 +12,16 @@ namespace Cygnet {
struct TexturedProg: public GlProgram {
using GlProgram::GlProgram;

GlLoc position = attribLoc("position");
GlLoc texCoord = attribLoc("texCoord");
GlLoc tex = uniformLoc("tex");
GLint position = attribLoc("position");
GLint texCoord = attribLoc("texCoord");
GLint tex = uniformLoc("tex");
};

struct SolidColorProg: public GlProgram {
using GlProgram::GlProgram;

GlLoc position = attribLoc("position");
GlLoc color = uniformLoc("color");
GLint position = attribLoc("position");
GLint color = uniformLoc("color");
};

struct RendererState {
@@ -32,10 +34,25 @@ struct RendererState {
SolidColorProg solidColorProg{basicVx, solidColorFr};

TileAtlas atlas;
GlTexture atlasTex;
};

Renderer::Renderer(): state_(std::make_unique<RendererState>()) {}

Renderer::~Renderer() = default;

void Renderer::draw() {
state_->texturedProg.use();
}

void Renderer::registerTileTexture(size_t tileId, const void *data, size_t len) {
state_->atlas.addTile(tileId, data, len);
}

void Renderer::uploadTileTexture() {
size_t w, h;
const unsigned char *data = state_->atlas.getImage(&w, &h);
state_->atlasTex.upload(w, h, (void *)data, GL_RGBA, GL_UNSIGNED_BYTE);
}

}

+ 6
- 0
libcygnet/src/TileAtlas.cc View File

@@ -56,4 +56,10 @@ void TileAtlas::addTile(size_t tileId, const void *data, size_t len) {
}
}

const unsigned char *TileAtlas::getImage(size_t *w, size_t *h) {
*w = state_->width * SwanCommon::TILE_SIZE;
*h = state_->height * SwanCommon::TILE_SIZE;
return state_->data.data();
}

}

+ 34
- 0
libcygnet/src/util.cc View File

@@ -0,0 +1,34 @@
#include "util.h"

#include <SDL_opengles2.h>

namespace Cygnet {

inline const char *glErrorString(int err) {
#define errcase(x) case x: return #x
switch (err) {
errcase(GL_NO_ERROR);
errcase(GL_INVALID_ENUM);
errcase(GL_INVALID_VALUE);
errcase(GL_INVALID_OPERATION);
errcase(GL_INVALID_FRAMEBUFFER_OPERATION);
errcase(GL_OUT_OF_MEMORY);
default: return "(unknown)";
}
#undef errcase
}

void sdlCheck(bool ok) {
if (!ok) {
throw SDLError(SDL_GetError());
}
}

void glCheck() {
GLenum err = glGetError();
if (err != GL_NO_ERROR) {
throw GlError(glErrorString(err));
}
}

}

+ 11
- 0
src/cygnet-test.cc View File

@@ -1,7 +1,9 @@
#include <cygnet/Context.h>
#include <cygnet/Window.h>
#include <cygnet/Renderer.h>
#include <swan-common/constants.h>

#include <stdint.h>
#include <SDL.h>

int main() {
@@ -9,6 +11,13 @@ int main() {
Cygnet::Window win("Cygnet Test", 640, 480);
Cygnet::Renderer rnd;

uint32_t img[SwanCommon::TILE_SIZE * SwanCommon::TILE_SIZE];
for (size_t i = 0; i < sizeof(img) / sizeof(*img); ++i) {
img[i] = 0xff00aaff;
}
rnd.registerTileTexture(0, img, sizeof(img));
rnd.uploadTileTexture();

while (true) {
SDL_Event evt;
while (SDL_PollEvent(&evt)) {
@@ -18,6 +27,8 @@ int main() {
}
}

win.clear();
rnd.draw();
win.flip();
}


Loading…
Cancel
Save