使用VAO和VBO我已经提出了这个代码,它将一堆立方体渲染成一个巨大的块,所有这些都具有相同的设置颜色方案:
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#define WIDTH 0x320
#define HEIGHT 0x258
#define GLUT_KEY_LSHIFT 112
#define QUIT 0x11
#define ESC 0x1B
typedef char* string;
typedef struct vertex {
float x;
float y;
float z;
} Vertex;
float angle = 0.0;
float deltaX, deltaY;
float deltaS, deltaSt;
float deltaUp;
float vx, vz, vy;
float x = 0.0f, y = 0.0f, z = 0.0f;
float defaultSpeed = 1.0f;
float speed = 1.0f;
float lastMousePosY = HEIGHT / 2;
float lastMousePosX = WIDTH / 2;
int nFrames;
double lastTime;
GLint up, down;
GLuint vbo0, vbo1, ibo, vao;
GLint indexAmnt, vertexAmnt, colorAmnt;
GLint menuId;
GLenum mode;
int release;
int xBlocks = 30;
int yBlocks = 4;
int zBlocks = 16;
void direction(float delta_h, float delta_v)
{
angle += delta_h;
vx = sin(angle);
vz = -cos(angle);
vy += sin(delta_v) * cos(delta_v);
}
void position(float delta_x, float delta_z)
{
x += delta_z * vx * speed;
z += delta_z * vz * speed;
x += delta_x * -vz * speed;
z += delta_x * vx * speed;
}
int toRGBA(int r, int g, int b, int a)
{
return ((a << 24) | (b << 16) | (g << 8) | r);
}
Vertex initVector(float x, float y, float z)
{
Vertex v = {.x=x, .y=y, .z=z};
return v;
}
unsigned int initVertexBuffer(Vertex* v)
{
unsigned int vbo_v;
glGenBuffers(1, &vbo_v);
glBindBuffer(GL_ARRAY_BUFFER, vbo_v);
glBufferData(GL_ARRAY_BUFFER, vertexAmnt * sizeof(Vertex), v, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return vbo_v;
}
unsigned int initColorBuffer(int* c)
{
unsigned int vbo_c;
glGenBuffers(1, &vbo_c);
glBindBuffer(GL_ARRAY_BUFFER, vbo_c);
glBufferData(GL_ARRAY_BUFFER, colorAmnt * sizeof(int), c, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return vbo_c;
}
unsigned int initIndexBuffer(int *i)
{
unsigned int ibo_i;
glGenBuffers(1, &ibo_i);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_i);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexAmnt * sizeof(int), i, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
return ibo_i;
}
void menuActions(int value)
{
switch(value)
{
case 1:
mode = GL_LINES;
break;
case 0:
mode = GL_TRIANGLES;
break;
default:
break;
}
}
int createMenu()
{
int menu;
menu = glutCreateMenu(menuActions);
glutAddMenuEntry("On", 1);
glutAddMenuEntry("Off", 0);
return menu;
}
unsigned int initVertexArray()
{
GLuint vao_a;
glGenVertexArrays(1, &vao_a);
glBindVertexArray(vao_a);
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(int), 0);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vbo0);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), 0);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBindVertexArray(0);
return vao_a;
}
void loadgame()
{
Vertex vertices[] = {
initVector(-0.5f, -0.5f, 0.5f),
initVector(0.5f, -0.5f, 0.5f),
initVector(0.5f, 0.5f, 0.5f),
initVector(-0.5f, 0.5f, 0.5f),
initVector(-0.5f, -0.5f, -0.5f),
initVector(0.5f, -0.5f, -0.5f),
initVector(0.5f, 0.5f, -0.5f),
initVector(-0.5f, 0.5f, -0.5f)
};
int colors[] = {
toRGBA(0xff, 0x00, 0x00, 0xff),
toRGBA(0xff, 0xa5, 0x00, 0xff),
toRGBA(0xa5, 0x2a, 0x2a, 0xff),
toRGBA(0x80, 0x00, 0x00, 0xff),
toRGBA(0x00, 0x00, 0xff, 0xff),
toRGBA(0x00, 0xff, 0xff, 0xff),
toRGBA(0x00, 0x80, 0x00, 0xff),
toRGBA(0xad, 0xff, 0x2f, 0xff)
};
int indices[] = {
0, 1, 2, 2, 3, 0,
3, 2, 6, 6, 7, 3,
7, 6, 5, 5, 4, 7,
4, 0, 3, 3, 7, 4,
0, 1, 5, 5, 4, 0,
1, 5, 6, 6, 2, 1
};
vertexAmnt = sizeof(vertices) / sizeof(Vertex);
colorAmnt = sizeof(colors) / sizeof(int);
indexAmnt = sizeof(indices) / sizeof(int);
vbo0 = initVertexBuffer(vertices);
vbo1 = initColorBuffer(colors);
ibo = initIndexBuffer(indices);
vao = initVertexArray();
mode = GL_TRIANGLES;
menuId = createMenu();
glutAttachMenu(GLUT_RIGHT_BUTTON);
glClearColor(0.6f, 0.6f, 1.0f, 1.0f);
lastTime = time(NULL);
}
void input(int key, int ix, int iy)
{
if(key == GLUT_KEY_LSHIFT){ deltaUp = -0.3f; down = 1; }
}
void input_r(int key, int ix, int iy)
{
if(key == GLUT_KEY_LSHIFT) down = 0;
}
void keyboard(unsigned char key, int kx, int ky)
{
if(key == QUIT) exit(0);
if(key == ESC) release = 1;
if(key == 'w') deltaS = 0.5f;
if(key == 's') deltaS = -0.5f;
if(key == 'a') deltaSt = -0.5f;
if(key == 'd') deltaSt = 0.5f;
if(key == 'r') speed = defaultSpeed * 5.0;
if(key == ' '){ deltaUp = 0.3f; up = 1; }
}
void keyboard_r(unsigned char key, int kx, int ky)
{
if(key == ESC) release = 0;
if(key == 'w' || key == 's') deltaS = 0.0f;
if(key == 'a' || key == 'd') deltaSt = 0.0f;
if(key == ' ') up = 0;
if(key == 'r') speed = defaultSpeed;
}
void resetPointer()
{
glutWarpPointer(WIDTH / 2.0, HEIGHT / 2.0);
lastMousePosY = HEIGHT / 2.0;
lastMousePosX = WIDTH / 2.0;
}
void mouse(int mx, int my)
{
if(!release)
{
if(fabs(WIDTH / 2 - mx) > 15 ||
fabs(HEIGHT / 2 - my) > 15)
resetPointer();
else
{
int vMotion = lastMousePosY - my;
int hMotion = lastMousePosX - mx;
deltaX = -hMotion / 25.0;
deltaY = vMotion / 25.0;
lastMousePosY = my;
lastMousePosX = mx;
}
}
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const double w = glutGet(GLUT_WINDOW_WIDTH);
const double h = glutGet(GLUT_WINDOW_HEIGHT);
gluPerspective(45.0, w / h, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x, y, z, x + vx, y + vy, z + vz, 0.0f, 1.0f, 0.0f);
glRotatef(angle, 0.0, 1.0, 0.0);
int i = 0, j = 0, k = 0;
for(; i < yBlocks; i ++)
for(j = -xBlocks / 2; j < xBlocks / 2; j ++)
for(k = -zBlocks / 2; k < zBlocks / 2; k ++)
{
glPushMatrix();
glTranslatef((float)j, -(float)i - 1.7f, (float)k);
glBindVertexArray(vao);
glDrawElements(mode, indexAmnt, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
glPopMatrix();
}
glutSwapBuffers();
}
void update()
{
if(deltaX || deltaY)
direction(deltaX, deltaY);
if(deltaS || deltaSt)
position(deltaSt, deltaS);
deltaX *= 0.9f;
deltaY *= 0.9f;
if(up == 0 && down == 0)
deltaUp *= 0.9;
if(fabs(deltaUp) >= 0.001f)
y += deltaUp;
double currentTime = time(NULL);
nFrames ++;
if(currentTime - lastTime >= 1.0)
{
//printf("%f ms/frame\n", 1000.0 / (double)nFrames);
printf("%d fps\n", nFrames);
defaultSpeed = (float)nFrames / 60.0f;
nFrames = 0;
lastTime += 1.0;
}
glutPostRedisplay();
}
int main(int argc, string argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("First Person World");
glutDisplayFunc(render);
glutIdleFunc(update);
glutPassiveMotionFunc(mouse);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboard_r);
glutSpecialFunc(input);
glutSpecialUpFunc(input_r);
glutSetCursor(GLUT_CURSOR_NONE);
GLenum error = glewInit();
if(error != GLEW_OK)
{
fprintf(stderr, "Error: %s\n", glewGetErrorString(error));
return -1;
}
glewGetString(GLEW_VERSION);
loadgame();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glutMainLoop();
return 0;
}
此代码有效,但效果很好,但我立即注意到它缺乏加载纹理的能力。所以我研究了如何加载和渲染纹理,但遗憾的是我无法让它工作。到目前为止,关于加载和渲染纹理的内容是:
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <SOIL/SOIL.h>
#define WIDTH 0x320
#define HEIGHT 0x258
#define GLUT_KEY_LSHIFT 112
#define QUIT 0x11
#define ESC 0x1B
typedef char* string;
typedef struct vertex {
float x;
float y;
float z;
float u;
float v;
} Vertex;
float angle = 0.0;
float deltaX, deltaY;
float deltaS, deltaSt;
float deltaUp;
float vx, vz, vy;
float x = 0.0f, y = 0.0f, z = 0.0f;
float defaultSpeed = 1.0f;
float speed = 1.0f;
float lastMousePosY = HEIGHT / 2;
float lastMousePosX = WIDTH / 2;
int nFrames;
double lastTime;
GLint up, down;
GLuint vbo0, vbo1, ibo, vao, texId, progId;
GLint indexAmnt, vertexAmnt, colorAmnt;
GLint menuId;
GLenum mode;
int release;
int xBlocks = 30;
int yBlocks = 4;
int zBlocks = 16;
void direction(float delta_h, float delta_v)
{
angle += delta_h;
vx = sin(angle);
vz = -cos(angle);
vy += sin(delta_v) * cos(delta_v);
}
void position(float delta_x, float delta_z)
{
x += delta_z * vx * speed;
z += delta_z * vz * speed;
x += delta_x * -vz * speed;
z += delta_x * vx * speed;
}
Vertex initVertex(float x, float y, float z, float u, float v)
{
Vertex v0 = {.x=x, .y=y, .z=z, .u=u, .v=v};
return v0;
}
unsigned int initShaderProgram()
{
unsigned int id_p, vs, fs;
const char* vertShader =
"#version 300 es\n"
"in vec2 texcoord;"
"out vec2 TexCoord;"
"void main() {"
" TexCoord = texcoord;"
"}";
const char* fragShader =
"#version 300 es\n"
"uniform sampler2D cubeTex;"
"in vec2 TexCoord;"
"void main() {"
" gl_FragColor = texture(cubeTex, TexCoord);"
"}";
int compile_ok = 0;
vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertShader, NULL);
glCompileShader(vs);
glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);
if(compile_ok == 0)
{
GLsizei slen = 0;
GLint blen = 0;
glGetShaderiv(vs, GL_INFO_LOG_LENGTH , &blen);
fprintf(stderr, "Error in vertex shader:\n");
GLchar* compiler_log = (GLchar*)malloc(blen);
glGetShaderInfoLog(vs, blen, &slen, compiler_log);
fprintf(stderr, "%s\n", compiler_log);
free (compiler_log);
}
fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragShader, NULL);
glCompileShader(fs);
glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);
if(compile_ok == 0)
{
GLsizei slen = 0;
GLint blen = 0;
glGetShaderiv(fs, GL_INFO_LOG_LENGTH , &blen);
fprintf(stderr, "Error in fragment shader:\n");
GLchar* compiler_log = (GLchar*)malloc(blen);
glGetShaderInfoLog(fs, blen, &slen, compiler_log);
fprintf(stderr, "%s\n", compiler_log);
free (compiler_log);
}
id_p = glCreateProgram();
glAttachShader(id_p, vs);
glAttachShader(id_p, fs);
glLinkProgram(id_p);
return id_p;
}
unsigned int initVertexBuffer(Vertex* v)
{
unsigned int vbo_v;
glGenBuffers(1, &vbo_v);
glBindBuffer(GL_ARRAY_BUFFER, vbo_v);
glBufferData(GL_ARRAY_BUFFER, vertexAmnt * sizeof(Vertex), v, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return vbo_v;
}
unsigned int initColorBuffer(int* c)
{
unsigned int vbo_c;
glGenBuffers(1, &vbo_c);
glBindBuffer(GL_ARRAY_BUFFER, vbo_c);
glBufferData(GL_ARRAY_BUFFER, colorAmnt * sizeof(int), c, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return vbo_c;
}
unsigned int initIndexBuffer(int *i)
{
unsigned int ibo_i;
glGenBuffers(1, &ibo_i);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_i);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexAmnt * sizeof(int), i, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
return ibo_i;
}
unsigned int initTexture(const char* filename)
{
unsigned int id_t;
glGenTextures(1, &id_t);
int w, h;
unsigned char* image = SOIL_load_image(filename, &w, &h, 0, SOIL_LOAD_RGB);
glBindTexture(GL_TEXTURE_2D, id_t);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
SOIL_free_image_data(image);
return id_t;
}
void menuActions(int value)
{
switch(value)
{
case 1:
mode = GL_LINES;
break;
case 0:
mode = GL_TRIANGLES;
break;
default:
break;
}
}
int createMenu()
{
int menu;
menu = glutCreateMenu(menuActions);
glutAddMenuEntry("On", 1);
glutAddMenuEntry("Off", 0);
return menu;
}
unsigned int initVertexArray()
{
GLuint vao_a;
glGenVertexArrays(1, &vao_a);
glBindVertexArray(vao_a);
glBindBuffer(GL_ARRAY_BUFFER, vbo0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)offsetof(Vertex, x));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)offsetof(Vertex, u));
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (GLvoid*)offsetof(Vertex, x));
glEnableClientState(GL_VERTEX_ARRAY);
glActiveTexture(GL_TEXTURE0);
glUniform1i(glGetUniformLocation(progId, "cubeTex"), 0);
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid*)offsetof(Vertex, u));
glBindTexture(GL_TEXTURE_2D, texId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBindVertexArray(0);
return vao_a;
}
void loadgame()
{
Vertex vertices[] = {
initVertex(-0.5f, -0.5f, 0.5f, 0.0f, 0.0f),
initVertex(0.5f, -0.5f, 0.5f, 1.0f, 0.0f),
initVertex(0.5f, 0.5f, 0.5f, 1.0f, 1.0f),
initVertex(-0.5f, 0.5f, 0.5f, 0.0f, 1.0f),
initVertex(-0.5f, -0.5f, -0.5f, 0.0f, 0.0f),
initVertex(0.5f, -0.5f, -0.5f, 1.0f, 0.0f),
initVertex(0.5f, 0.5f, -0.5f, 1.0f, 1.0f),
initVertex(-0.5f, 0.5f, -0.5f, 0.0f, 1.0f)
};
int indices[] = {
0, 1, 2, 2, 3, 0,
3, 2, 6, 6, 7, 3,
7, 6, 5, 5, 4, 7,
4, 0, 3, 3, 7, 4,
0, 1, 5, 5, 4, 0,
1, 5, 6, 6, 2, 1
};
vertexAmnt = sizeof(vertices) / sizeof(Vertex);
indexAmnt = sizeof(indices) / sizeof(int);
vbo0 = initVertexBuffer(vertices);
ibo = initIndexBuffer(indices);
texId = initTexture("stone.png");
progId = initShaderProgram();
vao = initVertexArray();
mode = GL_TRIANGLES;
menuId = createMenu();
glutAttachMenu(GLUT_RIGHT_BUTTON);
glClearColor(0.6f, 0.6f, 1.0f, 1.0f);
lastTime = time(NULL);
}
void input(int key, int ix, int iy)
{
if(key == GLUT_KEY_LSHIFT){ deltaUp = -0.3f; down = 1; }
}
void input_r(int key, int ix, int iy)
{
if(key == GLUT_KEY_LSHIFT) down = 0;
}
void keyboard(unsigned char key, int kx, int ky)
{
if(key == QUIT) exit(0);
if(key == ESC) release = 1;
if(key == 'w') deltaS = 0.5f;
if(key == 's') deltaS = -0.5f;
if(key == 'a') deltaSt = -0.5f;
if(key == 'd') deltaSt = 0.5f;
if(key == 'r') speed = defaultSpeed * 5.0;
if(key == ' '){ deltaUp = 0.3f; up = 1; }
}
void keyboard_r(unsigned char key, int kx, int ky)
{
if(key == ESC) release = 0;
if(key == 'w' || key == 's') deltaS = 0.0f;
if(key == 'a' || key == 'd') deltaSt = 0.0f;
if(key == ' ') up = 0;
if(key == 'r') speed = defaultSpeed;
}
void resetPointer()
{
glutWarpPointer(WIDTH / 2.0, HEIGHT / 2.0);
lastMousePosY = HEIGHT / 2.0;
lastMousePosX = WIDTH / 2.0;
}
void mouse(int mx, int my)
{
if(!release)
{
if(fabs(WIDTH / 2 - mx) > 15 ||
fabs(HEIGHT / 2 - my) > 15)
resetPointer();
else
{
int vMotion = lastMousePosY - my;
int hMotion = lastMousePosX - mx;
deltaX = -hMotion / 25.0;
deltaY = vMotion / 25.0;
lastMousePosY = my;
lastMousePosX = mx;
}
}
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const double w = glutGet(GLUT_WINDOW_WIDTH);
const double h = glutGet(GLUT_WINDOW_HEIGHT);
gluPerspective(45.0, w / h, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x, y, z, x + vx, y + vy, z + vz, 0.0f, 1.0f, 0.0f);
glRotatef(angle, 0.0, 1.0, 0.0);
glUseProgram(progId);
int i = 0, j = 0, k = 0;
for(; i < yBlocks; i ++)
for(j = -xBlocks / 2; j < xBlocks / 2; j ++)
for(k = -zBlocks / 2; k < zBlocks / 2; k ++)
{
glPushMatrix();
glTranslatef((float)j, -(float)i - 1.7f, (float)k);
glBindVertexArray(vao);
//glActiveTexture(GL_TEXTURE0);
//glUniform1i(glGetUniformLocation(progId, "cubeTex"), 0);
//glBindTexture(GL_TEXTURE_2D, texId);
glDrawElements(mode, indexAmnt, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
glPopMatrix();
}
glutSwapBuffers();
}
void update()
{
if(deltaX || deltaY)
direction(deltaX, deltaY);
if(deltaS || deltaSt)
position(deltaSt, deltaS);
deltaX *= 0.9f;
deltaY *= 0.9f;
if(up == 0 && down == 0)
deltaUp *= 0.9;
if(fabs(deltaUp) >= 0.001f)
y += deltaUp;
double currentTime = time(NULL);
nFrames ++;
if(currentTime - lastTime >= 1.0)
{
printf("%d fps\n", nFrames);
defaultSpeed = (float)nFrames / 60.0f;
nFrames = 0;
lastTime += 1.0;
}
glutPostRedisplay();
}
int main(int argc, string argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("First Person World");
glutDisplayFunc(render);
glutIdleFunc(update);
glutPassiveMotionFunc(mouse);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboard_r);
glutSpecialFunc(input);
glutSpecialUpFunc(input_r);
glutSetCursor(GLUT_CURSOR_NONE);
GLenum error = glewInit();
if(error != GLEW_OK)
{
fprintf(stderr, "Error: %s\n", glewGetErrorString(error));
return -1;
}
glewGetString(GLEW_VERSION);
loadgame();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glutMainLoop();
return 0;
}
我意识到,即使在我的工作代码中,也可能有许多其他我需要修复的东西,这是我仍在学习的预期。所以,我想知道是否有一种方法我仍然可以使用这些代码来处理纹理(也许我只是错过了一些小的东西?)或者我是否已经开始完全在这段代码中实现纹理(在这种情况下,我将如何处理它?)。
答案 0 :(得分:1)
Haven未对您的代码进行测试,因此这可能会有所帮助或无法帮助。
1
我看到你的顶点缓冲区设置为
{vertex0 [x,y,z,u,v],vertex1 [x,y,z,u,v] ...}
也就是说,你的glVertexAttripPointer调用必须是:
// Okay. vbo0 will be used for later operations.
glBindBuffer(GL_ARRAY_BUFFER, vbo0);
// Okay. We will use attribute at 0.
glEnableVertexAttribArray(0);
// Okay. Vertex position attribute will be sent to attribute at 0.
glVertexAttribPointer( 0 // attribute at 0
, 3 , GL_FLOAT // 3 floating numbers for each vertex
, GL_FALSE // shell not normalize.
, 5 * sizeof(GLfloat) // jump 5 floating numbers to reach next vertex position
, (GLvoid*)0); // start from beginning
glEnableVertexAttribArray(1);
glVertexAttribPointer(1
, 2, GL_FLOAT
, GL_FALSE
, 5 * sizeof(GLfloat)
, (GLvoid*)offsetof(Vertex, u)); // start from fourth floating point number in buffer.
2
//glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (GLvoid*)offsetof(Vertex, x));
这个功能对你没什么用。它会搞乱你的glVertexAttribPointer调用。带他们出去。
3
你的顶点着色器源shell是:
#version 300 es
layout(location=0) in vec3 a_vertexPosition; // attribute at 0 is vertex position
layout(location=1) in vec2 a_TexCoord; // attribute at 1 is uv
out vec2 v_TexCoord;
void main() {
gl_Position = vec4(a_vertexPosition, 1);
v_TexCoord = a_TexCoord;
}
你的片段着色器:
#version 300 es
in vec2 v_TexCoord;
uniform sampler2D u_cubeTexture;
void main()
{
gl_FragColor = texture(u_cubeTexture, v_TexCoord);
}
4
如果您认为您的紫外线没有正确发送,您可以随时通过将紫外线渲染为红色/绿色进行测试。您将获得类似this的内容。
void main()
{
gl_FragColor = vec4(v_TexCoord.x, v_TexCoord.y, 0, 1);
}
5
unsigned int initVertexArray()
{
GLuint vao_a;
...
glActiveTexture(GL_TEXTURE0); // can be moved to different place
glUniform1i(glGetUniformLocation(progId, "cubeTex"), 0); // Meaningless. You don't know what program is currently used.
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid*)offsetof(Vertex, u)); // Bad. Messes up your glVertexAttribPoionter call
glBindTexture(GL_TEXTURE_2D, texId); // can be moved to different place
...
return vao_a;
}
没有理由将纹理和着色器程序绑定为vao初始化的一部分。纹理绑定和程序都不是vao的一部分。 here
6
如果您不确定是否正确创建了纹理,请记住SOIL有一个简单的功能,可以为您完成所有工作。
/**
Loads an image from disk into an OpenGL texture.
\param filename the name of the file to upload as a texture
\param force_channels 0-image format, 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT
\return 0-failed, otherwise returns the OpenGL texture handle
**/
unsigned int
SOIL_load_OGL_texture
(
const char *filename,
int force_channels,
unsigned int reuse_texture_ID,
unsigned int flags
);
7
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const double w = glutGet(GLUT_WINDOW_WIDTH);
const double h = glutGet(GLUT_WINDOW_HEIGHT);
gluPerspective(45.0, w / h, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x, y, z, x + vx, y + vy, z + vz, 0.0f, 1.0f, 0.0f);
glRotatef(angle, 0.0, 1.0, 0.0);
glUseProgram(progId);
int i = 0, j = 0, k = 0;
for(; i < yBlocks; i ++)
for(j = -xBlocks / 2; j < xBlocks / 2; j ++)
for(k = -zBlocks / 2; k < zBlocks / 2; k ++)
{
glPushMatrix();
glTranslatef((float)j, -(float)i - 1.7f, (float)k);
glBindVertexArray(vao);
//glActiveTexture(GL_TEXTURE0);
//glUniform1i(glGetUniformLocation(progId, "cubeTex"), 0);
//glBindTexture(GL_TEXTURE_2D, texId);
glDrawElements(mode, indexAmnt, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
glPopMatrix();
}
glutSwapBuffers();
}
您在此处调用的每个Matrix函数都没有意义。
您的顶点着色器甚至无法使用任何推动的矩阵,因为您从未告诉它。你是ES版本。您无法从顶点着色器访问这些矩阵,如以下存根所述:
(从here归档)
一些框架(特别是OpenGL兼容性配置文件,但是 OpenGL核心配置文件和OpenGL ES 2.x都没有提供 内置制服来访问GLSL中的某些顶点变换 着色器。它们不应该被声明,但这里是声明 指定他们的类型:
uniform mat4 gl_ModelViewMatrix;
uniform mat4 gl_ProjectionMatrix;
uniform mat4 gl_ModelViewProjectionMatrix;
uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];
uniform mat3 gl_NormalMatrix; // transpose of the inverse of the
// upper left 3x3 matrix of gl_ModelViewMatrix
uniform mat4 gl_ModelViewMatrixInverse;
uniform mat4 gl_ProjectionMatrixInverse;
uniform mat4 gl_ModelViewProjectionMatrixInverse;
uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];
uniform mat4 gl_ModelViewMatrixTranspose;
uniform mat4 gl_ProjectionMatrixTranspose;
uniform mat4 gl_ModelViewProjectionMatrixTranspose;
uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];
uniform mat4 gl_ModelViewMatrixInverseTranspose;
uniform mat4 gl_ProjectionMatrixInverseTranspose;
uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;
uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];
如果您使用的是现代OpenGL,那么您将完全按照this文章的说法进行操作。
8
//glActiveTexture(GL_TEXTURE0);
//glUniform1i(glGetUniformLocation(progId, "cubeTex"), 0);
//glBindTexture(GL_TEXTURE_2D, texId);
这部分是正确的。为什么要注释掉?