gpt4 book ai didi

opengl - 在OpenGL中将纹理映射到VBO的问题

转载 作者:行者123 更新时间:2023-12-05 00:42:19 24 4
gpt4 key购买 nike

我无法使用 OpenGL 将纹理正确映射到几何体上。事实上,我似乎甚至打破了过去可以正常工作的颜色插值。我在 C99 中创建了一个使用 SDL、GLee 和 SOIL 的测试用例。

#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <SDL/SDL.h>
#include <GL/GLee.h>
#include <SOIL/SOIL.h>

static const char *vertex_source = " \
uniform mat4 projection; \
uniform mat4 view_model; \
\
attribute vec2 vertex; \
attribute vec2 texcoord; \
attribute vec4 colour; \
\
varying vec2 _texcoord; \
\
void main() \
{ \
gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex, 0, 1); \
_texcoord = texcoord; \
gl_FrontColor = colour; \
} ";

static const char *fragment_source = " \
uniform sampler2D sampler0; \
\
varying vec2 _texcoord; \
\
void main() \
{ \
gl_FragColor = texture2D(sampler0, _texcoord) * 0.01 + gl_Color; \
} ";

typedef struct
{
GLfloat position[2];
GLfloat texcoord[2];
GLubyte colour[4];
} Vertex;

static Vertex verts[] = {
{
.position = { 1, 1 },
.texcoord = { 1, 1 },
.colour = { 255, 0, 0, 255 },
},
{
.position = { -1, 1 },
.texcoord = { 0, 1 },
.colour = { 0, 255, 0, 255 },
},
{
.position = { -1, -1 },
.texcoord = { 0, 0 },
.colour = { 0, 0, 255, 255 },
},
{
.position = { 1, -1 },
.texcoord = { 1, 0 },
.colour = { 255, 255, 0, 255 },
},
};

static GLuint vertex, fragment, program, vbo, texture;
static GLint sampler_loc, vertex_loc, texcoord_loc, colour_loc;

static void init()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_SetVideoMode(800, 800, 0, SDL_OPENGL);

glClearColor(1, 0, 0, 0);

glMatrixMode(GL_PROJECTION);
glOrtho(-1, 1, -1, 1, -1, 1);

/* Shaders */
vertex = glCreateShader(GL_VERTEX_SHADER);
assert(vertex != 0);
fragment = glCreateShader(GL_FRAGMENT_SHADER);
assert(fragment != 0);

GLint length = strlen(vertex_source);
glShaderSource(vertex, 1, &vertex_source, &length);
length = strlen(fragment_source);
glShaderSource(fragment, 1, &fragment_source, &length);

glCompileShader(vertex);
glCompileShader(fragment);

program = glCreateProgram();

glAttachShader(program, vertex);
glAttachShader(program, fragment);

glLinkProgram(program);

sampler_loc = glGetUniformLocation(program, "sampler0");
vertex_loc = glGetAttribLocation(program, "vertex");
texcoord_loc = glGetAttribLocation(program, "texcoord");
colour_loc = glGetAttribLocation(program, "colour");

/* VBO */
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), &verts[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

/* Texture */
texture = SOIL_load_OGL_texture("test.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
assert(texture != 0);
}

static void draw()
{
glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(program);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(sampler_loc, 0);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glScalef(.5, .5, .5);

glBindBuffer(GL_ARRAY_BUFFER, vbo);

glEnableVertexAttribArray(0);

glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, position));
glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, texcoord));
glVertexAttribPointer(colour_loc, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), offsetof(Vertex, colour));

glDrawArrays(GL_QUADS, 0, 4);

glDisableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();

glUseProgram(0);
}

static void shutdown()
{
SDL_Quit();
}

int main()
{
init();
atexit(shutdown);

while(true)
{
static SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
exit(0);
break;

default:
break;
}
}

draw();

SDL_GL_SwapBuffers();

if(glGetError() != GL_NO_ERROR)
{
printf("Error\n");
exit(1);
}
}

return 0;
}

唯一呈现的是 glClearColor 顶部的纯蓝色方 block 。

非常感谢任何帮助。

感谢您的回答,为了完整起见,我附上了固定代码。
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <SDL/SDL.h>
#include <GL/GLee.h>
#include <SOIL/SOIL.h>

static const char *vertex_source = " \
uniform mat4 projection; \
uniform mat4 view_model; \
\
attribute vec2 vertex; \
attribute vec2 texcoord; \
attribute vec4 colour; \
\
varying vec2 _texcoord; \
\
void main() \
{ \
gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex, 0, 1); \
_texcoord = texcoord; \
gl_FrontColor = colour; \
} ";

