forked from LeenkxTeam/LNXSDK
Update Files
This commit is contained in:
@ -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
|
||||
}
|
@ -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;
|
||||
};
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "IndexBufferImpl.h"
|
||||
#include "RenderTargetImpl.h"
|
||||
#include "TextureImpl.h"
|
||||
#include "VertexBufferImpl.h"
|
@ -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;
|
||||
}
|
@ -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;
|
||||
};
|
||||
}
|
@ -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);
|
||||
}
|
@ -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;
|
||||
};
|
||||
}
|
1073
Kha/Kinc/Backends/Graphics3/OpenGL1/Sources/kinc/backend/OpenGL.cpp
Normal file
1073
Kha/Kinc/Backends/Graphics3/OpenGL1/Sources/kinc/backend/OpenGL.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <Kore/Graphics1/Image.h>
|
||||
#include <Kore/Graphics3/Graphics.h>
|
||||
#include <Kore/Math/Matrix.h>
|
@ -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;
|
||||
}
|
@ -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;
|
||||
};
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
};
|
||||
}
|
@ -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) {}
|
@ -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;
|
||||
};
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
};
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
};
|
||||
}
|
@ -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__); \
|
||||
} \
|
||||
}
|
Reference in New Issue
Block a user