Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,147 @@
#include "ComputeImpl.h"
#include "ogl.h"
#include <Kore/Compute/Compute.h>
#include <Kore/Graphics3/Graphics.h>
#include <Kore/Math/Core.h>
#include <stdio.h>
using namespace Kore;
#if defined(KINC_WINDOWS) || (defined(KINC_LINUX) && defined(GL_VERSION_4_3)) || (defined(KINC_ANDROID) && defined(GL_ES_VERSION_3_1))
#define HAS_COMPUTE
#endif
ComputeShaderImpl::ComputeShaderImpl(void *source, int length) : _length(length) {
_source = new char[length + 1];
for (int i = 0; i < length; ++i) {
_source[i] = ((char *)source)[i];
}
_source[length] = 0;
#ifdef HAS_COMPUTE
_id = glCreateShader(GL_COMPUTE_SHADER);
glCheckErrors();
glShaderSource(_id, 1, &_source, nullptr);
glCompileShader(_id);
int result;
glGetShaderiv(_id, GL_COMPILE_STATUS, &result);
if (result != GL_TRUE) {
int length;
glGetShaderiv(_id, GL_INFO_LOG_LENGTH, &length);
char *errormessage = new char[length];
glGetShaderInfoLog(_id, length, nullptr, errormessage);
log(Error, "GLSL compiler error: %s\n", errormessage);
delete[] errormessage;
}
_programid = glCreateProgram();
glAttachShader(_programid, _id);
glLinkProgram(_programid);
glGetProgramiv(_programid, GL_LINK_STATUS, &result);
if (result != GL_TRUE) {
int length;
glGetProgramiv(_programid, GL_INFO_LOG_LENGTH, &length);
char *errormessage = new char[length];
glGetProgramInfoLog(_programid, length, nullptr, errormessage);
log(Error, "GLSL linker error: %s\n", errormessage);
delete[] errormessage;
}
#endif
}
ComputeShaderImpl::~ComputeShaderImpl() {
delete[] _source;
_source = nullptr;
#ifdef HAS_COMPUTE
glDeleteProgram(_programid);
glDeleteShader(_id);
#endif
}
ComputeShader::ComputeShader(void *_data, int length) : ComputeShaderImpl(_data, length) {}
ComputeConstantLocation ComputeShader::getConstantLocation(const char *name) {
ComputeConstantLocation location;
#ifdef HAS_COMPUTE
location.location = glGetUniformLocation(_programid, name);
glCheckErrors2();
if (location.location < 0) {
log(Warning, "Uniform %s not found.", name);
}
#endif
return location;
}
ComputeTextureUnit ComputeShader::getTextureUnit(const char *name) {
ComputeTextureUnit unit;
unit.unit = 0;
return unit;
}
void Compute::setFloat(ComputeConstantLocation location, float value) {
#ifdef HAS_COMPUTE
glUniform1f(location.location, value);
glCheckErrors2();
#endif
}
void Compute::setBuffer(ShaderStorageBuffer *buffer, int index) {
#ifdef HAS_COMPUTE
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer->bufferId);
glCheckErrors2();
#endif
}
void Compute::setTexture(ComputeTextureUnit unit, Graphics4::Texture *texture, Access access) {
#ifdef HAS_COMPUTE
glActiveTexture(GL_TEXTURE0 + unit.unit);
glCheckErrors2();
GLenum glaccess = access == Access::Read ? GL_READ_ONLY : (access == Access::Write ? GL_WRITE_ONLY : GL_READ_WRITE);
glBindImageTexture(0, texture->texture, 0, GL_FALSE, 0, glaccess, GL_RGBA32F);
glCheckErrors2();
#endif
}
void Compute::setTexture(ComputeTextureUnit unit, Graphics4::RenderTarget *target, Access access) {}
void Compute::setSampledTexture(ComputeTextureUnit unit, Graphics4::Texture *texture) {}
void Compute::setSampledTexture(ComputeTextureUnit unit, Graphics4::RenderTarget *target) {}
void Compute::setSampledDepthTexture(ComputeTextureUnit unit, Graphics4::RenderTarget *target) {}
void Compute::setTextureAddressing(ComputeTextureUnit unit, Graphics4::TexDir dir, Graphics4::TextureAddressing addressing) {}
void Compute::setTexture3DAddressing(ComputeTextureUnit unit, Graphics4::TexDir dir, Graphics4::TextureAddressing addressing) {}
void Compute::setTextureMagnificationFilter(ComputeTextureUnit unit, Graphics4::TextureFilter filter) {}
void Compute::setTexture3DMagnificationFilter(ComputeTextureUnit unit, Graphics4::TextureFilter filter) {}
void Compute::setTextureMinificationFilter(ComputeTextureUnit unit, Graphics4::TextureFilter filter) {}
void Compute::setTexture3DMinificationFilter(ComputeTextureUnit unit, Graphics4::TextureFilter filter) {}
void Compute::setTextureMipmapFilter(ComputeTextureUnit unit, Graphics4::MipmapFilter filter) {}
void Compute::setTexture3DMipmapFilter(ComputeTextureUnit unit, Graphics4::MipmapFilter filter) {}
void Compute::setShader(ComputeShader *shader) {
#ifdef HAS_COMPUTE
glUseProgram(shader->_programid);
glCheckErrors2();
#endif
}
void Compute::compute(int x, int y, int z) {
#ifdef HAS_COMPUTE
glDispatchCompute(x, y, z);
glCheckErrors2();
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glCheckErrors2();
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
glCheckErrors2();
#endif
}

View File

@ -0,0 +1,23 @@
#pragma once
namespace Kore {
class ComputeConstantLocationImpl {
public:
int location;
};
class ComputeTextureUnitImpl {
public:
int unit;
};
class ComputeShaderImpl {
public:
ComputeShaderImpl(void *source, int length);
virtual ~ComputeShaderImpl();
uint _id;
uint _programid;
char *_source;
int _length;
};
}

View File

@ -0,0 +1,6 @@
#pragma once
#include "IndexBufferImpl.h"
#include "RenderTargetImpl.h"
#include "TextureImpl.h"
#include "VertexBufferImpl.h"

View File

