Самое простое для ладьи ie - использовать старый API без шейдеров. Для того, чтобы это работало, вы просто кодируете свои данные в 1D линейный массив с плавающей точкой в диапазоне <0.0,1.0>
, что можно сделать из <-1,+1>
довольно быстро на стороне процессора с единичным значением для l oop, например:
for (i=0;i<size*size;i++) data[i]=0.5*(data[i]+1.0);
Я не использую ни GLUT, ни код для вашей платформы, поэтому я придерживаюсь только рендеринга:
//---------------------------------------------------------------------------
const int size=512; // data resolution
const int size2=size*size;
float data[size2]; // your float size*size data
GLuint txrid=-1; // GL texture ID
//---------------------------------------------------------------------------
void init() // this must be called once (after GL is initialized)
{
int i;
// generate float data
Randomize();
for (i=0;i<size2;i++) data[i]=Random();
// create texture
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,txrid);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);
glDisable(GL_TEXTURE_2D);
}
//---------------------------------------------------------------------------
void exit() // this must be called once (before GL is unitialized)
{
// release texture
glDeleteTextures(1,&txrid);
}
//---------------------------------------------------------------------------
void gl_draw()
{
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// bind texture
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,txrid);
// copy your actual data into it
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE32F_ARB, size, size, 0, GL_LUMINANCE, GL_FLOAT, data);
// render single textured QUAD
glColor3f(1.0,1.0,1.0);
glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0); glVertex2f(-1.0,-1.0);
glTexCoord2f(1.0,0.0); glVertex2f(+1.0,-1.0);
glTexCoord2f(1.0,1.0); glVertex2f(+1.0,+1.0);
glTexCoord2f(0.0,1.0); glVertex2f(-1.0,+1.0);
glEnd();
// unbind texture (so it does not mess with othre rendering)
glBindTexture(GL_TEXTURE_2D,0);
glDisable(GL_TEXTURE_2D);
glFlush();
SwapBuffers(hdc); // ignore this GLUT should make it on its own
}
//---------------------------------------------------------------------------
Вот предварительный просмотр:
Чтобы сделать это, вам нужно вызвать init()
при запуске приложения после того, как GLUT создает контекст GL, и exit()
в конце приложения, прежде чем GLUT закроет контекст GL. gl_draw()
отобразит ваши данные, поэтому их нужно вызывать в событии рисования GLUT.
Если вы не хотите выполнять преобразование диапазона в <0,1>
на стороне процессора, вы можете переместить его в шейдеры (очень простой вершинный и фрагментный шейдеры), но у меня возникло ощущение, что вы ладья ie, и шейдеров было бы просто слишком много для начала. Если вы действительно хотите go, то посмотрите:
Это также охватывает Инициализация GL без GLUT, но на Windows ...
Теперь некоторые примечания к программе выше:
Я использовал GL_LUMINANCE32F_ARB
расширение формата текстуры
это 32-битный формат текстур с плавающей точкой, который не ограничен, поэтому ваши данные остаются как есть. Он должен присутствовать на всех современных gfx HW. Я сделал это, чтобы облегчить переход к последним шейдерам, где вы можете напрямую работать с вашими необработанными данными ...
size
в оригинальной спецификации GL размер текстуры должен быть степенью 2, так что 16,32,64,128,256,512, ... Если нет, вам нужно использовать расширение текстур прямоугольников, но это является родным для gfx HW уже многие годы, поэтому не нужно ничего менять. Но на linux и MA C могут быть проблемы с реализацией GL, поэтому, если что-то не работает, попробуйте использовать мощность 2 размера (на всякий случай) ...
Также не слишком увлекайтесь с размером, поскольку у карт gfx есть ограничения, обычно 2048 - безопасный предел для вещей низкого уровня. Если вам нужно больше, тогда сделайте mosai c из большего числа квадов / текстур
GL_CLAMP_TO_EDGE
, это также расширение (теперь родное для HW), так что ваша текстура координаты go от 0
до 1
вместо от 0+pixel/2
до 1-pixel/2
...
Однако все это не относится к GL 1.0, поэтому вам нужно добавить расширения в ваше приложение (если GLUT или что вы используете, еще не сделали). Все это просто токены / константы, а не вызовы функций, поэтому на случай, если компилятор жалуется, этого должно быть достаточно:
#include <gl\glext.h>
После включения gl.h
или непосредственного добавления определений:
#define GL_CLAMP_TO_EDGE 0x812F
#define GL_LUMINANCE32F_ARB 0x8818
кстати. ваш код не похож на приложение GLUT (но я могу ошибаться, поскольку я его не использую), например, посмотрите:
Ваш заголовок предлагает GLFW3 , что является чем-то совершенно иным (если оно не является производным от GLUT), чем GLUT , поэтому, возможно, вам следует отредактировать теги и OP, чтобы они соответствовали тому, что вы действительно используете / используете .
Теперь шейдеры:
, если вы генерируете свои данные в <-1,+1>
диапазоне:
for (i=0;i<size2;i++) data[i]=(2.0*Random())-1.0;
И используете эти шейдеры:
Вершина:
// Vertex
#version 400 core
layout(location = 0) in vec2 pos; // position
layout(location = 8) in vec2 tex; // texture
out vec2 vpos;
out vec2 vtex;
void main()
{
vpos=pos;
vtex=tex;
gl_Position=vec4(pos,0.0,1.0);
}
Фрагмент:
// Fragment
#version 400 core
uniform sampler2D txr;
in vec2 vpos; // position
in vec2 vtex; // texture
out vec4 col;
void main()
{
vec4 c;
c=texture(txr,vtex);
c=(c+1.0)*0.5;
col=c;
}
Тогда результат тот же (пример более быстрого преобразования на Сторона графического процессора). Однако вам необходимо преобразовать GL_QUADS
в VAO / VBO (, если не используется карта nVidia , но даже тогда вам обязательно следует использовать VBO / VAO).