Browse Source

move base class out, text shader supports, checkGLState() refactor/cleanup

master
Odilitime 5 years ago
parent
commit
46e03cfef1
  1. 531
      src/interfaces/graphical/renderers/glfw/opengl.cpp
  2. 80
      src/interfaces/graphical/renderers/glfw/opengl.h

531
src/interfaces/graphical/renderers/glfw/opengl.cpp

@ -1,46 +1,43 @@ @@ -1,46 +1,43 @@
#include "opengl.h"
#include "../../../../browser.h"
#include <iostream>
#include <cmath>
#include <cstring> // for memset
// maybe change to return std::pair<GLuint, GLuint>
// for creating new windows
extern std::unique_ptr<Browser> browser;
inline void checkGLState(std::string whereWhat) {
GLenum glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << whereWhat << " - not ok: " << glErr << std::endl;
}
}
// maybe change to return std::pair<GLuint, GLuint>
// with the renderer and version?
bool initGL() {
const GLubyte *renderer = glGetString(GL_RENDERER);
const GLubyte *version = glGetString(GL_VERSION);
std::cout << "Renderer: " << renderer << std::endl;
std::cout << "Version: " << version << std::endl;
checkGLState("opengl::initGL - start");
glEnable(GL_BLEND); checkGLState("opengl::initGL - glEnable blend");
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); checkGLState("opengl::initGL - glBlendFunc");
GLenum glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::initGL - start - not ok: " << glErr << std::endl;
}
unsigned int clearColor = 0xCCCCCCCC;
float r = (static_cast<float>((clearColor >> 24) & 0xFF)) / 255;
float g = (static_cast<float>((clearColor >> 16) & 0xFF)) / 255;
float b = (static_cast<float>((clearColor >> 8) & 0xFF)) / 255;
float a = (static_cast<float>((clearColor >> 0) & 0xFF)) / 255;
glEnable(GL_BLEND);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::initGL - glEnable blend - not ok: " << glErr << std::endl;
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::initGL - glBlendFunc - not ok: " << glErr << std::endl;
}
glClearColor(0.8f, 0.8f, 0.8f, 0.8f);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::initGL - glClearColor - not ok: " << glErr << std::endl;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::initGL - glTexParameteri min - not ok: " << glErr << std::endl;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::initGL - glTexParameteri mag - not ok: " << glErr << std::endl;
}
//glClearColor(0.8f, 0.8f, 0.8f, 0.8f);
glClearColor(r, g, b, a); checkGLState("opengl::initGL - glClearColor");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); checkGLState("opengl::initGL - glTexParameteri min");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); checkGLState("opengl::initGL - glTexParameteri mag");
//std::cout << "OpenGL is set up" << std::endl;
@ -58,7 +55,7 @@ bool initGLEW() { @@ -58,7 +55,7 @@ bool initGLEW() {
}
// only called once
bool opengl::initialize() {
bool OpenGL::initialize() {
if (!glfwInit()) {
std::cout << "Could not initialize GLFW" << std::endl;
return false;
@ -70,13 +67,12 @@ bool opengl::initialize() { @@ -70,13 +67,12 @@ bool opengl::initialize() {
glfwSetErrorCallback([](int error, const char* description) {
std::cout << "glfw error [" << error << "]:" << description << std::endl;
});
// I don't think you can init GLEW without a window
// I don't think you can init GLEW without a window
return true;
}
opengl_window_handle * opengl::createWindow(std::string title, Rect *position, unsigned int flags) {
OpenGLWindowHandle * OpenGL::createWindow(std::string title, Rect *position, unsigned int flags) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
@ -84,7 +80,7 @@ opengl_window_handle * opengl::createWindow(std::string title, Rect *position, u @@ -84,7 +80,7 @@ opengl_window_handle * opengl::createWindow(std::string title, Rect *position, u
int windowWidth = position->w;
int windowHeight = position->h;
opengl_window_handle *win = new opengl_window_handle();
OpenGLWindowHandle *win = new OpenGLWindowHandle();
win->width = position->w;
win->height = position->h;
GLFWwindow *window = glfwCreateWindow(windowWidth, windowHeight, title.c_str(), nullptr, nullptr);
@ -116,58 +112,135 @@ opengl_window_handle * opengl::createWindow(std::string title, Rect *position, u @@ -116,58 +112,135 @@ opengl_window_handle * opengl::createWindow(std::string title, Rect *position, u
// configure opengl coordinates
//std::cout << "position: " << position->w << "x" << position->h << std::endl;
glViewport(0, 0, static_cast<GLsizei>(position->w), static_cast<GLsizei>(position->h));
GLenum glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - glViewport - not ok: " << gluErrorString(glErr) << std::endl;
}
glViewport(0, 0, static_cast<GLsizei>(position->w), static_cast<GLsizei>(position->h)); checkGLState("OpenGL::createWindow - glViewport");
// replace first parameter of all these callbacks with our window object instead of a GLFWwindow
glfwSetWindowUserPointer(win->window, win);
// set up event callbacks
// window events
glfwSetFramebufferSizeCallback(window, [](GLFWwindow *win, int width, int height) {
glViewport(0, 0, width, height);
});
glfwSetWindowSizeCallback(window, [](GLFWwindow *win, int width, int height) {
OpenGLWindowHandle *thiz = reinterpret_cast<OpenGLWindowHandle*>(glfwGetWindowUserPointer(win));
if (thiz->onResize) {
thiz->onResize(width, height);
}
});
// mouse events
glfwSetCursorPosCallback(window, [](GLFWwindow *win, double xPos, double yPos) {
OpenGLWindowHandle *thiz = reinterpret_cast<OpenGLWindowHandle*>(glfwGetWindowUserPointer(win));
//std::cout << "Window::Window:onMousemove - at " << static_cast<int>(xPos) << "," << static_cast<int>(yPos) << std::endl;
thiz->cursorX = xPos;
thiz->cursorY = yPos;
if (xPos < 0 || yPos < 0) return;
if (xPos > thiz->width || yPos > thiz->height) return;
// p. much worthless on double
/*
static double lx = 0;
static double ly = 0;
if (lx == xPos && ly == yPos) {
return;
}
lx = xPos;
ly = yPos;
std::cout << "Window::Window:onMousemove - noCache" << std::endl;
*/
//std::cout << "Window::Window:onMousemove - onWheel" << std::endl;
if (thiz->onMouseMove) {
thiz->onMouseMove(xPos, yPos);
}
});
glfwSetScrollCallback(window, [](GLFWwindow *win, double xOffset, double yOffset) {
OpenGLWindowHandle *thiz = reinterpret_cast<OpenGLWindowHandle*>(glfwGetWindowUserPointer(win));
//std::cout << "glfwSetScrollCallback " << yOffset << " int" << (int)(yOffset * 10) << std::endl;
if (thiz->onWheel) {
thiz->onWheel(xOffset * 10, yOffset * 10);
}
});
glfwSetMouseButtonCallback(window, [](GLFWwindow *win, int button, int action, int mods) {
OpenGLWindowHandle *thiz = reinterpret_cast<OpenGLWindowHandle*>(glfwGetWindowUserPointer(win));
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
//std::cout << "left press" << std::endl;
if (thiz->onMouseUp) {
thiz->onMouseDown(thiz->cursorX, thiz->cursorY);
}
}
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) {
//std::cout << "left release" << std::endl;
if (thiz->onMouseUp) {
thiz->onMouseUp(thiz->cursorX, thiz->cursorY);
}
}
});
// keyboard events
// works with utf-32 and os keyboard layout but we'll lkeep the low level for now
glfwSetCharCallback(window, [](GLFWwindow* win, unsigned int codepoint) {
OpenGLWindowHandle *thiz = reinterpret_cast<OpenGLWindowHandle*>(glfwGetWindowUserPointer(win));
//std::cout << "OpenGL::glfwSetCharCallback - codepoint: " << codepoint << std::endl;
// should be used for inputComponent
if (thiz->onKeyPress) {
thiz->onKeyPress(codepoint);
}
});
glfwSetKeyCallback(window, [](GLFWwindow *win, int key, int scancode, int action, int mods) {
OpenGLWindowHandle *thiz = reinterpret_cast<OpenGLWindowHandle*>(glfwGetWindowUserPointer(win));
if (action == GLFW_RELEASE) {
if (thiz->onKeyUp) {
thiz->onKeyUp(key, scancode, mods);
}
}
if (action == GLFW_REPEAT) {
//thiz->ui->onKeyRepeat(key, scancode, mods);
//thiz->ui->onKeyPress(key, scancode, action, mods);
if (thiz->onKeyRepeat) {
thiz->onKeyRepeat(key, scancode, mods);
}
}
if (action == GLFW_PRESS) {
//thiz->ui->onKeyDown(key, scancode, mods);
//thiz->ui->onKeyPress(key, scancode, action, mods);
if (thiz->onKeyRepeat) {
thiz->onKeyRepeat(key, scancode, mods);
}
}
});
/*
// Change to the projection matrix, reset the matrix and set up orthagonal projection (i.e. 2D)
glMatrixMode(GL_PROJECTION);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - glMatrixMode - not ok: " << gluErrorString(glErr) << std::endl;
std::cout << "OpenGL::createWindow - glMatrixMode - not ok: " << gluErrorString(glErr) << std::endl;
}
glLoadIdentity();
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - glLoadIdentity - not ok: " << gluErrorString(glErr) << std::endl;
std::cout << "OpenGL::createWindow - glLoadIdentity - not ok: " << gluErrorString(glErr) << std::endl;
}
glOrtho(0, position->w, position->h, 0, 0, 1); // Paramters: left, right, bottom, top, near, far
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - glOrtho - not ok: " << gluErrorString(glErr) << std::endl;
std::cout << "OpenGL::createWindow - glOrtho - not ok: " << gluErrorString(glErr) << std::endl;
}
*/
// set up box shader
GLuint elementBufferObject = 0;
glGenVertexArrays(1, &win->vertexArrayObject);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - genVAO - not ok: " << glErr << std::endl;
}
glBindVertexArray(win->vertexArrayObject);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - bindVAO - not ok: " << glErr << std::endl;
}
glGenBuffers(1, &elementBufferObject);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - genEBO - not ok: " << glErr << std::endl;
}
glGenVertexArrays(1, &win->vertexArrayObjectBox); checkGLState("OpenGL::createWindow - genVAOBox");
glBindVertexArray(win->vertexArrayObjectBox); checkGLState("OpenGL::createWindow - bindVAOBox");
glGenBuffers(1, &elementBufferObject); checkGLState("OpenGL::createWindow - genEBO");
// we may need the VBO here...
glGenBuffers(1, &win->vertexBufferObject);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - genVBO - not ok: " << glErr << std::endl;
}
glGenBuffers(1, &win->vertexBufferObjectBox); checkGLState("OpenGL::createWindow - genVBOBox");
float vertices[20] = {
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
@ -175,84 +248,72 @@ opengl_window_handle * opengl::createWindow(std::string title, Rect *position, u @@ -175,84 +248,72 @@ opengl_window_handle * opengl::createWindow(std::string title, Rect *position, u
0.0f, 0.0f, 0.0f, 0.0f, 0.0f
};
glBindBuffer(GL_ARRAY_BUFFER, win->vertexBufferObject); // selects buffer
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - bindVBO - not ok: " << glErr << std::endl;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // writes buffer
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - bufVBO - not ok: " << glErr << std::endl;
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferObject);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - bindEBO - not ok: " << glErr << std::endl;
}
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(this->indices), this->indices, GL_STATIC_DRAW);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - buffEBO - not ok: " << glErr << std::endl;
}
// select buffer
glBindBuffer(GL_ARRAY_BUFFER, win->vertexBufferObjectBox); checkGLState("OpenGL::createWindow - bindVBO");
// write buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); checkGLState("OpenGL::createWindow - bufVBO");
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferObject); checkGLState("OpenGL::createWindow - bindEBO");
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(this->indices), this->indices, GL_STATIC_DRAW); checkGLState("OpenGL::createWindow - buffEBO");
// attribute 0 = 3 floats
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), nullptr);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - glVertexAttribPointer0 - not ok: " << glErr << std::endl;
}
glEnableVertexAttribArray(0);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - glEnableVertexAttribArray0 - not ok: " << glErr << std::endl;
}
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), nullptr); checkGLState("OpenGL::createWindow - glVertexAttribPointer0");
glEnableVertexAttribArray(0); checkGLState("OpenGL::createWindow - glEnableVertexAttribArray0");
// attribute 1 = 2 floats, at 3
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), reinterpret_cast<void*>(3 * sizeof(float)));
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - glVertexAttribPointer1 - not ok: " << glErr << std::endl;
}
glEnableVertexAttribArray(1);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createWindow - glEnableVertexAttribArray1 - not ok: " << glErr << std::endl;
}
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), reinterpret_cast<void*>(3 * sizeof(float))); checkGLState("OpenGL::createWindow - glVertexAttribPointer1");
glEnableVertexAttribArray(1); checkGLState("OpenGL::createWindow - glEnableVertexAttribArray1");
//glBindVertexArray(0);
// set up text shader
glGenVertexArrays(1, &win->vertexArrayObjectText); checkGLState("OpenGL::createWindow - genVAOText");
glBindVertexArray(win->vertexArrayObjectText); checkGLState("OpenGL::createWindow - bindVBOText");
// vBO
glGenBuffers(1, &win->vertexBufferObjectText); checkGLState("OpenGL::createWindow - genVBOText");
glBindBuffer(GL_ARRAY_BUFFER, win->vertexBufferObjectText); checkGLState("OpenGL::createWindow - bindVBOText");
std::unique_ptr<float[]> vertices2 = std::make_unique<float[]>(36); // upload garbage for now
glBufferData(GL_ARRAY_BUFFER, ((3 + 4 + 2) * 4) * sizeof(float), vertices2.get(), GL_STATIC_DRAW); checkGLState("OpenGL::createWindow - buffVBOText");
// eBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferObject); checkGLState("OpenGL::createWindow - bindVBOText");
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, (3 + 4 + 2) * sizeof(float), nullptr); checkGLState("OpenGL::createWindow - glVertexAttribPointerText0");
glEnableVertexAttribArray(0); checkGLState("OpenGL::createWindow - glEnableVertexAttribArrayText0");
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, (3 + 4 + 2) * sizeof(float), reinterpret_cast<void*>(3 * sizeof(float))); checkGLState("opengl::createWindow - glVertexAttribPointerText1");
glEnableVertexAttribArray(1); checkGLState("OpenGL::createWindow - glEnableVertexAttribArrayText1");
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, (3 + 4 + 2) * sizeof(float), reinterpret_cast<void*>(7 * sizeof(float))); checkGLState("opengl::createWindow - glVertexAttribPointerText2");
glEnableVertexAttribArray(2); checkGLState("OpenGL::createWindow - glEnableVertexAttribArrayText2");
glBindVertexArray(0);
return win;
}
void opengl_window_handle::clear() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLenum glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::clear - not ok: " << glErr << std::endl;
}
void OpenGLWindowHandle::clear() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); checkGLState("OpenGLWindowHandle::clear");
}
void opengl_window_handle::swapBuffers() {
glfwSwapBuffers(this->window);
GLenum glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::swapBuffers - not ok: " << glErr << std::endl;
}
void OpenGLWindowHandle::swapBuffers() {
glfwSwapBuffers(this->window); checkGLState("OpenGLWindowHandle::swapBuffers");
}
opengl_texture_handle* opengl_window_handle::createTexture(unsigned char* texture, GLsizei w, GLsizei h) {
opengl_texture_handle *handle=new opengl_texture_handle;
OpenGLTexture* OpenGLWindowHandle::createSprite(unsigned char* texture, GLsizei w, GLsizei h) {
OpenGLTexture *handle = new OpenGLTexture;
glGenTextures(1, &handle->number);
// make sure texture size is a power of two
size_t potw = pow(2, ceil(log(w) / log(2)));
size_t poth = pow(2, ceil(log(h) / log(2)));
// FIXME: need to dynamically allocate for c++
unsigned char data[16384][16384][4];
memset(data, 0, poth * potw * 4);
//unsigned char data[16384][16384][4];
//unsigned char ***image = allocate_dynamic_bitmap(poth, potw, 4);
unsigned char *data = (unsigned char *)malloc(sizeof(unsigned char) * poth * potw * 4);
//memset(data, 0, poth * potw * 4);
//memset(image, 0, poth * potw * 4);
// unflip texture
unsigned int loadWidth = static_cast<unsigned int>(w);
unsigned int loadHeight = static_cast<unsigned int>(h);
@ -263,21 +324,46 @@ opengl_texture_handle* opengl_window_handle::createTexture(unsigned char* textur @@ -263,21 +324,46 @@ opengl_texture_handle* opengl_window_handle::createTexture(unsigned char* textur
size_t read = ((px * 4) + (py * 4 * loadWidth)) + i;
unsigned char val = texture[read];
size_t ypos = potw - 1 - py; // flip y
data[ypos][px][i] = val;
size_t write = ((px * 4) + (ypos * 4 * potw)) + i;
data[write] = val;
//data[ypos][px][i] = val;
}
}
}
// upload to video card
// select
glBindTexture(GL_TEXTURE_2D, handle->number); checkGLState("OpenGLWindowHandle::createSprite - bind");
// upload
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<int>(potw), static_cast<int>(poth), 0, GL_RGBA, GL_UNSIGNED_BYTE, data); checkGLState("OpenGLWindowHandle::createSprite - upload");
// process
glGenerateMipmap(GL_TEXTURE_2D); checkGLState("OpenGLWindowHandle::createSprite - process");
// unselect
glBindTexture(GL_TEXTURE_2D, 0); checkGLState("OpenGLWindowHandle::createSprite - unselect");
return handle;
}
OpenGLTexture* OpenGLWindowHandle::createTextSprite(unsigned char *texture, GLsizei w, GLsizei h, textureMap &textureMap) {
OpenGLTexture *handle = new OpenGLTexture;
glGenTextures(1, &handle->number); checkGLState("OpenGLWindowHandle::createTextureFromColor - glGenTextures");
// upload
glBindTexture(GL_TEXTURE_2D, handle->number); // select
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<int>(potw), static_cast<int>(poth), 0, GL_RGBA, GL_UNSIGNED_BYTE, data); // upload
glGenerateMipmap(GL_TEXTURE_2D); // process it
glBindTexture(GL_TEXTURE_2D, 0); // unselect
glBindTexture(GL_TEXTURE_2D, handle->number); checkGLState("OpenGLWindowHandle::createTextureFromColor - bindTexture");
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, texture); checkGLState("OpenGLWindowHandle::createTextureFromColor - glTexImage2D");
glGenerateMipmap(GL_TEXTURE_2D); checkGLState("OpenGLWindowHandle::createTextureFromColor - glGenerateMipmap");
glBindTexture(GL_TEXTURE_2D, 0); checkGLState("OpenGLWindowHandle::createTextureFromColor - unBindTex");
// I flipped this maybe due to coords...
handle->s0 = textureMap.map[0];
handle->t0 = textureMap.map[1];
handle->s1 = textureMap.map[2];
handle->t1 = textureMap.map[3];
return handle;
}
opengl_texture_handle* opengl_window_handle::createTextureFromColor(const unsigned int hexColor) {
OpenGLTexture* OpenGLWindowHandle::createSpriteFromColor(const unsigned int hexColor) {
//std::cout << "createTextureFromColor: " << hexColor << std::endl;
unsigned char texture[1][1][4];
texture[0][0][0]=(hexColor >> 24) & 0xFF;
@ -287,34 +373,14 @@ opengl_texture_handle* opengl_window_handle::createTextureFromColor(const unsign @@ -287,34 +373,14 @@ opengl_texture_handle* opengl_window_handle::createTextureFromColor(const unsign
//std::cout << "opengl::createTextureFromColor R: " << (int)texture[0][0][0] << " G: " << (int)texture[0][0][1] << " B: " << (int)texture[0][0][2] << " A: " << (int)texture[0][0][3] << std::endl;
// I can't figure out how to pass data to opengl::createTexture
// so we'll just do this for now
opengl_texture_handle *handle=new opengl_texture_handle;
OpenGLTexture *handle=new OpenGLTexture;
glGenTextures(1, &handle->number);
GLenum glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createTextureFromColor - glGenTextures - not ok: " << gluErrorString(glErr) << std::endl;
}
glGenTextures(1, &handle->number); checkGLState("OpenGLWindowHandle::createTextureFromColor - glGenTextures");
glBindTexture(GL_TEXTURE_2D, handle->number); checkGLState("OpenGLWindowHandle::createTextureFromColor - glBindTexture");
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture); checkGLState("OpenGLWindowHandle::createTextureFromColor - glTexImage2D");
glGenerateMipmap(GL_TEXTURE_2D); checkGLState("OpenGLWindowHandle::createTextureFromColor - glGenerateMipmap");
glBindTexture(GL_TEXTURE_2D, 0); checkGLState("OpenGLWindowHandle::createTextureFromColor - unselect");
glBindTexture(GL_TEXTURE_2D, handle->number); // select
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createTextureFromColor - bindTexture - not ok: " << glErr << std::endl;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture); // upload
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createTextureFromColor - glTexImage2D - not ok: " << glErr << std::endl;
}
glGenerateMipmap(GL_TEXTURE_2D); // process it
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createTextureFromColor - glGenerateMipmap - not ok: " << glErr << std::endl;
}
glBindTexture(GL_TEXTURE_2D, 0); // unselect
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "opengl::createTextureFromColor - unBindTex - not ok: " << glErr << std::endl;
}
return handle;
}
@ -323,35 +389,32 @@ opengl_texture_handle* opengl_window_handle::createTextureFromColor(const unsign @@ -323,35 +389,32 @@ opengl_texture_handle* opengl_window_handle::createTextureFromColor(const unsign
// converts 0-1 to screen
// but centered
void pointToViewport(float &rawX, float &rawY, size_t windowWidth, size_t windowHeight) {
//std::cout << "Component::pointToViewport - notBoundToPage converting from " << static_cast<int>(rawX) << "," << static_cast<int>(rawY) << std::endl;
//std::cout << "BoundToPage using " << screenWidth << "x" << screenHeight << std::endl;
rawX = ((rawX / windowWidth) * 2) - 1;
rawY = ((rawY / windowHeight) * 2) - 1;
//std::cout << "Component::pointToViewport - BoundToPage using " << static_cast<int>(rawX) << "x" << static_cast<int>(rawY) << std::endl;
//std::cout << "Component::pointToViewport - BoundToPage converted to " << rawX << "," << rawY << std::endl;
}
//if (useBoxShader) {
//std::cout << "Component::pointToViewport - notBoundToPage converting from " << static_cast<int>(rawX) << "," << static_cast<int>(rawY) << std::endl;
//std::cout << "BoundToPage using " << screenWidth << "x" << screenHeight << std::endl;
rawX = ((rawX / windowWidth) * 2) - 1;
rawY = ((rawY / windowHeight) * 2) - 1;
//std::cout << "Component::pointToViewport - BoundToPage using " << static_cast<int>(rawX) << "x" << static_cast<int>(rawY) << std::endl;
//std::cout << "Component::pointToViewport - BoundToPage converted to " << rawX << "," << rawY << std::endl;
/*
} else {
//std::cout << "notBoundToPage using " << screenWidth << "x" << screenHeight << std::endl;
//std::cout << "Component::pointToViewport - notBoundToPage converting from " << static_cast<int>(rawX) << "," << static_cast<int>(rawY) << std::endl;
if (rawX < 0) {
rawX += windowWidth;
}
if (rawY < 0) {
rawY += windowHeight;
}
if (rawX > 1) {
rawX /= windowWidth;
}
if (rawY > 1) {
rawY /= windowHeight;
}
rawX = (rawX * 2) - 1;
rawY = (rawY * 2) - 1;
//std::cout << "Component::pointToViewport - notBoundToPage converted to " << rawX << "," << rawY << std::endl;
void pointToViewportText(float &rawX, float &rawY, size_t windowWidth, size_t windowHeight) {
//std::cout << "notBoundToPage using " << screenWidth << "x" << screenHeight << std::endl;
//std::cout << "Component::pointToViewport - notBoundToPage converting from " << static_cast<int>(rawX) << "," << static_cast<int>(rawY) << std::endl;
if (rawX < 0) {
rawX += windowWidth;
}
*/
if (rawY < 0) {
rawY += windowHeight;
}
if (rawX > 1) {
rawX /= windowWidth;
}
if (rawY > 1) {
rawY /= windowHeight;
}
rawX = (rawX * 2) - 1;
rawY = (rawY * 2) - 1;
//std::cout << "Component::pointToViewport - notBoundToPage converted to " << rawX << "," << rawY << std::endl;
}
// keeps 0-1 (and *2 to convert to screen)
@ -368,7 +431,7 @@ void distanceToViewport(float &rawX, float &rawY, size_t windowWidth, size_t win @@ -368,7 +431,7 @@ void distanceToViewport(float &rawX, float &rawY, size_t windowWidth, size_t win
rawY *= 2;
}
void opengl_window_handle::drawTexturedBox(opengl_texture_handle *texture, Rect *position) {
void OpenGLWindowHandle::drawSpriteBox(OpenGLTexture *texture, Rect *position) {
std::cout << "Window size: " << this->width << "," << this->height << std::endl;
// figure out new vertices
float vx = position->x;
@ -401,16 +464,8 @@ void opengl_window_handle::drawTexturedBox(opengl_texture_handle *texture, Rect @@ -401,16 +464,8 @@ void opengl_window_handle::drawTexturedBox(opengl_texture_handle *texture, Rect
vertices[(3 * 5) + 0] = vx;
vertices[(3 * 5) + 1] = vy;
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
GLenum glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "BoxComponent::render - glBindBuffer not ok: " << glErr << std::endl;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "BoxComponent::render - glBufferData not ok: " << glErr << std::endl;
}
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectBox); checkGLState("OpenGLWindowHandle::drawSpriteBox - unselect");
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); checkGLState("OpenGLWindowHandle::drawSpriteBox - glBufferData");
float textureTransformMatrix[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
@ -419,26 +474,76 @@ void opengl_window_handle::drawTexturedBox(opengl_texture_handle *texture, Rect @@ -419,26 +474,76 @@ void opengl_window_handle::drawTexturedBox(opengl_texture_handle *texture, Rect
};
textureShader->bind();
GLint transformLocation = textureShader->uniform("transform");
glUniformMatrix4fv(transformLocation, 1, GL_FALSE, textureTransformMatrix);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "MultiComponent::render - glUniformMatrix4fv - not ok: " << glErr << std::endl;
}
glUniformMatrix4fv(transformLocation, 1, GL_FALSE, textureTransformMatrix); checkGLState("OpenGLWindowHandle::drawSpriteBox - glUniformMatrix4fv");
glBindVertexArray(vertexArrayObject);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "BoxComponent::render - glBindVertexArray not ok: " << glErr << std::endl;
}
glBindTexture(GL_TEXTURE_2D, texture->number);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "BoxComponent::render - glBindTexture not ok: " << glErr << std::endl;
}
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "BoxComponent::render - glDrawElements not ok: " << glErr << std::endl;
}
glBindVertexArray(vertexArrayObjectBox); checkGLState("OpenGLWindowHandle::drawSpriteBox - glBindVertexArray");
glBindTexture(GL_TEXTURE_2D, texture->number); checkGLState("OpenGLWindowHandle::drawSpriteBox - glBindTexture");
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); checkGLState("OpenGLWindowHandle::drawSpriteBox - glDrawElements");
}
inline void setVerticesColor(std::unique_ptr<float[]> &vertices, int p, unsigned int color);
#define posMac(p) (p * (3 + 4 + 2)) // 3 positions + 4 color channels + 2 S&T (texture mapping)
inline void setVerticesColor(std::unique_ptr<float[]> &vertices, int p, unsigned int color) {
vertices[static_cast<size_t>(posMac(p) + 2)] = 0.0f;
vertices[static_cast<size_t>(posMac(p) + 3)] = (static_cast<float>((color >> 24) & 0xFF)) / 255;
vertices[static_cast<size_t>(posMac(p) + 4)] = (static_cast<float>((color >> 16) & 0xFF)) / 255;
vertices[static_cast<size_t>(posMac(p) + 5)] = (static_cast<float>((color >> 8) & 0xFF)) / 255;
vertices[static_cast<size_t>(posMac(p) + 6)] = (static_cast<float>((color >> 0) & 0xFF)) / 255;
}
void OpenGLWindowHandle::drawSpriteText(OpenGLTexture *texture, unsigned int hexColor, Rect *position) {
float vx0 = position->x;
float vy0 = this->height - position->y + position->h;
float vx1 = position->x + position->w;
float vy1 = this->height - position->y;
pointToViewportText(vx0, vy0, this->width, this->height);
pointToViewportText(vx1, vy1, this->width, this->height);
std::unique_ptr<float[]> vertices = std::make_unique<float[]>(36);
vertices[posMac(0) + 0] = vx0;
vertices[posMac(0) + 1] = vy0;
setVerticesColor(vertices, 0, hexColor);
vertices[posMac(0) + 7] = texture->s0;
vertices[posMac(0) + 8] = texture->t0;
vertices[posMac(1) + 0] = vx0;
vertices[posMac(1) + 1] = vy1;
setVerticesColor(vertices, 1, hexColor);
vertices[posMac(1) + 7] = texture->s0;
vertices[posMac(1) + 8] = texture->t1;
vertices[posMac(2) + 0] = vx1;
vertices[posMac(2) + 1] = vy1;
setVerticesColor(vertices, 2, hexColor);
vertices[posMac(2) + 7] = texture->s1;
vertices[posMac(2) + 8] = texture->t1;
vertices[posMac(3) + 0] = vx1;
vertices[posMac(3) + 1] = vy0;
setVerticesColor(vertices, 3, hexColor);
vertices[posMac(3) + 7] = texture->s1;
vertices[posMac(3) + 8] = texture->t0;
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectText); checkGLState("OpenGLWindowHandle::drawSpriteText - glBindBuffer");
glBufferData(GL_ARRAY_BUFFER, ((3 + 4 + 2) * 4) * sizeof(float), vertices.get(), GL_STATIC_DRAW); checkGLState("OpenGLWindowHandle::drawSpriteText - glBufferData");
float transformMatrix[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
fontShader->bind();
GLint transformLocation = fontShader->uniform("transform");
glUniformMatrix4fv(transformLocation, 1, GL_FALSE, transformMatrix); checkGLState("OpenGLWindowHandle::drawSpriteText - glUniformMatrix4fv");
// load vertices
glBindVertexArray(vertexArrayObjectText); checkGLState("OpenGLWindowHandle::drawSpriteText - glBindVertexArray");
// load texture
glBindTexture(GL_TEXTURE_2D, texture->number); checkGLState("OpenGLWindowHandle::drawSpriteText - glBindTexture");
// draw primitives using vertices and texture
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); checkGLState("OpenGLWindowHandle::drawSpriteText - glDrawElements");
}