@ -0,0 +1,58 @@
#include "ogl.h"
#include <Kore/Graphics3/Graphics.h>
using namespace Kore;
Graphics3::IndexBuffer *IndexBufferImpl::current = nullptr;
IndexBufferImpl::IndexBufferImpl(int count) : myCount(count) {}
Graphics3::IndexBuffer::IndexBuffer(int indexCount) : IndexBufferImpl(indexCount) {
glGenBuffers(1, &bufferId);
glCheckErrors();
data = new int[indexCount];
#if defined(KINC_ANDROID) || defined(KINC_RASPBERRY_PI)
shortData = new u16[indexCount];
#endif
}
Graphics3::IndexBuffer::~IndexBuffer() {
unset();
delete[] data;
}
int *Graphics3::IndexBuffer::lock() {
return data;
}
void Graphics3::IndexBuffer::unlock() {
#if defined(KINC_ANDROID) || defined(KINC_RASPBERRY_PI)
for (int i = 0; i < myCount; ++i)
shortData[i] = (u16)data[i];
#endif
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferId);
glCheckErrors();
#if defined(KINC_ANDROID) || defined(KINC_RASPBERRY_PI)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, myCount * 2, shortData, GL_STATIC_DRAW);
glCheckErrors();
#else
glBufferData(GL_ELEMENT_ARRAY_BUFFER, myCount * 4, data, GL_STATIC_DRAW);
glCheckErrors();
#endif
}
void Graphics3::IndexBuffer::_set() {
current = this;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferId);
glCheckErrors();
}
void IndexBufferImpl::unset() {
if ((void *)current == (void *)this)
current = nullptr;
}
int Graphics3::IndexBuffer::count() {
return myCount;
}

View File

@ -0,0 +1,24 @@
#pragma once
namespace Kore {
namespace Graphics3 {
class IndexBuffer;
}
class IndexBufferImpl {
protected:
public:
IndexBufferImpl(int count);
void unset();
#if defined(KINC_ANDROID) || defined(KINC_RASPBERRY_PI)
u16 *shortData;
#endif
int *data;
int myCount;
uint bufferId;
public:
static Graphics3::IndexBuffer *current;
};
}

View File

