Problem-mapping-Texturen in OpenGL VBO
Ich habe Probleme dabei, eine textur-map auf die geometrie richtig mit OpenGL. In der Tat habe ich zu haben scheinen sogar gebrochen ist, wird der Farb-interpolation, die gut funktioniert haben. Ich habe einen test-Fall in C99 verwendet SDL, Frohsinn und BODEN.
#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;
}
Das einzige, was macht, dass ist eine einfache Blaue Quadrat auf der Oberseite des glClearColor.
Jede Hilfe sehr geschätzt.
Danke für die Antworten, ich angehängt habe festen code für Vollständigkeit.
#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;
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du bist nicht die Aktivierung der vertex attrib-arrays korrekt.
vertex_loc
, aber Sie sollten sich nicht darauf verlassen)Versuchen Sie Folgendes:
Bearbeiten, um hinzuzufügen: ich könnte auch darauf hinweisen, weitere details:
Ich würde festlegen der sampler-Standort nur einmal. Einstellung neigt Sie dazu zu zwingen, zusätzliche Arbeit in die Treiber, und da Sie nur legen Sie es auf die gleiche textur-Einheit jedes mal, Sie könnte genauso gut tun es auf initilization.
Den Ort, den Sie nennen
glBindBuffer(GL_ARRAY_BUFFER, 0)
ist nicht falsch, aber ich würde es nur nach der VertexAttribPointer Anrufe. Das momentan gebundene Puffer ist eigentlich nur ein zusätzliches argument, um solche Anrufe... Und es nicht auf die glDrawArrays sich selbst aufrufen.Shader umfasst, der Teilausdruck
Denen würde machen Ihrer Struktur im wesentlichen unsichtbar auf den meisten displays, wäre es nicht?
Afaik müssen Sie glClientActiveTexture() vor dem binden einer textur für ein VBO.