80
src/interfaces/graphical/renderers/glfw/opengl.h

@ -7,48 +7,13 @@ @@ -7,48 +7,13 @@
#include <vector>
#include <string>
#include "ShaderLoader.h"
#ifdef FLOATCOORDS
typedef double coordinates;
typedef double sizes;
#else
typedef short coordinates;
typedef unsigned short sizes;
#endif
typedef struct{
coordinates x, y;
sizes w, h;
} Rect;
class texture_handle {
};
class window_handle {
public:
virtual void clear() { }
virtual void swapBuffers() { }
// can we const texture?
virtual texture_handle* createTexture(unsigned char *texture, GLsizei w, GLsizei h) { return nullptr; }
virtual texture_handle* createTextureFromColor(const unsigned int hexColor) { return nullptr; }
virtual void drawTexturedBox(texture_handle *texture, Rect *position) {}
//
size_t width;
size_t height;
};
// maybe convert to interface?
class baseRenderer {
public:
virtual bool initialize() { return true; }
// maybe it should return a window object?
virtual window_handle *createWindow(std::string title, Rect *position, unsigned int flags) { return nullptr; }
};
#include "../renderer.h"
struct quadVector {
GLfloat vector[4][3];
};
class texture_atlas {
class TextureAtlas {
public:
GLuint texture;
sizes w, h; // texture width/height
@ -58,27 +23,27 @@ public: @@ -58,27 +23,27 @@ public:
bool smooth;
unsigned char bpp; // 0-4
~texture_atlas();
~TextureAtlas();
void updateMaxAvailArea();
void markAreaUsed(Rect *it);
void rebuildAvailable();
};
class opengl_texture_handle : public texture_handle {
class OpenGLTexture : public Sprite {
public:
// future
texture_atlas *mp_atlas;
TextureAtlas *mp_atlas;
quadVector m_texureVector;
// temp for now
GLuint number;
float s0;
float t0;
float s1;
float t1;
GLfloat s0;
GLfloat t0;
GLfloat s1;
GLfloat t1;
};
// unlike a texture more like a sprite
class OpenglTexturedQuad {
class OpenGLTexturedQuad {
public:
bool fontShader;
sizes width;
@ -103,31 +68,38 @@ class opengl; // few declr @@ -103,31 +68,38 @@ class opengl; // few declr
bool initGL();
bool initGLEW();
class opengl_window_handle : public window_handle {
class OpenGLWindowHandle : public WindowHandle {
public:
void clear();
void swapBuffers();
opengl_texture_handle* createTexture(unsigned char* texture, GLsizei w, GLsizei h);
opengl_texture_handle* createTextureFromColor(const unsigned int hexColor);
using window_handle::drawTexturedBox;
void drawTexturedBox(opengl_texture_handle *texture, Rect *position);
OpenGLTexture* createSprite(unsigned char* texture, GLsizei w, GLsizei h);
OpenGLTexture* createTextSprite(unsigned char *texture, GLsizei w, GLsizei h, textureMap &textureMap);
OpenGLTexture* createSpriteFromColor(const unsigned int hexColor);
using WindowHandle::drawSpriteBox;
void drawSpriteBox(OpenGLTexture *texture, Rect *position);
void drawSpriteText(OpenGLTexture *texture, unsigned int hexColor, Rect *position);
// property
GLFWwindow *window;
opengl *renderer;
// our singular vao
GLuint vertexArrayObject = 0;
GLuint vertexArrayObjectBox = 0;
GLuint vertexArrayObjectText = 0;
// our singular vbo
GLuint vertexBufferObject = 0;
GLuint vertexBufferObjectBox = 0;
GLuint vertexBufferObjectText = 0;
ShaderLoader shaderLoader;
Shader *textureShader;
Shader *fontShader;
// needed for mouse down/up events
double cursorX = 0;
double cursorY = 0;
};
// singleton, there should only be one of these in the system
class opengl : public baseRenderer {
class OpenGL : public BaseRenderer {
public:
bool initialize();
opengl_window_handle *createWindow(std::string title, Rect *position, unsigned int flags);
OpenGLWindowHandle *createWindow(std::string title, Rect *position, unsigned int flags);
// need texture/sprite functions (for elements that are going to be used across windows)
// maybe take in opengl_window_handle*, nullptr meaning all
// properties

Loading…
Cancel
Save