@ -0,0 +1,100 @@
#include "ogl.h"
#include <Kore/Graphics3/Graphics.h>
#include <Kore/Graphics3/Light.h>
#include <Kore/Math/Core.h>
using namespace Kore;
// OpenGL man pages for "glLight" function:
// see https://www.opengl.org/sdk/docs/man2/xhtml/glLight.xml
LightImpl::LightImpl()
: myType(DirectionalLight), myAmbient(0, 0, 0, 1), myDiffuse(1, 1, 1, 1), mySpecular(1, 1, 1, 1), myPositionOrDirection(0, 0, 1, 0),
mySpotDirection(0, 0, 1), // default point in +Z direction
mySpotExponent(0.0f), mySpotCutoff(180.0f), myConstAttn(1.0f), myLinearAttn(0.0f), myQuadricAttn(0.0f) {}
LightImpl::~LightImpl() {}
void Light::setType(LightType type) {
// Set new light type
myType = type;
// Update position/directior vector
myPositionOrDirection[3] = (myType == DirectionalLight ? 0.0f : 1.0f);
}
void Light::setColors(const vec4 &ambient, const vec4 &diffuse, const vec4 &specular) {
// Store light colors
myAmbient = ambient;
myDiffuse = diffuse;
mySpecular = specular;
}
void Light::setPosition(const vec3 &position) {
// Store position point (x, y, z, 1)
myPositionOrDirection = vec4(position, 1);
}
void Light::setDirection(const vec3 &direction) {
if (myType == SpotLight) {
// Store spot direction vector (x, y, z)
mySpotDirection = direction;
}
else {
// Store direction vector (x, y, z, 0)
myPositionOrDirection = vec4(direction, 0);
}
}
void Light::setSpot(float exponent, float cutoff) {
mySpotExponent = exponent;
mySpotCutoff = cutoff;
}
void Light::setAttenuation(float constAttn, float linearAttn, float quadricAttn) {
myConstAttn = constAttn;
myLinearAttn = linearAttn;
myQuadricAttn = quadricAttn;
}
/*
1
GL Light Intensity = -----------------------------------
constant + d*linear + d^2*quadratic
*/
void Light::setAttenuationRadius(float radius) {
setAttenuation(1.0f, 1.0f / radius, 1.0f / radius);
}
void LightImpl::submitLightParamsToGL(GLenum lightID) const {
// Submit colors
glLightfv(lightID, GL_AMBIENT, myAmbient.values);
glLightfv(lightID, GL_DIFFUSE, myDiffuse.values);
glLightfv(lightID, GL_SPECULAR, mySpecular.values);
// Submit attenuation
glLightf(lightID, GL_CONSTANT_ATTENUATION, myConstAttn);
glLightf(lightID, GL_LINEAR_ATTENUATION, myLinearAttn);
glLightf(lightID, GL_QUADRATIC_ATTENUATION, myQuadricAttn);
// Submit spot parameters
glLightfv(lightID, GL_SPOT_DIRECTION, mySpotDirection.values);
glLightf(lightID, GL_SPOT_EXPONENT, mySpotExponent);
glLightf(lightID, GL_SPOT_CUTOFF, mySpotCutoff);
}
void LightImpl::submitLightTransformToGL(GLenum lightID) const {
glLightfv(lightID, GL_POSITION, myPositionOrDirection.values);
}
Light::Light(LightType type) : LightImpl() {
setType(type);
}
void Light::_set(int num) {
GLenum lightID = GL_LIGHT0 + num;
glEnable(lightID);
submitLightParamsToGL(lightID);
submitLightTransformToGL(lightID);
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "ogl.h"
#include <Kore/Math/Vector.h>
namespace Kore {
enum LightType { DirectionalLight, PointLight, SpotLight };
class LightImpl {
public:
LightImpl();
virtual ~LightImpl();
protected:
// Submit light parameters to OpenGL (lightID is GL_LIGHT<n> where <n> is in the range [0, 7])
void submitLightParamsToGL(GLenum lightID) const;
// Submit light transformation to OpenGL (lightID is GL_LIGHT<n> where <n> is in the range [0, 7]).
void submitLightTransformToGL(GLenum lightID) const;
LightType myType;
vec4 myAmbient;
vec4 myDiffuse;
vec4 mySpecular;
vec4 myPositionOrDirection;
vec3 mySpotDirection;
float mySpotExponent;
float mySpotCutoff;
float myConstAttn;
float myLinearAttn;
float myQuadricAttn;
};
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
#pragma once
#include <Kore/Graphics1/Image.h>
#include <Kore/Graphics3/Graphics.h>
#include <Kore/Math/Matrix.h>

View File

@ -0,0 +1,204 @@
#include "ogl.h"
#include <Kore/Graphics3/Graphics.h>
#include <Kore/Graphics4/Shader.h>
#include <Kore/Log.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
using namespace Kore;
namespace Kore {
#ifndef OPENGLES
bool programUsesTessellation = false;
#endif
}
ProgramImpl::ProgramImpl()
: textureCount(0), vertexShader(nullptr), fragmentShader(nullptr), geometryShader(nullptr), tessellationEvaluationShader(nullptr),
tessellationControlShader(nullptr) {
textures = new const char *[16];
textureValues = new int[16];
}
Graphics4::Program::Program() {
programId = glCreateProgram();
glCheckErrors();
}
ProgramImpl::~ProgramImpl() {
glDeleteProgram(programId);
}
void Graphics4::Program::setVertexShader(Shader *shader) {
vertexShader = shader;
}
void Graphics4::Program::setFragmentShader(Shader *shader) {
fragmentShader = shader;
}
void Graphics4::Program::setGeometryShader(Shader *shader) {
#ifndef OPENGLES
geometryShader = shader;
#endif
}
void Graphics4::Program::setTessellationControlShader(Shader *shader) {
#ifndef OPENGLES
tessellationControlShader = shader;
#endif
}
void Graphics4::Program::setTessellationEvaluationShader(Shader *shader) {
#ifndef OPENGLES
tessellationEvaluationShader = shader;
#endif
}
namespace {
int toGlShader(Graphics4::ShaderType type) {
switch (type) {
case Graphics4::VertexShader:
default:
return GL_VERTEX_SHADER;
case Graphics4::FragmentShader:
return GL_FRAGMENT_SHADER;
/*#ifndef OPENGLES
case GeometryShader:
return GL_GEOMETRY_SHADER;
case TessellationControlShader:
return GL_TESS_CONTROL_SHADER;
case TessellationEvaluationShader:
return GL_TESS_EVALUATION_SHADER;
#endif*/
}
}
void compileShader(uint &id, char *source, int length, Graphics4::ShaderType type) {
id = glCreateShader(toGlShader(type));
glCheckErrors();
glShaderSource(id, 1, (const GLchar **)&source, 0);
glCompileShader(id);
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if (result != GL_TRUE) {
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
char *errormessage = new char[length];
glGetShaderInfoLog(id, length, nullptr, errormessage);
printf("GLSL compiler error: %s\n", errormessage);
delete[] errormessage;
}
}
}
void Graphics4::Program::link(VertexStructure **structures, int count) {
compileShader(vertexShader->id, vertexShader->source, vertexShader->length, VertexShader);
compileShader(fragmentShader->id, fragmentShader->source, fragmentShader->length, FragmentShader);
#ifndef OPENGLES
if (geometryShader != nullptr)
compileShader(geometryShader->id, geometryShader->source, geometryShader->length, GeometryShader);
if (tessellationControlShader != nullptr)
compileShader(tessellationControlShader->id, tessellationControlShader->source, tessellationControlShader->length, TessellationControlShader);
if (tessellationEvaluationShader != nullptr)
compileShader(tessellationEvaluationShader->id, tessellationEvaluationShader->source, tessellationEvaluationShader->length,
TessellationEvaluationShader);
#endif
glAttachShader(programId, vertexShader->id);
glAttachShader(programId, fragmentShader->id);
#ifndef OPENGLES
if (geometryShader != nullptr)
glAttachShader(programId, geometryShader->id);
if (tessellationControlShader != nullptr)
glAttachShader(programId, tessellationControlShader->id);
if (tessellationEvaluationShader != nullptr)
glAttachShader(programId, tessellationEvaluationShader->id);
#endif
glCheckErrors();
int index = 0;
for (int i1 = 0; i1 < count; ++i1) {
for (int i2 = 0; i2 < structures[i1]->size; ++i2) {
VertexElement element = structures[i1]->elements[i2];
glBindAttribLocation(programId, index, element.name);
glCheckErrors();
if (element.data == Float4x4VertexData) {
index += 4;
}
else {
++index;
}
}
}
glLinkProgram(programId);
int result;
glGetProgramiv(programId, GL_LINK_STATUS, &result);
if (result != GL_TRUE) {
int length;
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &length);
char *errormessage = new char[length];
glGetProgramInfoLog(programId, length, nullptr, errormessage);
printf("GLSL linker error: %s\n", errormessage);
delete[] errormessage;
}
#ifndef KINC_OPENGL_ES
#ifndef KINC_LINUX
/* if (tessellationControlShader != nullptr) {
glPatchParameteri(GL_PATCH_VERTICES, 3);
glCheckErrors();
}*/
#endif
#endif
}
void Graphics4::Program::set() {
#ifndef KINC_OPENGL_ES
programUsesTessellation = tessellationControlShader != nullptr;
#endif
glUseProgram(programId);
glCheckErrors();
for (int index = 0; index < textureCount; ++index) {
glUniform1i(textureValues[index], index);
glCheckErrors();
}
}
Graphics4::ConstantLocation Graphics4::Program::getConstantLocation(const char *name) {
ConstantLocation location;
location.location = glGetUniformLocation(programId, name);
glCheckErrors();
if (location.location < 0) {
log(Warning, "Uniform %s not found.", name);
}
return location;
}
int ProgramImpl::findTexture(const char *name) {
for (int index = 0; index < textureCount; ++index) {
if (strcmp(textures[index], name) == 0)
return index;
}
return -1;
}
Graphics4::TextureUnit Graphics4::Program::getTextureUnit(const char *name) {
int index = findTexture(name);
if (index < 0) {
int location = glGetUniformLocation(programId, name);
glCheckErrors();
index = textureCount;
textureValues[index] = location;
textures[index] = name;
++textureCount;
}
TextureUnit unit;
unit.unit = index;
return unit;
}

View File

@ -0,0 +1,29 @@
#pragma once
namespace Kore {
namespace Graphics4 {
class Shader;
}
class ProgramImpl {
protected:
uint programId;
Graphics4::Shader *vertexShader;
Graphics4::Shader *fragmentShader;
Graphics4::Shader *geometryShader;
Graphics4::Shader *tessellationControlShader;
Graphics4::Shader *tessellationEvaluationShader;
ProgramImpl();
virtual ~ProgramImpl();
int findTexture(const char *name);
const char **textures;
int *textureValues;
int textureCount;
};
class ConstantLocationImpl {
public:
int location;
};
}

View File

@ -0,0 +1,236 @@
#include "RenderTargetImpl.h"
#include "ogl.h"
#include <Kore/Graphics3/Graphics.h>
#include <Kore/Log.h>
#include <Kore/System.h>
#ifdef KINC_ANDROID
#include <GLContext.h>
#endif
using namespace Kore;
#ifndef GL_RGBA16F_EXT
#define GL_RGBA16F_EXT 0x881A
#endif
#ifndef GL_RGBA32F_EXT
#define GL_RGBA32F_EXT 0x8814
#endif
#ifndef GL_HALF_FLOAT
#define GL_HALF_FLOAT 0x140B
#endif
namespace {
int pow(int pow) {
int ret = 1;
for (int i = 0; i < pow; ++i)
ret *= 2;
return ret;
}
int getPower2(int i) {
for (int power = 0;; ++power)
if (pow(power) >= i)
return pow(power);
}
bool nonPow2RenderTargetsSupported() {
#ifdef KINC_OPENGL_ES
#ifdef KINC_ANDROID
if (ndk_helper::GLContext::GetInstance()->GetGLVersion() >= 3.0)
return true;
else
return false;
#else
return false;
#endif
#else
return true;
#endif
}
}
void RenderTargetImpl::setupDepthStencil(int depthBufferBits, int stencilBufferBits, int width, int height) {
if (depthBufferBits > 0 && stencilBufferBits > 0) {
#ifdef KINC_OPENGL_ES
GLenum internalFormat = GL_DEPTH24_STENCIL8_OES;
#else
GLenum internalFormat;
if (depthBufferBits == 24)
internalFormat = GL_DEPTH24_STENCIL8;
else
internalFormat = GL_DEPTH32F_STENCIL8;
#endif
// Renderbuffer
// glGenRenderbuffers(1, &_depthRenderbuffer);
// glCheckErrors();
// glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer);
// glCheckErrors();
// glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, width, height);
// glCheckErrors();
// #ifdef KINC_OPENGL_ES
// glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);
// glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);
// #else
// glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);
// #endif
// glCheckErrors();
// Texture
glGenTextures(1, &_depthTexture);
glCheckErrors();
glBindTexture(GL_TEXTURE_2D, _depthTexture);
glCheckErrors();
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
glCheckErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
glCheckErrors();
glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
glCheckErrors();
#ifdef KINC_OPENGL_ES
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _depthTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, _depthTexture, 0);
#else
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, _depthTexture, 0);
#endif
glCheckErrors();
}
else if (depthBufferBits > 0) {
// Renderbuffer
// glGenRenderbuffers(1, &_depthRenderbuffer);
// glCheckErrors();
// glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer);
// glCheckErrors();
// glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
// glCheckErrors();
// glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);
// glCheckErrors();
// Texture
glGenTextures(1, &_depthTexture);
glCheckErrors();
glBindTexture(GL_TEXTURE_2D, _depthTexture);
glCheckErrors();
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
glCheckErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
glCheckErrors();
glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
glCheckErrors();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _depthTexture, 0);
glCheckErrors();
}
}
Graphics3::RenderTarget::RenderTarget(int width, int height, int depthBufferBits, bool antialiasing, RenderTargetFormat format, int stencilBufferBits,
int contextId)
: width(width), height(height) {
if (nonPow2RenderTargetsSupported()) {
texWidth = width;
texHeight = height;
}
else {
texWidth = getPower2(width);
texHeight = getPower2(height);
}
this->contextId = contextId;
// (DK) required on windows/gl
Kore::System::makeCurrent(contextId);
glGenTextures(1, &_texture);
glCheckErrors();
glBindTexture(GL_TEXTURE_2D, _texture);
glCheckErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glCheckErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glCheckErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glCheckErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glCheckErrors();
switch (format) {
#ifndef KINC_MACOS
case Target128BitFloat:
#ifdef KINC_OPENGL_ES
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_EXT, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, 0);
#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, 0);
#endif
break;
case Target64BitFloat:
#ifdef KINC_OPENGL_ES
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_EXT, texWidth, texHeight, 0, GL_RGBA, GL_HALF_FLOAT, 0);
#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, texWidth, texHeight, 0, GL_RGBA, GL_HALF_FLOAT, 0);
#endif
break;
case Target16BitDepth:
#ifdef KINC_OPENGL_ES
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, texWidth, texHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
break;
case Target32Bit:
#endif
default:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}
glCheckErrors();
glGenFramebuffers(1, &_framebuffer);
glCheckErrors();
glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
glCheckErrors();
setupDepthStencil(depthBufferBits, stencilBufferBits, texWidth, texHeight);
if (format == Target16BitDepth) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _texture, 0);
#ifndef OPENGLES
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
#endif
}
else {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0);
}
glCheckErrors();
// GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
// glDrawBuffers(1, drawBuffers);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glCheckErrors();
glBindTexture(GL_TEXTURE_2D, 0);
glCheckErrors();
}
void Graphics3::RenderTarget::useColorAsTexture(TextureUnit unit) {
glActiveTexture(GL_TEXTURE0 + unit.unit);
glCheckErrors();
glBindTexture(GL_TEXTURE_2D, _texture);
glCheckErrors();
}
void Graphics3::RenderTarget::useDepthAsTexture(TextureUnit unit) {
glActiveTexture(GL_TEXTURE0 + unit.unit);
glCheckErrors();
glBindTexture(GL_TEXTURE_2D, _depthTexture);
glCheckErrors();
}
void Graphics3::RenderTarget::setDepthStencilFrom(RenderTarget *source) {
glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, source->_depthTexture, 0);
}

