C OpenGL 4.x纹理不工作
我是新来的。 我在OpenGL4.4中遇到了纹理问题,我只是得到了一个黑屏。 以下是我的代码(我怀疑glGenBuffers()之前的一切都不重要,但你永远不知道):C OpenGL 4.x纹理不工作,c,opengl,glsl,C,Opengl,Glsl,我是新来的。 我在OpenGL4.4中遇到了纹理问题,我只是得到了一个黑屏。 以下是我的代码(我怀疑glGenBuffers()之前的一切都不重要,但你永远不知道): #包括 #包括 #包括 #包括 #包括 #包括“永恒.h” #包括“error.h” #定义机顶盒映像的实现 #定义STBI\u故障\u用户消息 #包括“stb_image.h” int main(int argc,char*argv[]) { 如果(argcwindow=glfwCreateWindow( 宽度, 高度, “永恒
#包括
#包括
#包括
#包括
#包括
#包括“永恒.h”
#包括“error.h”
#定义机顶盒映像的实现
#定义STBI\u故障\u用户消息
#包括“stb_image.h”
int main(int argc,char*argv[])
{
如果(argc<2)
死(“%s\n”,“参数不足”);
胶缝宽度=0,高度=0,bpp=0;
未签名字符*图像_原始;
if((image_raw=stbi_load(“image.jpg”、&width、&height、&bpp,0))==NULL)
死亡(“stbi错误:%s\n”,stbi故障原因();
uint8_t rv;
如果(rv=initialize_glfw())
模具(“%s%”PRIu8“\n”,“初始化\u glfw()失败,代码为”,rv);
glfwSetErrorCallback(glfw_错误_callback);
glfw*glfw=malloc(sizeof(glfw));
如果(!(glfw->window=glfwCreateWindow(
宽度,
高度,
“永恒”,
无效的
NULL)))
{
glfwTerminate();
模具(“%s\n”,“glfwCreateWindow失败”);
}
glfwMakeContextCurrent(glfw->window);
glfwSetKeyCallback(glfw->window,glfw_key_callback);
glewExperimental=GL_TRUE;
如果(glewInit()!=GLEW\u确定)
{
永久性清洁(glfw);
死(“%s\n”,“glewInit()失败”);
}
printf(“OpenGL%s\n”,glGetString(GL_版本));
glEnable(GLU深度试验);
glDepthFunc(GL_LESS);
GLshort顶点[]={
-1, 1, 0,
1, 1, 0,
-1, -1, 0,
1, -1, 0
};
GLushort texcoords[]={
0, 0,
1, 0,
0, 1,
1, 1
};
gl={0};//这只是一个结构
glGenBuffers(1,&(gl.points_vbo));
glBindBuffer(GL_数组_BUFFER,GL.points_vbo);
glBufferData(GLU数组缓冲区,12*sizeof(GLshort),顶点,GLU静态图);
glGenBuffers(1和(gl.texcoords_vbo));
glBindBuffer(GL_数组_BUFFER,GL.texcoords_vbo);
glBufferData(GLU数组缓冲区、8*sizeof(GLushort)、texcoords、GLU静态图);
glBindBuffer(GL_数组_BUFFER,GL.points_vbo);//编辑:我添加了这一行
glGenVertexArrays(1,&(gl.vao));
glBindVertexArray(gl.vao);
GlenableVertexAttributeArray(0);
glvertexattributepointer(0,3,GL_SHORT,GL_FALSE,0,NULL);
GlenableVertexAttributeArray(1);
glvertexattributepointer(1,3,GL_UNSIGNED_SHORT,GL_FALSE,0,NULL);
设置着色器(&gl);
盂型;
开关(bpp*8)
{
案例24:
格式=GL_RGB;
打破
案例32:
格式=GL_RGBA;
打破
}
胶合纹理_id=0;
glGenTextures(1和纹理标识);
玻璃纹理(GL_纹理0);
glBindTexture(GL_纹理_2D,纹理_id);
glTexParameteri(GL_纹理_2D、GL_纹理_包裹、GL_夹紧_至_边缘);
glTexParameteri(GL_纹理\u 2D、GL_纹理\u包裹\u T、GL_夹紧\u至\u边缘);
glTexParameteri(GL_纹理2D、GL_纹理最小过滤器、GL_线性);
glTexParameteri(GL_纹理2D、GL_纹理MAG_过滤器、GL_线性);
glTexImage2D(GL_纹理_2D,0,(闪烁)格式,宽度,高度,0,格式,GL_无符号字节,图像_原始);
无stbi图像(图像原始);
glBindTexture(GL_纹理_2D,纹理_id);
检查_错误();
而(!GLFWWindowsShouldClose(glfw->window))
{
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
glUseProgram(gl.shader_程序);
glBindVertexArray(gl.vao);
gldrawArray(GL_三角带,0,4);
glfwSwapBuffers(glfw->窗口);
glfwPollEvents();
}
glDeleteTextures(1和纹理id);
永久性清洁(glfw);
}
无效设置_着色器(gl*gl)
{
常量GLchar*vs_源=
“#版本440\n”
“vec3 vp中的布局(位置=0)”
“vec2 vt中的布局(位置=1)”
“out vec2 texcoord;”
void main(){gl_Position=vec4(vp,1.0);“
“texcoord=vt;}”,
*飞秒源=
“#版本440\n”
“out vec4 frag_颜色;”
“在vec2 texcoord中;”
“均匀的二维纹理;”
“void main(){frag_color=texture2D(texture,texcoord);}”;
GLuint vs=glCreateShader(GL_顶点_着色器);
glShaderSource(vs,1,&vs_source,NULL);
glCompileShader(vs);
GLuint fs=glCreateShader(GL_片段_着色器);
glShaderSource(fs,1,&fs_source,NULL);
glCompileShader(fs);
gl->shader_program=glCreateProgram();
glAttachShader(gl->shader_程序,fs);
glAttachShader(gl->shader_程序,vs);
glLinkProgram(gl->shader_程序);
glDeleteShader(vs);
glDeleteShader(fs);
}
uint8\u t初始化\u glfw(无效)
{
int主要=0,次要=0,版本=0;
glfwGetVersion(主版本、次版本和修订版本);
printf(“GLFW%d.%d版本%d\n”,大调,小调,版本);
glfwWindowHint(GLFW_上下文_版本_主要,主要);
glfwWindowHint(GLFW_上下文_版本_大调、小调);
glfwWindowHint(GLFWU上下文修订版,修订版);
glfwWindowHint(GLFW_样本,8个);
如果(!glfwInit())
返回1;
返回0;
}
void glfw_error_回调(int error,const char*description)
{
printf(“触发glfw错误回调\n”);
fprintf(标准,“%d:%s\n”,错误,说明);
}
无效glfw_键_回调(GLFWwindow*窗口,int键,int扫描码,int操作,int mods)
{
如果(键==GLFW\U键\转义和操作==GLFW\U按)
glfwSetWindowShouldClose(窗口,GL_TRUE);
}
空洞清理(glfw*glfw)
{
glfw窗口(glfw->window);
免费(glfw);
glfwTerminate();
}
我不确定我是否忘记在这里做一些事情,或者我做了一些不正确的事情,我已经非常努力地修复了这个问题,但是黑屏仍然存在。
我觉得问题出在我的着色器中(在setup_shaders()中硬编码),或者可能在glTexImage2D()附近
编辑:
我发现如果我在glgenvertexarray之前再次调用glBindBuffer,那么我会得到一个浅蓝色的屏幕,并且我正在加载的特定图像是pre
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "eternity.h"
#include "error.h"
#define STB_IMAGE_IMPLEMENTATION
#define STBI_FAILURE_USERMSG
#include "stb_image.h"
int main(int argc, char *argv[])
{
if (argc < 2)
DIE("%s\n", "not enough arguments");
GLuint width = 0, height = 0, bpp = 0;
unsigned char *image_raw;
if ((image_raw = stbi_load("image.jpg", &width, &height, &bpp, 0)) == NULL)
DIE("stbi error: %s\n", stbi_failure_reason());
uint8_t rv;
if (rv = initialize_glfw())
DIE("%s%" PRIu8 "\n", "initialize_glfw() failed with code ", rv);
glfwSetErrorCallback(glfw_error_callback);
glfw *glfw = malloc(sizeof(glfw));
if (!(glfw->window = glfwCreateWindow(
width,
height,
"Eternity",
NULL,
NULL)))
{
glfwTerminate();
DIE("%s\n", "glfwCreateWindow failed");
}
glfwMakeContextCurrent(glfw->window);
glfwSetKeyCallback(glfw->window, glfw_key_callback);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
eternity_cleanup(glfw);
DIE("%s\n", "glewInit() failed");
}
printf("OpenGL %s\n", glGetString(GL_VERSION));
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
GLshort vertices[] = {
-1, 1, 0,
1, 1, 0,
-1, -1, 0,
1, -1, 0
};
GLushort texcoords[] = {
0, 0,
1, 0,
0, 1,
1, 1
};
gl gl = {0}; // This is just a struct
glGenBuffers(1, &(gl.points_vbo));
glBindBuffer(GL_ARRAY_BUFFER, gl.points_vbo);
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLshort), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &(gl.texcoords_vbo));
glBindBuffer(GL_ARRAY_BUFFER, gl.texcoords_vbo);
glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLushort), texcoords, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, gl.points_vbo); // EDIT: I added this line
glGenVertexArrays(1, &(gl.vao));
glBindVertexArray(gl.vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_SHORT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_UNSIGNED_SHORT, GL_FALSE, 0, NULL);
setup_shaders(&gl);
GLenum format;
switch (bpp * 8)
{
case 24:
format = GL_RGB;
break;
case 32:
format = GL_RGBA;
break;
}
GLuint texture_id = 0;
glGenTextures(1, &texture_id);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_id);
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, (GLint)format, width, height, 0, format, GL_UNSIGNED_BYTE, image_raw);
stbi_image_free(image_raw);
glBindTexture(GL_TEXTURE_2D, texture_id);
check_error();
while (!glfwWindowShouldClose(glfw->window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(gl.shader_program);
glBindVertexArray(gl.vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glfwSwapBuffers(glfw->window);
glfwPollEvents();
}
glDeleteTextures(1, &texture_id);
eternity_cleanup(glfw);
}
void setup_shaders(gl *gl)
{
const GLchar *vs_source =
"#version 440\n"
"layout(location = 0) in vec3 vp;"
"layout(location = 1) in vec2 vt;"
"out vec2 texcoord;"
"void main() { gl_Position = vec4(vp, 1.0);"
"texcoord = vt; }",
*fs_source =
"#version 440\n"
"out vec4 frag_color;"
"in vec2 texcoord;"
"uniform sampler2D texture;"
"void main() { frag_color = texture2D(texture, texcoord); }";
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vs_source, NULL);
glCompileShader(vs);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fs_source, NULL);
glCompileShader(fs);
gl->shader_program = glCreateProgram();
glAttachShader(gl->shader_program, fs);
glAttachShader(gl->shader_program, vs);
glLinkProgram(gl->shader_program);
glDeleteShader(vs);
glDeleteShader(fs);
}
uint8_t initialize_glfw(void)
{
int major = 0, minor = 0, rev = 0;
glfwGetVersion(&major, &minor, &rev);
printf("GLFW %d.%d rev %d\n", major, minor, rev);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, major);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, minor);
glfwWindowHint(GLFW_CONTEXT_REVISION, rev);
glfwWindowHint(GLFW_SAMPLES, 8);
if (!glfwInit())
return 1;
return 0;
}
void glfw_error_callback(int error, const char *description)
{
printf("glfw error callback triggered\n");
fprintf(stderr, "%d: %s\n", error, description);
}
void glfw_key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
void eternity_cleanup(glfw* glfw)
{
glfwDestroyWindow(glfw->window);
free(glfw);
glfwTerminate();
}