mirror of
https://github.com/love2d/love.git
synced 2026-08-16 08:11:02 +02:00
Fix issue #292: Can't send arrays to pixeleffects.
Arrays of numbers, vectors and matrices are supported.
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
#include "GLee.h"
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -148,28 +147,28 @@ namespace opengl
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void PixelEffect::sendFloat(const std::string& name, int count, const GLfloat* vec)
|
||||
void PixelEffect::sendFloat(const std::string& name, int size, const GLfloat* vec, int count)
|
||||
{
|
||||
TemporaryAttacher attacher(this);
|
||||
GLint location = getUniformLocation(name);
|
||||
|
||||
if (count < 1 || count > 4) {
|
||||
throw love::Exception("Invalid variable count: %d (expected 1-4).", count);
|
||||
if (size < 1 || size > 4) {
|
||||
throw love::Exception("Invalid variable size: %d (expected 1-4).", size);
|
||||
}
|
||||
|
||||
switch (count) {
|
||||
switch (size) {
|
||||
case 4:
|
||||
glUniform4fv(location, 1, vec);
|
||||
glUniform4fv(location, count, vec);
|
||||
break;
|
||||
case 3:
|
||||
glUniform3fv(location, 1, vec);
|
||||
glUniform3fv(location, count, vec);
|
||||
break;
|
||||
case 2:
|
||||
glUniform2fv(location, 1, vec);
|
||||
glUniform2fv(location, count, vec);
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
glUniform1fv(location, 1, vec);
|
||||
glUniform1fv(location, count, vec);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -177,7 +176,7 @@ namespace opengl
|
||||
checkSetUniformError();
|
||||
}
|
||||
|
||||
void PixelEffect::sendMatrix(const std::string& name, int size, const GLfloat* m)
|
||||
void PixelEffect::sendMatrix(const std::string& name, int size, const GLfloat* m, int count)
|
||||
{
|
||||
TemporaryAttacher attacher(this);
|
||||
GLint location = getUniformLocation(name);
|
||||
@@ -189,14 +188,14 @@ namespace opengl
|
||||
|
||||
switch (size) {
|
||||
case 4:
|
||||
glUniformMatrix4fv(location, 1, GL_FALSE, m);
|
||||
glUniformMatrix4fv(location, count, GL_FALSE, m);
|
||||
break;
|
||||
case 3:
|
||||
glUniformMatrix3fv(location, 1, GL_FALSE, m);
|
||||
glUniformMatrix3fv(location, count, GL_FALSE, m);
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
glUniformMatrix2fv(location, 1, GL_FALSE, m);
|
||||
glUniformMatrix2fv(location, count, GL_FALSE, m);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -257,9 +256,9 @@ namespace opengl
|
||||
if (GL_INVALID_OPERATION == error_code) {
|
||||
throw love::Exception(
|
||||
"Invalid operation:\n"
|
||||
"Trying to send more than one value to a float variable, or"
|
||||
"Size of shader variable does not match indicated size, or"
|
||||
"Invalid variable name.");
|
||||
"- Trying to send the wrong value type to shader variable, or\n"
|
||||
"- Trying to send array values with wrong dimension, or\n"
|
||||
"- Invalid variable name.");
|
||||
}
|
||||
}
|
||||
} // opengl
|
||||
|
||||
@@ -28,8 +28,8 @@ namespace opengl
|
||||
static void detach();
|
||||
static bool isSupported();
|
||||
|
||||
void sendFloat(const std::string& name, int count, const GLfloat* vec);
|
||||
void sendMatrix(const std::string& name, int size, const GLfloat* m);
|
||||
void sendFloat(const std::string& name, int size, const GLfloat* vec, int count);
|
||||
void sendMatrix(const std::string& name, int size, const GLfloat* m, int count);
|
||||
void sendImage(const std::string& name, const Image& image);
|
||||
void sendCanvas(const std::string& name, const Canvas& canvas);
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include "wrap_Image.h"
|
||||
#include "wrap_Canvas.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -21,48 +23,128 @@ namespace opengl
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_PixelEffect_sendFloat(lua_State * L)
|
||||
static int _sendScalars(lua_State * L, PixelEffect * effect, const char * name, int count)
|
||||
{
|
||||
size_t count = lua_gettop(L) - 2;
|
||||
PixelEffect * effect = luax_checkpixeleffect(L, 1);
|
||||
const char* name = luaL_checkstring(L, 2);
|
||||
|
||||
if (count < 1 || count > 4)
|
||||
return luaL_error(L, "Invalid variable count (expected 1-4, got %d).", count);
|
||||
|
||||
float values[4] = {0,0,0,0};
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
values[i] = (float) luaL_checknumber(L, i+1 + 2);
|
||||
|
||||
try {
|
||||
effect->sendFloat(name, count, values);
|
||||
} catch(love::Exception& e) {
|
||||
luaL_error(L, e.what());
|
||||
float * values = new float[count];
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (!lua_isnumber(L, 3 + i)) {
|
||||
delete[] values;
|
||||
return luaL_typerror(L, 3 + i, "number");
|
||||
}
|
||||
values[i] = (float)lua_tonumber(L, 3 + i);
|
||||
}
|
||||
|
||||
try {
|
||||
effect->sendFloat(name, 1, values, count);
|
||||
} catch(love::Exception& e) {
|
||||
delete[] values;
|
||||
return luaL_error(L, e.what());
|
||||
}
|
||||
|
||||
delete[] values;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _sendVectors(lua_State * L, PixelEffect * effect, const char * name, int count)
|
||||
{
|
||||
int dimension = lua_objlen(L, 3);
|
||||
float * values = new float[count * dimension];
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (!lua_istable(L, 3 + i)) {
|
||||
delete[] values;
|
||||
return luaL_typerror(L, 3 + i, "table");
|
||||
}
|
||||
if (lua_objlen(L, 3 + i) != dimension) {
|
||||
delete[] values;
|
||||
return luaL_error(L, "Error in argument %d: Expected table size %d, got %d.",
|
||||
3+i, dimension, lua_objlen(L, 3+i));
|
||||
}
|
||||
|
||||
for (int k = 1; k <= dimension; ++k) {
|
||||
lua_rawgeti(L, 3 + i, k);
|
||||
values[i * dimension + k - 1] = (float)lua_tonumber(L, -1);
|
||||
}
|
||||
lua_pop(L, dimension);
|
||||
}
|
||||
|
||||
try {
|
||||
effect->sendFloat(name, dimension, values, count);
|
||||
} catch(love::Exception& e) {
|
||||
delete[] values;
|
||||
return luaL_error(L, e.what());
|
||||
}
|
||||
|
||||
delete[] values;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_PixelEffect_sendFloat(lua_State * L)
|
||||
{
|
||||
PixelEffect * effect = luax_checkpixeleffect(L, 1);
|
||||
const char* name = luaL_checkstring(L, 2);
|
||||
int count = lua_gettop(L) - 2;
|
||||
|
||||
if (count < 1)
|
||||
return luaL_error(L, "No variable to send.");
|
||||
|
||||
if (lua_isnumber(L, 3))
|
||||
return _sendScalars(L, effect, name, count);
|
||||
else if (lua_istable(L, 3))
|
||||
return _sendVectors(L, effect, name, count);
|
||||
|
||||
return luaL_typerror(L, 3, "number or table");
|
||||
}
|
||||
|
||||
int w_PixelEffect_sendMatrix(lua_State * L)
|
||||
{
|
||||
size_t count = lua_gettop(L) - 3;
|
||||
int count = lua_gettop(L) - 2;
|
||||
PixelEffect * effect = luax_checkpixeleffect(L, 1);
|
||||
const char* name = luaL_checkstring(L, 2);
|
||||
int size = luaL_checkinteger(L, 3);
|
||||
|
||||
if (size < 2 || size > 4)
|
||||
return luaL_error(L, "Invalid matrix size: %dx%d (only 2x2, 3x3 and 4x4 matrices are supported).", count, count);
|
||||
if (!lua_istable(L, 3))
|
||||
return luaL_typerror(L, 3, "matrix table");
|
||||
|
||||
float values[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
values[i] = (float) luaL_checknumber(L, i+1 + 3);
|
||||
lua_getfield(L, 3, "dimension");
|
||||
int dimension = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
try {
|
||||
effect->sendFloat(name, size, values);
|
||||
} catch(love::Exception& e) {
|
||||
luaL_error(L, e.what());
|
||||
if (dimension < 2 || dimension > 4)
|
||||
return luaL_error(L, "Invalid matrix size: %dx%d (only 2x2, 3x3 and 4x4 matrices are supported).",
|
||||
count, count);
|
||||
|
||||
float * values = new float[dimension * dimension * count];
|
||||
for (int i = 0; i < count; ++i) {
|
||||
lua_getfield(L, 3+i, "dimension");
|
||||
if (lua_tointeger(L, -1) != dimension) {
|
||||
// You unlock this door with the key of imagination. Beyond it is
|
||||
// another dimension: a dimension of sound, a dimension of sight,
|
||||
// a dimension of mind. You're moving into a land of both shadow
|
||||
// and substance, of things and ideas. You've just crossed over
|
||||
// into... the Twilight Zone.
|
||||
int other_dimension = lua_tointeger(L, -1);
|
||||
delete[] values;
|
||||
return luaL_error(L, "Invalid matrix size at argument %d: Expected size %dx%d, got %dx%d.",
|
||||
3+i, dimension, dimension, other_dimension, other_dimension);
|
||||
}
|
||||
|
||||
for (int k = 1; k <= dimension*dimension; ++k) {
|
||||
lua_rawgeti(L, 3+i, k);
|
||||
values[i * dimension * dimension + k - 1] = (float)lua_tonumber(L, -1);
|
||||
cout << i << "." << k << " = " << (float)lua_tonumber(L, -1) << endl;
|
||||
}
|
||||
|
||||
lua_pop(L, 1 + dimension);
|
||||
}
|
||||
|
||||
try {
|
||||
effect->sendMatrix(name, dimension, values, count);
|
||||
} catch(love::Exception& e) {
|
||||
delete[] values;
|
||||
return luaL_error(L, e.what());
|
||||
}
|
||||
|
||||
delete[] values;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user