View File

@ -0,0 +1,13 @@
#pragma once
namespace Kore {
class RenderTargetImpl {
public:
unsigned _framebuffer;
unsigned _texture;
unsigned _depthTexture;
// unsigned _depthRenderbuffer;
int contextId;
void setupDepthStencil(int depthBufferBits, int stencilBufferBits, int width, int height);
};
}

View File

@ -0,0 +1,24 @@
#include "ogl.h"
#include <Kore/Graphics3/Graphics.h>
#include <Kore/Graphics4/Shader.h>
#include <Kore/Math/Core.h>
using namespace Kore;
ShaderImpl::ShaderImpl(void *source, int length) : length(length), id(0) {
this->source = new char[length + 1];
for (int i = 0; i < length; ++i) {
this->source[i] = ((char *)source)[i];
}
this->source[length] = 0;
}
ShaderImpl::~ShaderImpl() {
delete[] source;
source = nullptr;
if (id != 0)
glDeleteShader(id);
}
Graphics4::Shader::Shader(void *source, int length, Graphics4::ShaderType type) : ShaderImpl(source, length) {}

View File

@ -0,0 +1,20 @@
#pragma once
namespace Kore {
namespace Graphics4 {
class Program;
}
class ProgramImpl;
class ShaderImpl {
public:
ShaderImpl(void *source, int length);
virtual ~ShaderImpl();
uint id;
char *source;
int length;
friend class Program;
friend class ProgramImpl;
};
}