static const char *fragment_source = " \
uniform sampler2D sampler0; \
\
varying vec2 _texcoord; \
\
void main() \
{ \
gl_FragColor = texture2D(sampler0, _texcoord) + gl_Color; \
} ";

typedef struct
{
GLfloat position[2];
GLfloat texcoord[2];
GLubyte colour[4];
} Vertex;

static Vertex verts[] = {
{
.position = { 1, 1 },
.texcoord = { 1, 1 },
.colour = { 255, 0, 0, 255 },
},
{
.position = { -1, 1 },
.texcoord = { 0, 1 },
.colour = { 0, 255, 0, 255 },
},
{
.position = { -1, -1 },
.texcoord = { 0, 0 },
.colour = { 0, 0, 255, 255 },
},
{
.position = { 1, -1 },
.texcoord = { 1, 0 },
.colour = { 255, 255, 0, 255 },
},
};

static GLuint vertex, fragment, program, vbo, texture;
static GLint sampler_loc, vertex_loc, texcoord_loc, colour_loc;

static void init()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_SetVideoMode(800, 800, 0, SDL_OPENGL);

glClearColor(1, 0, 0, 0);

glMatrixMode(GL_PROJECTION);
glOrtho(-1, 1, -1, 1, -1, 1);

/* Shaders */
vertex = glCreateShader(GL_VERTEX_SHADER);
assert(vertex != 0);
fragment = glCreateShader(GL_FRAGMENT_SHADER);
assert(fragment != 0);

GLint length = strlen(vertex_source);
glShaderSource(vertex, 1, &vertex_source, &length);
length = strlen(fragment_source);
glShaderSource(fragment, 1, &fragment_source, &length);

glCompileShader(vertex);
glCompileShader(fragment);

program = glCreateProgram();

glAttachShader(program, vertex);
glAttachShader(program, fragment);

glLinkProgram(program);

sampler_loc = glGetUniformLocation(program, "sampler0");
vertex_loc = glGetAttribLocation(program, "vertex");
texcoord_loc = glGetAttribLocation(program, "texcoord");
colour_loc = glGetAttribLocation(program, "colour");

glUseProgram(program);
glUniform1i(sampler_loc, 0);
glUseProgram(0);

/* VBO */
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);

glBufferData(GL_ARRAY_BUFFER, sizeof(verts), &verts[0], GL_STATIC_DRAW);
glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, position));
glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, texcoord));
glVertexAttribPointer(colour_loc, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), offsetof(Vertex, colour));

glBindBuffer(GL_ARRAY_BUFFER, 0);

/* Texture */
texture = SOIL_load_OGL_texture("test.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
assert(texture != 0);
}

static void draw()
{
glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(program);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glScalef(.5, .5, .5);

glEnableVertexAttribArray(vertex_loc);
glEnableVertexAttribArray(texcoord_loc);
glEnableVertexAttribArray(colour_loc);

glDrawArrays(GL_QUADS, 0, 4);

glDisableVertexAttribArray(vertex_loc);
glDisableVertexAttribArray(texcoord_loc);
glDisableVertexAttribArray(colour_loc);

glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();

glUseProgram(0);
}

static void shutdown()
{
SDL_Quit();
}

int main()
{
init();
atexit(shutdown);

while(true)
{
static SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
exit(0);
break;

default:
break;
}
}

draw();

SDL_GL_SwapBuffers();

if(glGetError() != GL_NO_ERROR)
{
printf("Error\n");
exit(1);
}
}

return 0;
}

最佳答案

您没有正确启用顶点属性数组。

  • 您启用 0,这甚至可能不是您使用的东西(好吧,实际上,它可能是 vertex_loc,但您不应该依赖它)
  • 您忽略其他 2 个数组

  • 尝试以下操作:
    glEnableVertexAttribArray(vertex_loc);
    glEnableVertexAttribArray(texcoord_loc);
    glEnableVertexAttribArray(colour_loc);

    编辑添加:我不妨指出其他细节:
  • 我只会设置一次采样器位置。设置它往往会在驱动程序中强制执行额外的工作,并且由于您每次只会将其设置为相同的纹理单元,因此您最好在初始化时进行。
  • 你打电话的地方glBindBuffer(GL_ARRAY_BUFFER, 0)没错,但我会把它放在 VertexAttribPointer 调用之后。当前绑定(bind)的缓冲区实际上只是这些调用的一个额外参数......而且它不会影响 glDrawArrays 调用本身。
  • 关于opengl - 在OpenGL中将纹理映射到VBO的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2211910/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com