您没有正确绑定纹理...
- 您绑定 txr1 并渲染整个立方体
- 然后绑定 txr2 并渲染整个立方体
- 然后绑定 txr3 并渲染整个立方体
所以根据深度测试,您看到的只有 txr1 或 txr3 或一些 z 战斗混乱......
您需要将具有相同纹理的单独面分成单独的 VAO/VBO(而不是将整个立方体放在一个中)
或使用 texture "atlas"(将所有纹理放入单个图像中)并校正纹理坐标...例如这样的:
在新版本中也有可能使用无绑定 teturing(从未使用过,但它应该只是将纹理 id 传递给着色器的问题)
[Edit1] 纹理图集
好的,让我们有一些纹理图集,例如这个(我刚刚编译):
您可以看到它的 7x7 方形纹理,因此每个纹理 i = 0,1,2,...,7*7-1 都从纹理坐标开始:
x = (i%7)/7.0;
y = (i/7)/7.0;
所以您只需将x,y 添加到每个面的每个顶点的纹理坐标中,其中i 是所选纹理,并将坐标标准化为单个纹理的大小,因此:
x = ((i%7)+x0)/7.0;
y = ((i/7)+y0)/7.0;
x0,y0 是普通纹理的纹理坐标(就像你现在得到的那样),i 是选定的纹理。如果您有不同的图集布局,则只需更改 7 以获取图集中每个轴的纹理 xcount。
我修改了我的complete GL+GLSL+VAO/VBO C++ example 并为立方体添加了纹理:
//---------------------------------------------------------------------------
//--- GL simple ver: 1.002 --------------------------------------------------
//---------------------------------------------------------------------------
// [complete GL+GLSL+VAO/VBO C++ example](https://stackoverflow.com/a/31913542/2521214)
//---------------------------------------------------------------------------
#define GLEW_STATIC
#include "glew.c"
#include <gl\gl.h>
#include <gl\glu.h>
//---------------------------------------------------------------------------
//--- OpenGL GL example -----------------------------------------------------
//---------------------------------------------------------------------------
int xs,ys; // screen size
HDC hdc=NULL; // device context
HGLRC hrc=NULL; // rendering context
int gl_inicialized=0;
int gl_init(HWND Handle);
void gl_exit();
void gl_draw();
void gl_resize(int _xs,int _ys);
//---------------------------------------------------------------------------
//--- OpenGL GLSL example ---------------------------------------------------
//---------------------------------------------------------------------------
GLint prog_id=0, // whole program
vert_id=0, // vertex shader
geom_id=0, // geometry shader
frag_id=0; // fragment shader
char glsl_log[4096];// compile/link GLSL log
int glsl_logs=0;
void glsl_init(char *vert,char *frag); // create/compile/link GLSL program
void glsl_exit();
//---------------------------------------------------------------------------
//--- OpenGL VAO example ----------------------------------------------------
//---------------------------------------------------------------------------
#pragma pack(1)
// #define vao_indices
GLuint vbo[5]={-1,-1,-1,-1,-1};
GLuint vao[5]={-1,-1,-1,-1,-1};
const GLfloat vao_pos[]=
{
// x y z //ix
-1.0,+1.0,-1.0, //0
+1.0,+1.0,-1.0, //1
+1.0,-1.0,-1.0, //2
-1.0,-1.0,-1.0, //3
-1.0,-1.0,+1.0, //4
+1.0,-1.0,+1.0, //5
+1.0,+1.0,+1.0, //6
-1.0,+1.0,+1.0, //7
#ifndef vao_indices
-1.0,-1.0,-1.0, //3
+1.0,-1.0,-1.0, //2
+1.0,-1.0,+1.0, //5
-1.0,-1.0,+1.0, //4
+1.0,-1.0,-1.0, //2
+1.0,+1.0,-1.0, //1
+1.0,+1.0,+1.0, //6
+1.0,-1.0,+1.0, //5
+1.0,+1.0,-1.0, //1
-1.0,+1.0,-1.0, //0
-1.0,+1.0,+1.0, //7
+1.0,+1.0,+1.0, //6
-1.0,+1.0,-1.0, //0
-1.0,-1.0,-1.0, //3
-1.0,-1.0,+1.0, //4
-1.0,+1.0,+1.0, //7
#endif
};
const GLfloat vao_txr[]=
{
// x y //ix
(0.0+0.0)/7.0,(5.0+1.0)/7.0, //0
(0.0+1.0)/7.0,(5.0+1.0)/7.0, //1
(0.0+1.0)/7.0,(5.0+0.0)/7.0, //2
(0.0+0.0)/7.0,(5.0+0.0)/7.0, //3
(5.0+0.0)/7.0,(5.0+0.0)/7.0, //4
(5.0+1.0)/7.0,(5.0+0.0)/7.0, //5
(5.0+1.0)/7.0,(5.0+1.0)/7.0, //6
(5.0+0.0)/7.0,(5.0+1.0)/7.0, //7
#ifndef vaices
(5.0+0.0)/7.0,(4.0+0.0)/7.0, //3
(5.0+1.0)/7.0,(4.0+0.0)/7.0, //2
(5.0+1.0)/7.0,(4.0+1.0)/7.0, //5
(5.0+0.0)/7.0,(4.0+1.0)/7.0, //4
(3.0+1.0)/7.0,(2.0+0.0)/7.0, //2
(3.0+1.0)/7.0,(2.0+1.0)/7.0, //1
(3.0+0.0)/7.0,(2.0+1.0)/7.0, //6
(3.0+0.0)/7.0,(2.0+0.0)/7.0, //5
(0.0+1.0)/7.0,(6.0+1.0)/7.0, //1
(0.0+0.0)/7.0,(6.0+1.0)/7.0, //0
(0.0+0.0)/7.0,(6.0+0.0)/7.0, //7
(0.0+1.0)/7.0,(6.0+0.0)/7.0, //6
(2.0+1.0)/7.0,(6.0+1.0)/7.0, //0
(2.0+1.0)/7.0,(6.0+0.0)/7.0, //3
(2.0+0.0)/7.0,(6.0+0.0)/7.0, //4
(2.0+0.0)/7.0,(6.0+1.0)/7.0, //7
#endif
};
const GLfloat vao_col[]=
{
// r g b //ix
0.0,0.0,0.0, //0
1.0,0.0,0.0, //1
1.0,1.0,0.0, //2
0.0,1.0,0.0, //3
0.0,0.0,1.0, //4
1.0,0.0,1.0, //5
1.0,1.0,1.0, //6
0.0,1.0,1.0, //7
#ifndef vao_indices
0.0,0.0,0.0, //0
1.0,0.0,0.0, //1
1.0,0.0,1.0, //5
0.0,0.0,1.0, //4
1.0,0.0,0.0, //1
1.0,1.0,0.0, //2
1.0,1.0,1.0, //6
1.0,0.0,1.0, //5
1.0,1.0,0.0, //2
0.0,1.0,0.0, //3
0.0,1.0,1.0, //7
1.0,1.0,1.0, //6
0.0,1.0,0.0, //3
0.0,0.0,0.0, //0
0.0,0.0,1.0, //4
0.0,1.0,1.0, //7
#endif
};
#ifndef vao_indices
const GLfloat vao_nor[]=
{
// nx ny nz //ix
0.0, 0.0,-1.0, //0
0.0, 0.0,-1.0, //1
0.0, 0.0,-1.0, //2
0.0, 0.0,-1.0, //3
0.0, 0.0,+1.0, //4
0.0, 0.0,+1.0, //5
0.0, 0.0,+1.0, //6
0.0, 0.0,+1.0, //7
0.0,-1.0, 0.0, //0
0.0,-1.0, 0.0, //1
0.0,-1.0, 0.0, //5
0.0,-1.0, 0.0, //4
+1.0, 0.0, 0.0, //1
+1.0, 0.0, 0.0, //2
+1.0, 0.0, 0.0, //6
+1.0, 0.0, 0.0, //5
0.0,+1.0, 0.0, //2
0.0,+1.0, 0.0, //3
0.0,+1.0, 0.0, //7
0.0,+1.0, 0.0, //6
-1.0, 0.0, 0.0, //3
-1.0, 0.0, 0.0, //0
-1.0, 0.0, 0.0, //4
-1.0, 0.0, 0.0, //7
};
#endif
#ifdef vao_indices
const GLuint vao_ix[]=
{
0,1,2,3,
4,5,6,7,
3,2,5,4,
2,1,6,5,
1,0,7,6,
0,3,4,7,
};
#endif
#pragma pack()
void vao_init();
void vao_exit();
void vao_draw();
//---------------------------------------------------------------------------
//--- bodies: ---------------------------------------------------------------
//---------------------------------------------------------------------------
int gl_init(HWND Handle)
{
if (gl_inicialized) return 1;
hdc = GetDC(Handle); // get device context
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory( &pfd, sizeof( pfd ) ); // set the pixel format for the DC
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 24;
pfd.iLayerType = PFD_MAIN_PLANE;
SetPixelFormat(hdc,ChoosePixelFormat(hdc, &pfd),&pfd);
hrc = wglCreateContext(hdc); // create current rendering context
if(hrc == NULL)
{
ShowMessage("Could not initialize OpenGL Rendering context !!!");
gl_inicialized=0;
return 0;
}
if(wglMakeCurrent(hdc, hrc) == false)
{
ShowMessage("Could not make current OpenGL Rendering context !!!");
wglDeleteContext(hrc); // destroy rendering context
gl_inicialized=0;
return 0;
}
gl_resize(1,1);
glEnable(GL_DEPTH_TEST); // Zbuf
glDisable(GL_CULL_FACE); // vynechavaj odvratene steny
glDisable(GL_TEXTURE_2D); // pouzivaj textury, farbu pouzivaj z textury
glDisable(GL_BLEND); // priehladnost
glShadeModel(GL_SMOOTH); // gourard shading
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // background color
gl_inicialized=1;
glewInit();
return 1;
}
//---------------------------------------------------------------------------
void gl_exit()
{
if (!gl_inicialized) return;
wglMakeCurrent(NULL, NULL); // release current rendering context
wglDeleteContext(hrc); // destroy rendering context
gl_inicialized=0;
}
//---------------------------------------------------------------------------
void gl_resize(int _xs,int _ys)
{
xs=_xs;
ys=_ys;
if (xs<=0) xs = 1; // Prevent a divide by zero
if (ys<=0) ys = 1;
if (!gl_inicialized) return;
glViewport(0,0,xs,ys); // Set Viewport to window dimensions
glMatrixMode(GL_PROJECTION); // operacie s projekcnou maticou
glLoadIdentity(); // jednotkova matica projekcie
gluPerspective(30,float(xs)/float(ys),0.1,100.0); // matica=perspektiva,120 stupnov premieta z viewsize do 0.1
glMatrixMode(GL_TEXTURE); // operacie s texturovou maticou
glLoadIdentity(); // jednotkova matica textury
glMatrixMode(GL_MODELVIEW); // operacie s modelovou maticou
glLoadIdentity(); // jednotkova matica modelu (objektu)
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void glsl_init(char *vert,char *geom,char *frag)
{
const int _size=1024;
GLint status,siz=0,i;
const char * VS = vert;
const char * GS = geom;
const char * FS = frag;
glsl_logs=0;
if (prog_id<=0) prog_id=glCreateProgram();
if (vert_id<=0) vert_id=glCreateShader(GL_VERTEX_SHADER); else glDetachShader(prog_id,vert_id);
if (vert)
{
glShaderSource(vert_id, 1, &VS,NULL);
glCompileShader(vert_id);
glAttachShader(prog_id,vert_id);
glGetShaderiv(vert_id,GL_COMPILE_STATUS,&status);
const char t[]="[Vertex]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
glGetShaderInfoLog(vert_id,_size,&siz,glsl_log+glsl_logs);
glsl_logs+=siz;
}
if (geom_id<=0) geom_id=glCreateShader(GL_GEOMETRY_SHADER); else glDetachShader(prog_id,geom_id);
if (geom)
{
glShaderSource(geom_id, 1, &GS,NULL);
glCompileShader(geom_id);
glAttachShader(prog_id,geom_id);
glGetShaderiv(geom_id,GL_COMPILE_STATUS,&status);
const char t[]="[Geometry]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
glGetShaderInfoLog(geom_id,_size,&siz,glsl_log+glsl_logs);
glsl_logs+=siz;
}
if (frag_id<=0) frag_id=glCreateShader(GL_FRAGMENT_SHADER); else glDetachShader(prog_id,frag_id);
if (frag)
{
glShaderSource(frag_id, 1, &FS,NULL);
glCompileShader(frag_id);
glAttachShader(prog_id,frag_id);
glGetShaderiv(frag_id,GL_COMPILE_STATUS,&status);
const char t[]="[Fragment]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
glGetShaderInfoLog(frag_id,_size,&siz,glsl_log+glsl_logs);
glsl_logs+=siz;
}
glLinkProgram(prog_id);
glGetProgramiv(prog_id,GL_LINK_STATUS,&status);
const char t[]="[Program]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
glGetProgramInfoLog(prog_id,_size,&siz,glsl_log+glsl_logs);
glsl_logs+=siz;
glReleaseShaderCompiler();
glsl_log[glsl_logs]=0;
}
//------------------------------------------------------------------------------
void glsl_exit()
{
glUseProgram(0);
if (vert_id>0) { glDetachShader(prog_id,vert_id); glDeleteShader(vert_id); }
if (geom_id>0) { glDetachShader(prog_id,geom_id); glDeleteShader(geom_id); }
if (frag_id>0) { glDetachShader(prog_id,frag_id); glDeleteShader(frag_id); }
if (prog_id>0) { glDeleteShader(prog_id); }
glsl_log[0]=0;
}
//---------------------------------------------------------------------------
//------------------------------------------------------------------------------
void vao_init()
{
GLuint i;
glGenVertexArrays(4,vao);
glGenBuffers(4,vbo);
glBindVertexArray(vao[0]);
i=0; // vertex
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_pos),vao_pos,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
i=1; // indices
#ifdef vao_indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(vao_ix),vao_ix,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribIPointer(i,4,GL_UNSIGNED_INT,0,0);
#endif
i=2; // normal
#ifndef vao_indices
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_nor),vao_nor,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
#endif
i=3; // color
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_col),vao_col,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
i=4; // textures
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_txr),vao_txr,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,2,GL_FLOAT,GL_FALSE,0,0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glDisableVertexAttribArray(4);
}
//---------------------------------------------------------------------------
void vao_exit()
{
glDeleteVertexArrays(5,vao);
glDeleteBuffers(5,vbo);
}
//---------------------------------------------------------------------------
void vao_draw()
{
glBindVertexArray(vao[0]);
#ifndef vao_indices
glDrawArrays(GL_QUADS,0,sizeof(vao_pos)/sizeof(vao_pos[0])); // QUADS ... no indices
#endif
#ifdef vao_indices
glDrawElements(GL_QUADS,sizeof(vao_ix)/sizeof(vao_ix[0]),GL_UNSIGNED_INT,0); // indices (choose just one line not both !!!)
#endif
glBindVertexArray(0);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
您需要将纹理添加到着色器并将采样器单元与纹理坐标一起传递。这也不适用于启用索引,因为该示例不是为此而构建的,我懒得重新编码它。这里重要的是:
const GLfloat vao_txr[]=
{
// x y //ix
(0.0+0.0)/7.0,(5.0+1.0)/7.0, //0
(0.0+1.0)/7.0,(5.0+1.0)/7.0, //1
(0.0+1.0)/7.0,(5.0+0.0)/7.0, //2
(0.0+0.0)/7.0,(5.0+0.0)/7.0, //3
(5.0+0.0)/7.0,(5.0+0.0)/7.0, //4
(5.0+1.0)/7.0,(5.0+0.0)/7.0, //5
(5.0+1.0)/7.0,(5.0+1.0)/7.0, //6
(5.0+0.0)/7.0,(5.0+1.0)/7.0, //7
#ifndef vaices
(5.0+0.0)/7.0,(4.0+0.0)/7.0, //3
(5.0+1.0)/7.0,(4.0+0.0)/7.0, //2
(5.0+1.0)/7.0,(4.0+1.0)/7.0, //5
(5.0+0.0)/7.0,(4.0+1.0)/7.0, //4
(3.0+1.0)/7.0,(2.0+0.0)/7.0, //2
(3.0+1.0)/7.0,(2.0+1.0)/7.0, //1
(3.0+0.0)/7.0,(2.0+1.0)/7.0, //6
(3.0+0.0)/7.0,(2.0+0.0)/7.0, //5
(0.0+1.0)/7.0,(6.0+1.0)/7.0, //1
(0.0+0.0)/7.0,(6.0+1.0)/7.0, //0
(0.0+0.0)/7.0,(6.0+0.0)/7.0, //7
(0.0+1.0)/7.0,(6.0+0.0)/7.0, //6
(2.0+1.0)/7.0,(6.0+1.0)/7.0, //0
(2.0+1.0)/7.0,(6.0+0.0)/7.0, //3
(2.0+0.0)/7.0,(6.0+0.0)/7.0, //4
(2.0+0.0)/7.0,(6.0+1.0)/7.0, //7
#endif
};
如您所见,坐标的形式为start_of_texture+texture_coordinate,我从图集中为每张脸选择了 6 种不同的纹理...
这里预览(禁用颜色以便纹理颜色更明显):
为了完整起见,着色器(但是您的纹理可以正常工作,因此无需更改您的):
// Fragment
#version 400 core
#extension GL_ARB_explicit_uniform_location : enable
layout(location =64) uniform vec3 lt_pnt_pos;// point light source position [GCS]
layout(location =67) uniform vec3 lt_pnt_col;// point light source color&strength
layout(location =70) uniform vec3 lt_amb_col;// ambient light source color&strength
layout(location =73) uniform sampler2D txr;
in vec3 pixel_pos; // fragment position [GCS]
in vec3 pixel_col; // fragment surface color
in vec3 pixel_nor; // fragment surface normal [GCS]
in vec2 pixel_txr; // fragment texture coord
out vec4 col;
void main()
{
float li;
vec3 c,lt_dir;
lt_dir=normalize(lt_pnt_pos-pixel_pos); // vector from fragment to point light source in [GCS]
li=dot(pixel_nor,lt_dir);
if (li<0.0) li=0.0;
c =texture(txr,pixel_txr).rgb;
// c*=pixel_col;
c*=(lt_amb_col+(lt_pnt_col*li));
col=vec4(c,1.0);
}
// Vertex
#version 400 core
#extension GL_ARB_explicit_uniform_location : enable
layout(location = 0) in vec3 pos;
layout(location = 2) in vec3 nor;
layout(location = 3) in vec3 col;
layout(location = 4) in vec2 txr;
layout(location = 0) uniform mat4 m_model; // model matrix
layout(location =16) uniform mat4 m_normal; // model matrix with origin=(0,0,0)
layout(location =32) uniform mat4 m_view; // inverse of camera matrix
layout(location =48) uniform mat4 m_proj; // projection matrix
out vec3 pixel_pos; // fragment position [GCS]
out vec3 pixel_col; // fragment surface color
out vec3 pixel_nor; // fragment surface normal [GCS]
out vec2 pixel_txr; // fragment texture coord
void main()
{
pixel_col=col;
pixel_pos=(m_model*vec4(pos,1)).xyz;
pixel_nor=(m_normal*vec4(nor,1)).xyz;
pixel_txr=txr;
gl_Position=m_proj*m_view*m_model*vec4(pos,1);
}
这里是我的窗口的 C++/VCL 代码:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <jpeg.hpp>
#pragma hdrstop
#include "Unit1.h"
#include "gl_simple.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
GLfloat lt_pnt_pos[3]={+2.5,+2.5,+2.5};
GLfloat lt_pnt_col[3]={0.8,0.8,0.8};
GLfloat lt_amb_col[3]={0.2,0.2,0.2};
GLuint txrid=0;
//---------------------------------------------------------------------------
void gl_draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
// load values into shader
GLint i,id;
GLfloat m[16];
glUseProgram(prog_id);
/*
id=glGetUniformLocation(prog_id,"lt_pnt_pos"); glUniform3fv(id,1,lt_pnt_pos);
id=glGetUniformLocation(prog_id,"lt_pnt_col"); glUniform3fv(id,1,lt_pnt_col);
id=glGetUniformLocation(prog_id,"lt_amb_col"); glUniform3fv(id,1,lt_amb_col);
glGetFloatv(GL_MODELVIEW_MATRIX,m);
id=glGetUniformLocation(prog_id,"m_model" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
m[12]=0.0; m[13]=0.0; m[14]=0.0;
id=glGetUniformLocation(prog_id,"m_normal" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
for (i=0;i<16;i++) m[i]=0.0; m[0]=1.0; m[5]=1.0; m[10]=1.0; m[15]=1.0;
id=glGetUniformLocation(prog_id,"m_view" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
glGetFloatv(GL_PROJECTION_MATRIX,m);
id=glGetUniformLocation(prog_id,"m_proj" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
*/
id=64; glUniform3fv(id,1,lt_pnt_pos);
id=67; glUniform3fv(id,1,lt_pnt_col);
id=70; glUniform3fv(id,1,lt_amb_col);
id=73; glUniform1i(id,0); // texture unit
glGetFloatv(GL_MODELVIEW_MATRIX,m);
id=0; glUniformMatrix4fv(id,1,GL_FALSE,m);
m[12]=0.0; m[13]=0.0; m[14]=0.0;
id=16; glUniformMatrix4fv(id,1,GL_FALSE,m);
for (i=0;i<16;i++) m[i]=0.0; m[0]=1.0; m[5]=1.0; m[10]=1.0; m[15]=1.0;
id=32; glUniformMatrix4fv(id,1,GL_FALSE,m);
glGetFloatv(GL_PROJECTION_MATRIX,m);
id=48; glUniformMatrix4fv(id,1,GL_FALSE,m);
// draw VAO cube
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,txrid);
vao_draw();
glBindTexture(GL_TEXTURE_2D,0);
glDisable(GL_TEXTURE_2D);
// turn of shader
glUseProgram(0);
// render the cube in old style GL
if (0)
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
#ifndef vao_indices
glBegin(GL_QUADS);
for (int i=0;i<6*4*3;i+=3)
{
glNormal3fv(vao_nor+i);
glColor3fv (vao_col+i);
glVertex3fv(vao_pos+i);
}
glEnd();
#else
int i,j,k;
const GLfloat vao_nor[]=
{
// nx ny nz
0.0, 0.0,-1.0,
0.0, 0.0,+1.0,
0.0,-1.0, 0.0,
+1.0, 0.0, 0.0,
0.0,+1.0, 0.0,
-1.0, 0.0, 0.0,
};
glBegin(GL_QUADS);
for (j=0;j<6*4;j++)
{
i=vao_ix[j]; i+=i+i;
k=j>>2; k+=k+k;
glNormal3fv(vao_nor+k);
glColor3fv (vao_col+i);
glVertex3fv(vao_pos+i);
}
glEnd();
#endif
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
}
// rotate the cube to see animation
glMatrixMode(GL_MODELVIEW);
glRotatef(1.0,0.0,1.0,0.0);
glRotatef(1.0,1.0,0.0,0.0);
// render point light source in [GCS]
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
GLfloat x,y,z,d=0.25;
x=lt_pnt_pos[0];
y=lt_pnt_pos[1];
z=lt_pnt_pos[2];
glBegin(GL_LINES);
glColor3fv(lt_pnt_col);
glVertex3f(x-d,y,z);
glVertex3f(x+d,y,z);
glVertex3f(x,y-d,z);
glVertex3f(x,y+d,z);
glVertex3f(x,y,z-d);
glVertex3f(x,y,z+d);
glEnd();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glFlush();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
gl_init(Handle);
// load shaders
int hnd,siz; char vertex[4096],fragment[4096];
hnd=FileOpen("normal_shading.glsl_vert",fmOpenRead); siz=FileSeek(hnd,0,2); FileSeek(hnd,0,0); FileRead(hnd,vertex ,siz); vertex [siz]=0; FileClose(hnd);
hnd=FileOpen("normal_shading.glsl_frag",fmOpenRead); siz=FileSeek(hnd,0,2); FileSeek(hnd,0,0); FileRead(hnd,fragment,siz); fragment[siz]=0; FileClose(hnd);
glsl_init(vertex,NULL,fragment);
hnd=FileCreate("GLSL.txt"); FileWrite(hnd,glsl_log,glsl_logs); FileClose(hnd);
// load texture atlas
Byte q;
unsigned int *pp;
int xs,ys,x,y,adr,*txr;
union { unsigned int c32; Byte db[4]; } c;
TJPEGImage *jpg=new TJPEGImage;
Graphics::TBitmap *bmp=new Graphics::TBitmap;
if (bmp)
{
if (jpg)
{
jpg->LoadFromFile("textures128x128.jpg");
bmp->Assign(jpg);
delete jpg;
}
glGenTextures(1,&txrid);
bmp->HandleType=bmDIB; // allow direct access to pixels
bmp->PixelFormat=pf32bit; // set pixel to 32bit so int is the same size as pixel
xs=bmp->Width; // resolution should be power of 2
ys=bmp->Height;
txr=new int[xs*ys]; // create linear framebuffer
for(adr=0,y=0;y<ys;y++)
{
pp=(unsigned int*)bmp->ScanLine[y];
for(x=0;x<xs;x++,adr++)
{
// rgb2bgr and copy bmp -> txr[]
c.c32=pp[x];
q =c.db[2];
c.db[2]=c.db[0];
c.db[0]=q;
txr[adr]=c.c32;
}
}
glEnable(GL_TEXTURE_2D); // copy it to gfx card
glBindTexture(GL_TEXTURE_2D,txrid);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xs, ys, 0, GL_RGBA, GL_UNSIGNED_BYTE, txr);
glDisable(GL_TEXTURE_2D);
delete[] txr;
delete bmp;
}
vao_init();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
glDeleteTextures(1,&txrid);
gl_exit();
glsl_exit();
vao_exit();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
gl_resize(ClientWidth,ClientHeight);
glMatrixMode(GL_PROJECTION);
glTranslatef(0,0,-15.0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
gl_draw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
gl_draw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled)
{
GLfloat dz=2.0;
if (WheelDelta<0) dz=-dz;
glMatrixMode(GL_PROJECTION);
glTranslatef(0,0,dz);
gl_draw();
}
//---------------------------------------------------------------------------
同样,大部分代码并不重要,您只需查找与 vao_ 相关的代码即可。