View File

@ -0,0 +1,444 @@
#include "TextureImpl.h"
#include "ogl.h"
#include <Kore/Graphics1/Image.h>
#include <Kore/Graphics3/Graphics.h>
#include <Kore/Log.h>
using namespace Kore;
#ifndef GL_TEXTURE_3D
#define GL_TEXTURE_3D 0x806F
#endif
namespace {
int convertFormat(Graphics3::Image::Format format) {
switch (format) {
case Graphics3::Image::RGBA32:
case Graphics3::Image::RGBA64:
case Graphics3::Image::RGBA128:
default:
// #ifdef GL_BGRA
// return GL_BGRA;
// #else
return GL_RGBA;
// #endif
case Graphics3::Image::RGB24:
return GL_RGB;
case Graphics3::Image::Grey8:
#ifdef KINC_OPENGL_ES
return GL_LUMINANCE;
#else
return GL_RED;
#endif
}
}
int convertInternalFormat(Graphics3::Image::Format format) {
switch (format) {
case Graphics3::Image::RGBA128:
return GL_RGBA;
case Graphics3::Image::RGBA32:
case Graphics3::Image::RGBA64:
default:
// #ifdef GL_BGRA
// return GL_BGRA;
// #else
return GL_RGBA;
// #endif
case Graphics3::Image::RGB24:
return GL_RGB;
case Graphics3::Image::Grey8:
#ifdef KINC_OPENGL_ES
return GL_LUMINANCE;
#else
return GL_RED;
#endif
}
}
int convertType(Graphics3::Image::Format format) {
switch (format) {
case Graphics3::Image::RGBA128:
case Graphics3::Image::RGBA64:
return GL_FLOAT;
case Graphics3::Image::RGBA32:
default:
return GL_UNSIGNED_BYTE;
}
}
#if 0
int astcFormat(u8 blockX, u8 blockY) {
switch (blockX) {
case 4:
switch (blockY) {
case 4:
return COMPRESSED_RGBA_ASTC_4x4_KHR;
}
case 5:
switch (blockY) {
case 4:
return COMPRESSED_RGBA_ASTC_5x4_KHR;
case 5:
return COMPRESSED_RGBA_ASTC_5x5_KHR;
}
case 6:
switch (blockY) {
case 5:
return COMPRESSED_RGBA_ASTC_6x5_KHR;
case 6:
return COMPRESSED_RGBA_ASTC_6x6_KHR;
}
case 8:
switch (blockY) {
case 5:
return COMPRESSED_RGBA_ASTC_8x5_KHR;
case 6:
return COMPRESSED_RGBA_ASTC_8x6_KHR;
case 8:
return COMPRESSED_RGBA_ASTC_8x8_KHR;
}
case 10:
switch (blockY) {
case 5:
return COMPRESSED_RGBA_ASTC_10x5_KHR;
case 6:
return COMPRESSED_RGBA_ASTC_10x6_KHR;
case 8:
return COMPRESSED_RGBA_ASTC_10x8_KHR;
case 10:
return COMPRESSED_RGBA_ASTC_10x10_KHR;
}
case 12:
switch (blockY) {
case 10:
return COMPRESSED_RGBA_ASTC_12x10_KHR;
case 12:
return COMPRESSED_RGBA_ASTC_12x12_KHR;
}
}
return 0;
}
#endif
int pow(int pow) {
int ret = 1;
for (int i = 0; i < pow; ++i)
ret *= 2;
return ret;
}
int getPower2(int i) {
for (int power = 0;; ++power)
if (pow(power) >= i)
return pow(power);
}
void convertImageToPow2(Graphics3::Image::Format format, u8 *from, int fw, int fh, u8 *to, int tw, int th) {
switch (format) {
case Graphics3::Image::RGBA32:
for (int y = 0; y < th; ++y) {
for (int x = 0; x < tw; ++x) {
to[tw * 4 * y + x * 4 + 0] = 0;
to[tw * 4 * y + x * 4 + 1] = 0;
to[tw * 4 * y + x * 4 + 2] = 0;
to[tw * 4 * y + x * 4 + 3] = 0;
}
}
for (int y = 0; y < fh; ++y) {
for (int x = 0; x < fw; ++x) {
to[tw * 4 * y + x * 4 + 0] = from[y * fw * 4 + x * 4 + 0];
to[tw * 4 * y + x * 4 + 1] = from[y * fw * 4 + x * 4 + 1];
to[tw * 4 * y + x * 4 + 2] = from[y * fw * 4 + x * 4 + 2];
to[tw * 4 * y + x * 4 + 3] = from[y * fw * 4 + x * 4 + 3];
}
}
break;
case Graphics3::Image::Grey8:
for (int y = 0; y < th; ++y) {
for (int x = 0; x < tw; ++x) {
to[tw * y + x] = 0;
}
}
for (int y = 0; y < fh; ++y) {
for (int x = 0; x < fw; ++x) {
to[tw * y + x] = from[y * fw + x];
}
}
break;
}
}
}
void Graphics3::Texture::init(const char *format, bool readable) {
bool toPow2;
if (Graphics3::nonPow2TexturesSupported()) {
texWidth = width;
texHeight = height;
toPow2 = false;
}
else {
texWidth = getPower2(width);
texHeight = getPower2(height);
toPow2 = !(texWidth == width && texHeight == height);
}
u8 *conversionBuffer = nullptr;
if (compressed) {
#if defined(KINC_IOS)
texWidth = Kore::max(texWidth, texHeight);
texHeight = Kore::max(texWidth, texHeight);
if (texWidth < 8)
texWidth = 8;
if (texHeight < 8)
texHeight = 8;
#elif defined(KINC_ANDROID)
texWidth = width;
texHeight = height;
#endif
}
else if (toPow2) {
conversionBuffer = new u8[texWidth * texHeight * sizeOf(this->format)];
convertImageToPow2(this->format, (u8 *)data, width, height, conversionBuffer, texWidth, texHeight);
}
#ifdef KINC_ANDROID
external_oes = false;
#endif
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glCheckErrors();
glGenTextures(1, &texture);
glCheckErrors();
glBindTexture(GL_TEXTURE_2D, texture);
glCheckErrors();
int convertedType = convertType(this->format);
bool isHdr = convertedType == GL_FLOAT;
if (compressed) {
#ifdef KINC_IOS
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, texWidth, texHeight, 0, texWidth * texHeight / 2, data);
// #elif defined(KINC_ANDROID)
// u8 blockX = internalFormat >> 8;
// u8 blockY = internalFormat & 0xff;
// glCompressedTexImage2D(GL_TEXTURE_2D, 0, astcFormat(blockX, blockY), texWidth, texHeight, 0, dataSize, data);
#endif
}
else {
if (isHdr) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, convertedType, hdrData);
}
else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, convertedType, toPow2 ? conversionBuffer : data);
}
glCheckErrors();
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glCheckErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glCheckErrors();
if (toPow2) {
delete[] conversionBuffer;
conversionBuffer = nullptr;
}
if (!readable) {
if (isHdr) {
delete[] hdrData;
hdrData = nullptr;
}
else {
delete[] data;
data = nullptr;
}
}
if (readable && compressed) {
log(Kore::Warning, "Compressed images can not be readable.");
}
}
Graphics3::Texture::Texture(int width, int height, Image::Format format, bool readable) : Image(width, height, format, readable) {
#ifdef KINC_IOS
texWidth = width;
texHeight = height;
#else
if (Graphics3::nonPow2TexturesSupported()) {
texWidth = width;
texHeight = height;
}
else {
texWidth = getPower2(width);
texHeight = getPower2(height);
}
#endif
// conversionBuffer = new u8[texWidth * texHeight * 4];
#ifdef KINC_ANDROID
external_oes = false;
#endif
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glCheckErrors();
glGenTextures(1, &texture);
glCheckErrors();
glBindTexture(GL_TEXTURE_2D, texture);
glCheckErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glCheckErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glCheckErrors();
if (convertType(format) == GL_FLOAT) {
glTexImage2D(GL_TEXTURE_2D, 0, convertInternalFormat(format), texWidth, texHeight, 0, convertFormat(format), GL_FLOAT, nullptr);
}
else {
glTexImage2D(GL_TEXTURE_2D, 0, convertInternalFormat(format), texWidth, texHeight, 0, convertFormat(format), GL_UNSIGNED_BYTE, data);
}
glCheckErrors();
/*if (!readable) {
delete[] data;
data = nullptr;
}*/
}
Graphics3::Texture::Texture(int width, int height, int depth, Graphics3::Image::Format format, bool readable) : Image(width, height, depth, format, readable) {
#ifndef OPENGLES
glGenTextures(1, &texture);
glCheckErrors();
glBindTexture(GL_TEXTURE_3D, texture);
glCheckErrors();
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glCheckErrors();
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glCheckErrors();
glTexImage3D(GL_TEXTURE_3D, 0, convertFormat(format), width, height, depth, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glCheckErrors();
#endif
}
#ifdef KINC_ANDROID
Texture::Texture(unsigned texid) : Image(1023, 684, Image::RGBA32, false) {
texture = texid;
external_oes = true;
texWidth = 1023;
texHeight = 684;
}
#endif
TextureImpl::~TextureImpl() {
glDeleteTextures(1, &texture);
glFlush();
}
void Graphics3::Texture::_set(TextureUnit unit) {
GLenum target = depth > 1 ? GL_TEXTURE_3D : GL_TEXTURE_2D;
glActiveTexture(GL_TEXTURE0 + unit.unit);
glCheckErrors();
#ifdef KINC_ANDROID
if (external_oes) {
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
glCheckErrors();
}
else {
glBindTexture(target, texture);
glCheckErrors();
}
#else
glBindTexture(target, texture);
glCheckErrors();
#endif
}
int Graphics3::Texture::stride() {
return width * sizeOf(format);
}
u8 *Graphics3::Texture::lock() {
return (u8 *)data;
}
/*void Texture::unlock() {
if (conversionBuffer != nullptr) {
convertImageToPow2(format, (u8*)data, width, height, conversionBuffer, texWidth, texHeight);
glBindTexture(GL_TEXTURE_2D, texture);
#ifndef GL_LUMINANCE
#define GL_LUMINANCE GL_RED
#endif
glTexImage2D(GL_TEXTURE_2D, 0, (format == Image::RGBA32) ? GL_RGBA : GL_LUMINANCE, texWidth, texHeight, 0, (format == Image::RGBA32) ? GL_RGBA :
GL_LUMINANCE, GL_UNSIGNED_BYTE, conversionBuffer);
}
}*/
void Graphics3::Texture::unlock() {
// if (conversionBuffer != nullptr) {
// convertImageToPow2(format, (u8*)data, width, height, conversionBuffer, texWidth, texHeight);
glBindTexture(GL_TEXTURE_2D, texture);
glCheckErrors();
// glTexImage2D(GL_TEXTURE_2D, 0, (format == Image::RGBA32) ? GL_RGBA : GL_LUMINANCE, texWidth, texHeight, 0, (format == Image::RGBA32) ? GL_RGBA :
// GL_LUMINANCE, GL_UNSIGNED_BYTE, conversionBuffer);
if (convertType(format) == GL_FLOAT) {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, convertFormat(format), GL_FLOAT, hdrData);
glCheckErrors();
}
else {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, convertFormat(format), GL_UNSIGNED_BYTE, data);
glCheckErrors();
}
// }
}
void Graphics3::Texture::clear(int x, int y, int z, int width, int height, int depth, uint color) {
#ifdef GL_VERSION_4_4
static float clearColor[4];
clearColor[0] = ((color & 0x00ff0000) >> 16) / 255.0f;
clearColor[1] = ((color & 0x0000ff00) >> 8) / 255.0f;
clearColor[2] = (color & 0x000000ff) / 255.0f;
clearColor[3] = ((color & 0xff000000) >> 24) / 255.0f;
GLenum target = depth > 1 ? GL_TEXTURE_3D : GL_TEXTURE_2D;
glBindTexture(target, texture);
glClearTexSubImage(texture, 0, x, y, z, width, height, depth, convertFormat(format), convertType(format), clearColor);
#endif
}
#ifdef KINC_IOS
void Texture::upload(u8 *data) {
glBindTexture(GL_TEXTURE_2D, texture);
glCheckErrors();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, convertFormat(format), GL_UNSIGNED_BYTE, data);
glCheckErrors();
}
#endif
void Graphics3::Texture::generateMipmaps(int levels) {
GLenum target = depth > 1 ? GL_TEXTURE_3D : GL_TEXTURE_2D;
glBindTexture(target, texture);
glCheckErrors();
glGenerateMipmap(target);
glCheckErrors();
}
void Graphics3::Texture::setMipmap(Texture *mipmap, int level) {
int convertedType = convertType(mipmap->format);
bool isHdr = convertedType == GL_FLOAT;
GLenum target = depth > 1 ? GL_TEXTURE_3D : GL_TEXTURE_2D;
glBindTexture(target, texture);
glCheckErrors();
if (isHdr) {
glTexImage2D(target, level, convertInternalFormat(mipmap->format), mipmap->texWidth, mipmap->texHeight, 0, convertFormat(mipmap->format), convertedType,
mipmap->hdrData);
glCheckErrors();
}
else {
glTexImage2D(target, level, convertInternalFormat(mipmap->format), mipmap->texWidth, mipmap->texHeight, 0, convertFormat(mipmap->format), convertedType,
mipmap->data);
glCheckErrors();
}
}

