【发布时间】:2016-04-27 14:17:37
【问题描述】:
想法:
我一直在尝试开发可以获取几(十)张 2D 图像并将它们渲染为 3D 纹理的代码。到目前为止,我根据我之前的帖子的建议使用了 glTexImage3D 和 glTexSubImage3D:OpenGL - 'glTexSubImage3D': identifier not found
我的工作基于 NeHe 的纹理映射教程:http://nehe.gamedev.net/tutorial/lesson_06_texturing_update/47002/
NeHe 教程main() 中的函数调用流程如下:CreateGLWindow()、InitGL()、LoadGLTextures()、DrawGLScene()。我只对从DrawGLScene() 开始的代码进行了更改,而该函数下方的所有内容都与我的代码中的相同。
问题: 代码中的所有内容看似看起来都正确,但是屏幕上没有呈现任何内容。我花了两天时间试图让它工作无济于事。我错过了什么?有什么我做错了吗?
编辑代码
#include "windows.h"
#include "stdio.h"
#include "gl\gl.h"
#include "gl\glu.h"
#include "GLext.h"
#include "SOIL.h"
HDC hDC=NULL;
HGLRC hRC=NULL;
HWND hWnd=NULL;
HINSTANCE hInstance;
bool keys[256];
bool active=TRUE;
bool fullscreen=TRUE;
GLfloat xrot;
GLfloat yrot;
GLfloat zrot;
GLuint m_nTexId;
unsigned char tex;
int h = 1024;
int w = 256;
int slices = 10;
GLfloat dOrthoSize = 1.0f;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// EDIT HERE
PFNGLTEXIMAGE3DPROC TexImage3D;
PFNGLTEXSUBIMAGE3DPROC TexSubImage3D;
PFNGLCOPYTEXSUBIMAGE3DPROC CopyTexSubImage3D;
int LoadGLTextures()
{
glGenTextures(1,(GLuint*)&m_nTexId );
if(m_nTexId == 0)
return false;
glBindTexture( GL_TEXTURE_3D, m_nTexId );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return true;
}
GLvoid ReSizeGLScene(GLsizei width, GLsizei height)
{
if (height==0)
{
height=1;
}
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int InitGL(GLvoid)
{
if (!LoadGLTextures())
{
return FALSE;
}
glEnable(GL_TEXTURE_3D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// EDIT HERE
TexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
TexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) wglGetProcAddress("glTexSubImage3D");
CopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) wglGetProcAddress("glCopyTexSubImage3D");
return TRUE;
}
#define MAP_3DTEXT( TexIndex ) \
glTexCoord3f(0.0f, 0.0f, ((float)TexIndex+1.0f)/2.0f); \
glVertex3f(-dOrthoSize,-dOrthoSize,TexIndex);\
glTexCoord3f(1.0f, 0.0f, ((float)TexIndex+1.0f)/2.0f); \
glVertex3f(dOrthoSize,-dOrthoSize,TexIndex);\
glTexCoord3f(1.0f, 1.0f, ((float)TexIndex+1.0f)/2.0f); \
glVertex3f(dOrthoSize,dOrthoSize,TexIndex);\
glTexCoord3f(0.0f, 1.0f, ((float)TexIndex+1.0f)/2.0f); \
glVertex3f(-dOrthoSize,dOrthoSize,TexIndex);
int DrawGLScene(GLvoid)
{
PFNGLTEXIMAGE3DPROC glTexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) wglGetProcAddress("glTexSubImage3D");
PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) wglGetProcAddress("glCopyTexSubImage3D");
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//glEnable( GL_ALPHA_TEST );
//glAlphaFunc( GL_GREATER, 0.2f );
//glEnable(GL_BLEND);
//glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt(0,0,-300,0,0,1,0,1,0);
glEnable(GL_TEXTURE_3D);
glBindTexture( GL_TEXTURE_3D, m_nTexId );
TexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, w, h , slices, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
glTranslatef( 0.0f, 0.0f, 100.0f );
glBegin(GL_QUADS);
tex = (unsigned char)SOIL_load_image("Data/PA_170090.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 1, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.0f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char) SOIL_load_image("Data/PA_170091.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 2, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.1f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char)SOIL_load_image("Data/PA_170092.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 3, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.2f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char)SOIL_load_image("Data/PA_170093.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 4, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.3f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char)SOIL_load_image("Data/PA_170094.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 5, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.4f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char)SOIL_load_image("Data/PA_170095.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 6, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.5f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char) SOIL_load_image("Data/PA_170096.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 7, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.6f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char) SOIL_load_image("Data/PA_170097.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 8, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.7f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char) SOIL_load_image("Data/PA_170098.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 9, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.8f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char) SOIL_load_image("Data/PA_170099.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 10, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.9f );
glEnd();
return TRUE;
}
【问题讨论】:
-
您应该在
DrawGLScene函数之外的范围内声明您的glTexImage3D等函数指针,然后在您调用InitGL (...)时加载这些指针。每次绘制场景时从驱动程序获取函数指针是没有意义的,它们永远不会改变。同样,您的纹理文件是否每帧都更改?如果不是,您可能只想加载它们一次……您目前对磁盘 I/O 施加了很大压力。 -
但最重要的是,我不明白您为什么要转换纹理矩阵?您已经在
MAP_3DTEXT(...)宏中为切片提供了 Z 坐标。您可能应该改用 ModelView。 -
@AndonM.Coleman 是的,当我尝试模拟实时系统时,我的帧每秒都在变化。因此,我需要硬件一直在重新加载图像。请参阅我在代码中的编辑,即在全局范围内声明
PFNGLTEXIMAGE3DPROC和相关指针,并在InitGL()中定义指针。 -
每一秒都不同于每一帧。您应该定期(每 1 秒)重新加载纹理,并在过渡期间重新使用加载的图像切片。此外,您的编辑并没有太大变化。您正在隐藏
DrawGLScene (...)中的同名变量。 -
@AndonM.Coleman 对,再次编辑。稍后我将修改代码以与系统一起工作,但现在我想坚持这个例子,看看为什么它仍然不起作用。我对 3D 纹理映射的了解仍在不断发展。你能告诉我应该如何转换 ModelView 吗?
标签: opengl