View File

@ -0,0 +1,28 @@
#pragma once
#include <Kore/Graphics1/Image.h>
namespace Kore {
namespace Graphics3 {
class Texture;
}
class TextureUnitImpl {
public:
int unit;
};
class TextureImpl {
protected:
// static TreeMap<Image, Texture*> images;
public:
unsigned int texture;
#ifdef KINC_ANDROID
bool external_oes;
#endif
u8 pixfmt;
~TextureImpl();
};
}

View File

@ -0,0 +1,245 @@
#include "VertexBufferImpl.h"
#include <Kore/Graphics3/Graphics.h>
#include "ShaderImpl.h"
#include "ogl.h"
#include <assert.h>
using namespace Kore;
Graphics3::VertexBuffer *VertexBufferImpl::current = nullptr;
VertexBufferImpl::VertexBufferImpl(int count, int instanceDataStepRate) : myCount(count), instanceDataStepRate(instanceDataStepRate) {
#ifndef NDEBUG
initialized = false;
#endif
}
Graphics3::VertexBuffer::VertexBuffer(int vertexCount, const Graphics4::VertexStructure &structure, Usage usage, int instanceDataStepRate)
: VertexBufferImpl(vertexCount, instanceDataStepRate) {
myStride = 0;
for (int i = 0; i < structure.size; ++i) {
Graphics4::VertexElement element = structure.elements[i];
switch (element.data) {
case Graphics4::ColorVertexData:
myStride += 1 * 4;
break;
case Graphics4::Float1VertexData:
myStride += 1 * 4;
break;
case Graphics4::Float2VertexData:
myStride += 2 * 4;
break;
case Graphics4::Float3VertexData:
myStride += 3 * 4;
break;
case Graphics4::Float4VertexData:
myStride += 4 * 4;
break;
case Graphics4::Float4x4VertexData:
myStride += 4 * 4 * 4;
break;
}
}
this->structure = structure;
glGenBuffers(1, &bufferId);
glCheckErrors();
data = new float[vertexCount * myStride / 4];
}
Graphics3::VertexBuffer::~VertexBuffer() {
unset();
delete[] data;
}
float *Graphics3::VertexBuffer::lock() {
return data;
}
/*
// TODO: FIXME!
float* VertexBuffer::lock(int start, int count) {
myCount = count;
return nullptr;//&buffer[start * 9];
}
*/
void Graphics3::VertexBuffer::unlock() {
glBindBuffer(GL_ARRAY_BUFFER, bufferId);
glCheckErrors();
glBufferData(GL_ARRAY_BUFFER, myStride * myCount, data, GL_STATIC_DRAW);
glCheckErrors();
#ifndef NDEBUG
initialized = true;
#endif
}
int Graphics3::VertexBuffer::_set(int offset) {
assert(initialized); // Vertex Buffer is used before lock/unlock was called
int offsetoffset = setVertexAttributes(offset);
if (IndexBuffer::current != nullptr)
IndexBuffer::current->_set();
return offsetoffset;
}
void VertexBufferImpl::unset() {
if ((void *)current == (void *)this)
current = nullptr;
}
int Graphics3::VertexBuffer::count() {
return myCount;
}
int Graphics3::VertexBuffer::stride() {
return myStride;
}
int VertexBufferImpl::setVertexAttributes(int offset) {
glBindBuffer(GL_ARRAY_BUFFER, bufferId);
glCheckErrors();
// Enable vertex attributes
unsigned int usedAttribsMask = 0;
int internaloffset = 0;
int actualIndex = 0;
for (int index = 0; index < structure.size; ++index) {
Graphics4::VertexElement element = structure.elements[index];
int size = 0;
GLenum type = GL_FLOAT;
switch (element.data) {
case Graphics4::ColorVertexData:
size = 4;
type = GL_UNSIGNED_BYTE;
break;
case Graphics4::Float1VertexData:
size = 1;
break;
case Graphics4::Float2VertexData:
size = 2;
break;
case Graphics4::Float3VertexData:
size = 3;
break;
case Graphics4::Float4VertexData:
size = 4;
break;
case Graphics4::Float4x4VertexData:
size = 16;
break;
}
switch (element.attribute) {
case Graphics4::VertexCoord:
assert(size >= 2 && size <= 4);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(size, type, myStride, reinterpret_cast<const void *>(internaloffset));
break;
case Graphics4::VertexNormal:
assert(size == 3);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(type, myStride, reinterpret_cast<const void *>(internaloffset));
break;
case Graphics4::VertexColor0:
assert(size >= 3 && size <= 4);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(size, type, myStride, reinterpret_cast<const void *>(internaloffset));
break;
case Graphics4::VertexColor1:
assert(size == 3);
glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
glSecondaryColorPointer(size, type, myStride, reinterpret_cast<const void *>(internaloffset));
break;
case Graphics4::VertexTexCoord0:
case Graphics4::VertexTexCoord1:
case Graphics4::VertexTexCoord2:
case Graphics4::VertexTexCoord3:
case Graphics4::VertexTexCoord4:
case Graphics4::VertexTexCoord5:
case Graphics4::VertexTexCoord6:
case Graphics4::VertexTexCoord7:
assert(size >= 1 && size <= 4);
glClientActiveTexture(GL_TEXTURE0 + static_cast<GLenum>(element.attribute - Graphics4::VertexTexCoord0));
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(size, type, myStride, reinterpret_cast<const void *>(internaloffset));
break;
default:
break;
}
usedAttribsMask |= (1u << element.attribute);
++actualIndex;
switch (element.data) {
case Graphics4::ColorVertexData:
internaloffset += 4 * 1;
break;
case Graphics4::Float1VertexData:
internaloffset += 4 * 1;
break;
case Graphics4::Float2VertexData:
internaloffset += 4 * 2;
break;
case Graphics4::Float3VertexData:
internaloffset += 4 * 3;
break;
case Graphics4::Float4VertexData:
internaloffset += 4 * 4;
break;
case Graphics4::Float4x4VertexData:
internaloffset += 4 * 4 * 4;
break;
}
}
// Disable unused vertex attributes
for (int attrib = Graphics4::VertexCoord; attrib <= Graphics4::VertexTexCoord7; ++attrib) {
if ((usedAttribsMask & (1u << attrib)) == 0) {
switch (attrib) {
case Graphics4::VertexCoord:
glDisableClientState(GL_VERTEX_ARRAY);
break;
case Graphics4::VertexNormal:
glDisableClientState(GL_NORMAL_ARRAY);
break;
case Graphics4::VertexColor0:
glDisableClientState(GL_COLOR_ARRAY);
break;
case Graphics4::VertexColor1:
glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
break;
case Graphics4::VertexTexCoord0:
case Graphics4::VertexTexCoord1:
case Graphics4::VertexTexCoord2:
case Graphics4::VertexTexCoord3:
case Graphics4::VertexTexCoord4:
case Graphics4::VertexTexCoord5:
case Graphics4::VertexTexCoord6:
case Graphics4::VertexTexCoord7:
glClientActiveTexture(GL_TEXTURE0 + static_cast<GLenum>(attrib - Graphics4::VertexTexCoord0));
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
break;
default:
break;
}
}
glCheckErrors();
}
return actualIndex;
}

View File

@ -0,0 +1,29 @@
#pragma once
#include <Kore/Graphics4/VertexStructure.h>
namespace Kore {
namespace Graphics3 {
class VertexBuffer;
}
class VertexBufferImpl {
protected:
VertexBufferImpl(int count, int instanceDataStepRate);
void unset();
float *data;
int myCount;
int myStride;
uint bufferId;
// #if defined KINC_ANDROID || defined KINC_EMSCRIPTEN
Graphics4::VertexStructure structure;
// #endif
int instanceDataStepRate;
int setVertexAttributes(int offset);
#ifndef NDEBUG
bool initialized;
#endif
public:
static Graphics3::VertexBuffer *current;
};
}

View File

@ -0,0 +1,71 @@
#pragma once
#ifdef KINC_WINDOWS
#include <GL/gl.h>
#include <GL/glew.h>
#endif
#ifdef KINC_MACOS
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#endif
#ifdef KINC_IOS
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
#import <OpenGLES/ES3/gl.h>
#endif
#ifdef KINC_ANDROID
#include <EGL/egl.h>
#if KINC_ANDROID_API >= 18
#include <GLES3/gl3.h>
#endif
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#endif
#ifdef KINC_EMSCRIPTEN
#define GL_GLEXT_PROTOTYPES
#define EGL_EGLEXT_PROTOTYPES
#include <GL/gl.h>
#endif
#ifdef KINC_LINUX
#include <X11/X.h>
#include <X11/Xlib.h>
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glx.h>
#endif
#ifdef KINC_RASPBERRY_PI
// #define GL_GLEXT_PROTOTYPES
#include "EGL/egl.h"
#include "EGL/eglext.h"
#include "GLES2/gl2.h"
#endif
#include <Kore/Log.h>
#if defined(NDEBUG) || defined(KINC_OSX) || defined(KINC_IOS) || defined(KINC_ANDROID) || 1 // Calling glGetError too early means trouble
#define glCheckErrors() \
{}
#else
#define glCheckErrors() \
{ \
GLenum code = glGetError(); \
while (code != GL_NO_ERROR) { \
Kore::log(Kore::Error, "GL Error %d %s %d\n", code, __FILE__, __LINE__); \
} \
}
#endif
#define glCheckErrors2() \
{ \
GLenum code = glGetError(); \
while (code != GL_NO_ERROR) { \
Kore::log(Kore::Error, "GL Error %d %s %d\n", code, __FILE__, __LINE__); \
} \
}